Анализируем HTTP трафик в Wireshark
Анализатор пакетов Wireshark является одним из основных инструментов, используемых как сетевыми инженерами и администраторами, так и разработчиками и тестировщиками приложений для решения проблем с сетевыми протоколами.
При этом, не все умеют эффективно использовать тот функционал который представляет анализатор для работы с дампами трафика.
В сегодняшней статье в качестве примера мы рассмотрим ситуацию, когда у нас имеется дамп трафика, в котором содержится HTTP сессия пользователя. Для упрощения ситуации будем считать, что мы получаем HTTPS трафик в уже расшифрованном виде, так как рассмотрение вопроса дешифровки TLS выходит за рамки этой статьи.
Итак, наш дамп трафика может представлять собой довольно увесистый файл, содержащий много различных пакетов. Да, в Wireshark можно настроить перехват только определенного трафика, но будем считать, что по тем или иным причинам нам собрали весь трафик, проходящий между нужными узлами за определенный период времени, и теперь уже наша задача найти в нем нужные пользовательские сессии. В качестве исходной проблем мы рассмотрим запрос в техподдержку, о том, что пользователь получает неверные данные при выгрузке Excel таблиц по заказам в своем личном кабинете на веб ресурсе. Соответственно, нам надо выяснить как пользователь подключался, какие действия он выполнял на веб ресурсе, и что за файлы он выгружал.
На практике это довольно типичная история. В компании есть сетевики, отвечающие за сетевую инфраструктуру и прикладники, отвечающие за прикладные сервисы. В случае проблем каждое подразделение стремиться «спихнуть» сбой на коллег, мол «это у сетевиков канал не тянет» или «это у прикладников софт глючит». Для того, чтобы разобраться, кто же виноват на самом деле, мы можем воспользоваться собранным дампом трафика.
Начнем с фильтров
Для работы с HTTP пакетами логичнее всего воспользоваться фильтром http, как показано на рисунке ниже:
Однако, как мы видим для всего сеанса нам показали только два пакета: запрос HTTP GET и сообщение 200. Однако, по факту сеанс естественно состоит из гораздо большего числа пакетов. Ниже представлены все перехваченные пакеты из данного сеанса:
Как видно, Wireshark не все пакеты, участвовавшие в данном информационном обмене раскодировал как HTTP. Первые три пакета это классическое трехстороннее рукопожатие, которое используется при установке TCP соединения. Полагаю, читатель знаком с принципом установки TCP соединения, так как в рамках данной статьи мы не будем подробно разбирать данный процесс.
Несмотря на то, что в них фигурирует порт 80, по факту они не являются пакетами прикладного уровня, так как в них нет полезной нагрузки (payload) выше транспортного уровня. Это видно по значению поля Length. Выделенный пакет как раз начинает общение по HTTP, и здесь Wireshark честно назвал HTTP. В ответ сервер вернул ACK — тоже служебный пакет, подтверждающий получение предыдущего, и затем начал передавать данные. И хотя в пакете с данными мы видим трафик, очень похожий на протокол HTTP, наш анализатор в поле Protocol по прежнему пишет унылый TCP.
В итоге, только пакет с сообщением 200 Wireshark распознал как HTTP. Такой странный парсинг может вызвать недоумение, как нам тогда отфильтровать сессию целиком? Нам же нужно понять, какие данные передавались в пакетах. Для получения разобранного дампа прикладного уровня выберем первый (хотя можно и последний) пакет, который был помечен как HTTP, далее правая кнопка мыши Follow → HTTP Stream. Получаем человеко-понятный набор параметров HTTP, элементов HTML, JavaScript и прочий контент, с которым уже можно работать. Здесь с помощью поиска уже можно попробовать поискать нужный контент, а можно перекинуть весь контент в какой-нибудь Burp Suite для последующей отладки.
Для простого дампа трафика HTTP Stream будет достаточно. Но если у нас тысячи пакетов, то ручной поиск может затянуться и здесь нам на помощь приходят готовые фильтры http.*.
Мы можем с помощью фильтров извлечь параметры HTTP, указанные в верхней части предыдущего рисунка. Так, если мы хотим узнать cookie, то можно воспользоваться фильтром http.cookie.
В результате нам будут отображены только те пакеты, которые содержат параметр Cookie.
Нередко проблемы возникают из-за не/использования кодирования контента. С помощью фильтра http.content_encoding мы можем узнать какой метод использовался.
Фильтр http.connection покажет нам какие методы использовались при передаче данных от пользователя (GET/POST). Отфильтровать отдельно методы HTTP можно с помощью http.request.method=«GET» и http.request.method=«POST» соответственно.
Таким образом мы можем увидеть, какие данные пользователь передавал на сервер.
Собственно, готовых фильтров для работы с HTTP в Wireshark довольно много. Можно, к примеру отдельно отфильтровать процесс аутентификации для различных протоколов.
Ищем произвольный контент
Готовые фильтры — это конечно замечательно, но что делать, если нам нужно найти в трафике какой-то конкретный набор байт. Можно конечно поискать в дампе HTTP Stream, но это может быть не совсем удобно. Лучше написать свой фильтр. Давайте разберем простой пример: нам нужно узнать, сколько попыток входа в свой личный кабинет на сайте делал пользователь.
Для этого нужно сначала найти пакет, в котором осуществляется отправка учетных данных и найти нужное поле в разобранном дампе. Далее по правой кнопке мыши Prepare As Filter → Selected. В примере мы будем искать пакеты с упоминанием значения test.
В результате получаем готовый фильтр, который будет искать пакеты, содержащие значение test.
Ищем по сырому
Но если и таким способом мы ничего найти не можем, то можно тупо искать последовательность нужных байтов. Для этого в сыром дампе, представленном в нижней части рабочего окна Wireshark ищем с какой позиции начинается нужный набор байтов:
Переводим это значение в десятичную систему и пишем фильтр следующего вида:
frame[начальная_позиция:число_байт] == ASCII_коды_в_HEX
Например, если мне нужно найти строку uname=test&
которая начинается с позиции 549, то фильтр будет иметь вид, представленный на рисунке:
Все три пакета содержали строку uname=test&. Отсюда мы можем сделать вывод, что попыток аутентификации было три.
Собственно фильтр frame[:] == … можно использовать не только для HTTP трафика, но и для других протоколов разных уровней иерархической модели. Главное знать что искать.
Заключение
Думаю, для начала информации по использованию Wireshark для отладки достаточно. За рамками статьи остались такие интересные вещи как ретрансмиты, плавающие окна и другие вопросы, о которых мы обязательно поговорим в следующих статьях.
Пользуясь случаем, напомню об открытых уроках, которые скоро пройдут в Otus:
11 июня: OSPFv3 vs. OSPFv2 на практике: сравнение LSDB. Записаться
20 июня: IS-IS на практике: алгоритм SPF и что полезного можно найти в LSDB? Записаться