Конференция "Сети" » Анализирование HTTP-трафика [D7, WinXP]
 
  • Очень Злой (02.09.13 20:43) [0]
    Нужно перехватывать HTTP-ответы сервера, направляемые браузеру, ну и разгзиповывать их и парсить.

    Допустим, я отсниффаю весь TCP трафик, выберу трафик от нужного сервера.
    Но как правильно собирать TCP-пакеты чтобы собрать их в нужной последовательности, не перепутать пакеты от разных HTTP - ответов сервера?
  • DVM © (03.09.13 00:42) [1]
    Rfc читать там написано как и что собирать. Тема обширная, могу подсказать  по любому конкретному вопросу и протоколу.
  • Очень Злой (03.09.13 12:42) [2]
    ну rfc пока не совсем понятно... Нужно немножко общей информации для начала...

    Пока смутно представляю себе это все так:
    создаем RAW сокет, и в цикле принимаем все пакеты.
    если это не TCP-пакет, или пакет не с нужного хоста, или не с нужного порта (80) , то игнорируем его.

    если это SYN-пакет - то создаем буфер для данных.

    если это FIN-пакет - то передаем собранные данные из буфера далее, т.е. парсеру или т.п.

    если это пакет с данными, то ищем соответствующие ему буфер и туда впихиваем

    Не знаю наскольо это верно. Но все равно возникают вопросы:
    1. По какому признаку определить в какой буфер пихать данные с пакета? по номеру порта?

    2. Могут ли пакеты с данными идти не в той последовательности, в которой должны собираться?
    По каким признакам их собирать? Sequence Number , Acknowledgment Number  или по чему-то другому?
  • DVM © (03.09.13 14:22) [3]

    > создаем RAW сокет, и в цикле принимаем все пакеты.

    Лучше все же использовать LibPCAP (WinPCap), иначе Ethernet уровня не будет, ну да ладно, сойдет и Raw Socket для начала.


    > если это не TCP-пакет, или пакет не с нужного хоста, или
    > не с нужного порта (80) , то игнорируем его.

    Ну по хорошему, сначала надо еще узнать, что это TCP пакет, а для этого пройти уровни Ethernet(если есть), IP/IPV6, VLAN (если есть), и их комбинации (они как матрешки могут быть вложены друг в друга).

    С портом не так просто, т.к. есть фрагментированные пакеты IP. Их надо объединять, иначе номер порта TCP не заполучить.


    > если это SYN-пакет - то создаем буфер для данных.

    По колхозному да, можно буфер, и в этот буфер клеим по смещению, вычисленному по номеру последовательности SequenceNumber TCP пакета, но тут нас подстерегает множество граблей: поврежденные пакеты, дубли и ретрансмишенны, RollOver номера последовательности, когда он опять начинается с 1 после достижения MaxInt и самое главное, пакеты с искаженным SequenceNumber в результате которого наш буфер может получиться на 4 гб размером. Кроме этого так не склеить большие объемы данных, например передающийся файл размером 5 гб.

    Есть другой способ, более сложный, но надежный.


    > если это SYN-пакет - то создаем буфер для данных.

    Да


    > если это FIN-пакет - то передаем собранные данные из буфера
    > далее, т.е. парсеру или т.п.

    На практике FIN приходит очень редко, поэтому все парсеры должны быть потоковыми, т.е. парсить данные по мере их поступления. Т.е собрал цепочку без дырок из TCP пакетов - отдал их парсеру.


    > 1. По какому признаку определить в какой буфер пихать данные
    > с пакета? по номеру порта?

    По сочетанию номеров портов отправителя и получателя и их IP. Вычисли от них какой нибудь хэш и его используй для идентификации направления.


    > 2. Могут ли пакеты с данными идти не в той последовательности,
    >  в которой должны собираться?

    Они не то что могут, они так и идут.


    > По каким признакам их собирать? Sequence Number , Acknowledgment
    > Number  или по чему-то другому?

    Как показала практика, располагая только одним Sequence Number и умением вычислять контрольную сумму пакета можно без потерь собирать данные в одном направлении. ACK он нужен клиенту, но сниферу он не нужен, т.к. всю работу делает клиент.
  • Очень Злой (03.09.13 20:13) [4]

    >
    > По колхозному да, можно буфер, и в этот буфер клеим по смещению,
    >  вычисленному по номеру последовательности SequenceNumber
    > TCP пакета, но тут нас подстерегает множество граблей: поврежденные
    > пакеты, дубли и ретрансмишенны, RollOver номера последовательности,
    >  когда он опять начинается с 1 после достижения MaxInt и
    > самое главное, пакеты с искаженным SequenceNumber в результате
    > которого наш буфер может получиться на 4 гб размером. Кроме
    > этого так не склеить большие объемы данных, например передающийся
    > файл размером 5 гб.


    ну речь идет о небольших размерах данных передаваемых за одно соединение максимум 50-100 кб. если будет больше - то это явно что-то не то, и можно отбрасывать...
    но вот еще проблема с keep-alive может случиться, типа несколько HTTP соединений за одно TCP-соединение... хм..
  • DVM © (03.09.13 20:41) [5]
    Вот потому и нужен потоковый парсер http. А еще http может иметь очень часто  Chunked Transfer Encoding, что тоже надо учитывать, т.е парсер должен понимать.
    Такой парсер чаще всего делают в виде машины состояний.
  • Dennis I. Komarov © (11.09.13 22:26) [6]

    > Лучше все же использовать LibPCAP (WinPCap)

    Лучше сразу использовать, ибо потом жалеть будешь
  • DVM © (11.09.13 23:51) [7]
    Лучше написать код так, чтобы одно устройство захвата пакетов легко заменялось на другое, ведь по сути без разницы откуда получать пакеты.
  • Очень Злой (12.09.13 00:56) [8]

    > Dennis I. Komarov ©   (11.09.13 22:26) [6]
    >
    >
    > > Лучше все же использовать LibPCAP (WinPCap)
    >
    > Лучше сразу использовать, ибо потом жалеть будешь


    Я пока не имел возможности пользоваться LibPCAP (WinPCap). Но хотелось бы знать в общих чертах чем она лучше в данной ситуации?


    > DVM ©   (11.09.13 23:51) [7]


    Ну это понятно. С этим я абсолютно согласен.


    > DVM ©   (03.09.13 20:41) [5]
    >
    > Вот потому и нужен потоковый парсер http.


    А если контент сжатый гзипом ? Прежде чем парсить - его же разжать нужно.
  • megavoid © (12.09.13 10:53) [9]
    У wireshark открытые исходники, он всё это умеет, там можно подсмотреть много чего полезного:
    svn co http://anonsvn.wireshark.org/wireshark/trunk
  • DVM © (12.09.13 14:11) [10]

    > Очень Злой   (12.09.13 00:56) [8]


    > А если контент сжатый гзипом ? Прежде чем парсить - его
    > же разжать нужно.

    Нет, не нужно. Сжат контент, но не сам протокол HTTP. HTTP как раз не сжат. По идее парсеру HTTP по барабану, что там за контент, он его должен найти (а это не зависит от типа) и выплюнуть на пару с заголовками HTTP. За разжатие HTTP контента должен отвечать другой уровень - Deflate и GZIP анализаторы как я их называю. А вот то о чем я говорил Chunked Transfer Encoding - это уже относится к HTTP протоколу, это парсер должен уметь разбирать.


    > megavoid ©   (12.09.13 10:53) [9]

    В Wireshark парсеры отдельных уровней протоколов назваются диссекторы. Там очень мудрено все и завязано на специфику отображения в интерфейсе.
  • DVM © (12.09.13 14:12) [11]

    > Очень Злой   (12.09.13 00:56) [8]


    > Я пока не имел возможности пользоваться LibPCAP (WinPCap).
    >  Но хотелось бы знать в общих чертах чем она лучше в данной
    > ситуации?

    Она перехватывает пакеты на самом нижнем уровне. Отличается тем, что надежна и проверена временем, работает и под линукс и вин.
 
Конференция "Сети" » Анализирование HTTP-трафика [D7, WinXP]
Есть новые Нет новых   [134427   +35][b:0][p:0]