Анализ HTTP-трафика с mitmproxy
В этом тексте рассмотрим mitmproxy — решение для анализа HTTP-трафика.
В практике веб-разработчика нередко возникают ситуации, когда требуется отследить и проанализировать трафик приложений, общающихся с сервером по протоколу HTTP (в качестве примера можно привести тестирование приложений для мобильных устройств или HTTP API).
Инструменты, традиционно используемые для прослушивания трафика (tshark, о котором мы уже писали, а также ngrep и tcpdump) для этой цели подходят плохо: функциональность для работы с протоколом HTTP у них ограничена.
Для анализа HTTP-трафика существует более специализированное, простое и эффективное решение — mitmproxy. В этой статье мы поделимся своим опытом работы с mitmproxy.
Общая информация
Mitmproxy представляет собой целый набор программных инструментов, в который входят:
- собственно mitmproxy — интерактивная консольная программа, перехватывающая трафик «на лету».
- mitmdump — утилита, которую можно описать как аналог tcpdump для протокола HTTP: она перехватывает трафик и сохраняет всю информацию о нем в текстовый файл.
- libmproxy — библиотека для Python, с помощью которой реализуется вся функциональность mitmproxy.
Само название mitmproxy происходит от аббревиатуры MITM, что означает man in the middle, или «человек посередине». Так называется метод компрометации канала связи, в котором взломщик подключается к каналу передачи между двумя контрагентами и вмешивается в протокол передачи, просматривая, удаляя и искажая информацию. mitmproxy работает похожим образом: он используется в качестве прокси-сервера, регистрируя весь HTTP-трафик. Как и любой прокси-сервер, в некоторых случаях mitmproxy может видоизменять как запросы пользователя, так и ответы на них.
Рассмотрим принципы и особенности mitmproxy более подробно.
Как это работает
В случае с незашифрованными HTTP-соединениями все просто: mitmproxy принимает соединение от клиента (например, от браузера на мобильном устройстве), отображает информацию о нем на консоли (или сохраняет в текстовый файл), а затем возвращает клиенту ответ от получателя запроса.
Mitmproxy можно использовать и для перехвата защищенного HTTPS-трафика. При запуске mitmproxy или mitmdump в директории ~/.mitmproxy создается набор файлов CA, на основе которых генерируются подменные сертификаты. Естественно, что браузер будет эти сертификаты определять как подозрительные, выдавая при каждой попытке установить SSL-соединение с помощью mitmproxy соответствующее предупреждение.
Чтобы этого предупреждения не было, можно добавить сертификат от mitmproxy в список сертификатов, используемых браузером (с подробными инструкциями можно ознакомиться здесь).
При выполнении этих двух условий клиент делает вывод о том, что устанавливаемое соединение является безопасным.
Mitmproxy может перехватывать и защищенный HTTPS-трафик. Процедура перехвата состоит из следующих шагов:
- Клиент устанавливает соединение с mitmproxy.
- Mitmproxy отправляет клиенту ответ с кодом 200 (соединение установлено).
- Клиент взаимодействует с mitmproxy так же, как и с удаленным сервером, и устанавливает SSL-соединение. Чтобы указать имя хоста, он использует SNI.
- Mitmproxy подключается к серверу и устанавливает SSL-соединение, используя указанное клиентом имя хоста.
- В ответе сервер передает SSL-сертификат, содержащий значения параметров CN и SAN, на основе которых затем будет создан подменный сертификат.
- Mitmproxy генерирует подменный сертификат и продолжает SSL-диалог с клиентом, приостановленный на этапе 3.
- Клиент отправляет запроc через установленное SSL-соединение.
- Mitmproxy передает запрос серверу через SSL-соединение, установленное на этапе 4.
Более наглядно процесс перехвата защищенного трафика можно представить в виде следующей графической схемы:
Зачем это нужно
Само название mitmproxy происходит от названия одного из самых распространенных видов атак. Даже официальная документация к продукту изобилует такими словами, как «атака», «перехват» и подобными. Все это наводит на мысли о том, что этот инструмент может выступать в качестве орудия взлома. Конечно, mitmproxy (как и все продукты с аналогичным набором функций — так называемые сниферы) вполне может быть использован для нелегальных целей, но мы по вполне понятным причинам обсуждать это не будем и сосредоточимся на легальных вариантах использования.
Mitmproxy можно использовать, во-первых, для тестирования и отладки веб-приложений. С его помощью можно получать подробную информацию о том, какие запросы делает приложение и какие ответы оно получает. Также mitproxy может помочь в изучении особенностей функционирования некоторых REST API, в особенности плохо документированнных и использующих закрытые (и зачастую- очень подозрительные) технологии.
Во-вторых, Mitmproxy может работать в режиме прозрачного прокси с перехватом трафика, а это значит, что его можно использовать для анализа сетевой активности подозрительных приложений.
Тестируем Mitmproxy
Установка
Сегодня mitmproxy включен в репозитории linux-систем и может быть установлен при помощи стандартного менеджера пакетов:
$ sudo aptitude install mitmproxy
Можно также установить его другими способами:
$ pip install mitmproxy
или
$ easy_install mitmproxy
Первый запуск
Посмотрим на конкретных примерах, как работает mitmproxy. Откроем браузер (в нашем случае это Firefox) и в настройках (меню Настройки → Сеть → Соединение) и в разделе «Ручная настройка сервиса прокси» укажем в качестве прокси-сервера машину, на которой установлен mitmproxy.
Теперь подключимся к серверу, на которому установлен mitmproxy, по ssh и выполним следующую команду:
$ mitmproxy
Консоль после этого будет выглядеть так:
Чтобы выйти из этого режима, нужно нажать клавишу q. Получить справку можно, нажав комбинацию клавиш, обозначающую вопросительный знак (?).
Теперь откроем в браузере любой сайт — например, ya.ru. Все запросы к этому сайту будут выводиться на консоль:
Перемещаться по списку запросов можно, нажимая на клавиши со стрелками. Вернуться в основное окно можно, нажав на клавишу q. Чтобы просмотреть подробную информацию о некотором запросе, нужно подвести к нему курсор и нажать на клавишу Enter:
В поле Request отображается подробная информация о запросе (запрашиваемый хост, ПО, с помощью которого осуществлялся запрос, передаваемые заголовки), а в поле Response — информация о полученном ответе.
Переключаться между этими полями можно при помощи клавиши Tab. Вернуться к списку запросов можно, нажав на клавишу q.
Запросы и ответы на них можно изменять. Для этого нужно использовать так называемые фильтры перехвата (interception filters). Чтобы ввести фильтр, нужно нажать на клавишу i. Введем в качестве фильтра, например, ya.ru Все запросы, содержащие этот адрес, будут перехватываться. Перехваченные запросы в списке будут подсвечиваться оранжевым цветом.
Такие запросы не будут обрабатываться, если мы их не примем. Чтобы принять запрос, нужно подвести к нему курсор и нажать на клавишу а, а чтобы принять все перехваченные запросы — на клавишу A.
Более подробную информацию о запросе можно просмотреть, подведя к нему курсор и нажав на клавишу E (E- первая буква в английском слове event — «событие»). Будет открыт лог событий, который имели место при обработке этого запроса:
И запросы, и ответы можно редактировать. Функция редактирования может оказаться полезной при тестировании: можно, например, смоделировать определенную ситуацию и увидеть, как будет вести себя приложение, получив от сервера определенный ответ.
Подведем курсор к интересующему нас запросу, подведем к нему курсор и нажмем на клавишу Enter. Затем подведем курсор к полю Request и нажмем на клавишу E (первая буква в слове edit — редактировать). В нижней части консоли появится меню редактирования:
Изменить можно как запрос целиком (клавиша Q), так и его отдельные параметры: путь (клавиша P), URL (U), заголовок (H), форму (F), тело (R) и метод (M).
Аналогичным образом осуществляется редактирование ответа. Отредактировать можно его код (клавиша C), сообщение (M), заголовки (H) и тело (R).
Дополнительные функции
Аутентификация на прокси-сервере
В mitmproxy можно активировать режим аутентификации пользователей перед использованием прокси. Заголовки аутентификации из запросов удаляются и на вышестоящие серверы на передаются. На сегодняшний день поддерживается только базовая HTTP-аутентификация. Настройка аутентификации осуществляется при помощи следующих опций:
#запретить анонимным пользователям пользоваться прокси
$ mitmproxy --nonanonymous
#разрешить пользоваться прокси только указанному пользователю
$ mitmrpoxy --singleuser <имя пользователя>
#разрешить пользоваться прокси только при вводе одного из указанных в файле паролей;
$ mitmproxy —htpasswd <путь к файлу с паролями>
Привязка cookies
Функция привязки cookies (sticky cookies) полезна при работе с сервисами, требующими авторизации. Достаточно авторизоваться на таком сервисе один раз, и mitmproxy будет автоматически добавлять соответствующий cookie к каждому запросу. После этого все запросы будут передаваться на сервер без повторной авторизации.
Режим привязки cookies активируется так:
$ mitmproxy -t <фильтр>
Ко всем проксируемым запросам можно также добавлять заголовки авторизации. Для этого используется опция -u.
Режим reverse proxy
В этом режиме все запросы отсылаются к вышестоящему серверу. Mitmproxy в данном случае можно использовать в качестве временной прослойки, наблюдая и перехватывая запросы.
Режим reverse proxy активируется при помощи команды:
$ mitmproxy -P http[s]://hostname[:port]
Функция anticache
Mitmproxy может убирать из запроса заголовки if-modified-since и if-none-match. Благодаря этому всегда можно просмотреть полный ответ от сервера, даже если браузер сообщает, что запрашиваемый документ есть в кэше.
Активируется эта функция при помощи следующей команды:
$ mitmproxy --anticache
Воспроизведение клиентских запросов
Функция воспроизведения клиентских запросов (client side replay) позволяет воспроизводить запросы из сохраненных ранее HTTP-диалогов. Запросы исполняются один за другим: отправив один запрос, mitmproxy ждет ответа от сервера, и только потом приступает к следующему. Поэтому поведение клиента может отличаться от записанного в сохраненный диалог, в котором некоторые запросы могли выполняться одновременно.
Воспроизвести клиентские запросы можно при помощи команды:
$ mitmproxy -c <путь к сохраненному диалогу>
Mitmdump
Как уже было сказано выше, Mitmdump представляет собой утилиту, работающую точно так же, как и tcpdump, только для протокола HTTP. Она перехватывает весь HTTP-трафик и записывает информацию о нем в отдельный текстовый файл.
Чтобы начать работу с mitmdump, нужно запустить mitmproxy в режиме прокси-сервера, а затем выполнить следующую команду:
$ mitmdump -w <имя файла>
Сохраненную информацию можно отфильтровать при помощи регулярных выражений, а затем сохранить в новый файл:
$ mitmdump -nr <файл1> -w <файл2> "~m post"
В приведенном примере mitmdump отбирает из файла 1 запросы, соответствующие определенному критерию (в нашем случае — POST-запросы), и записывает их в файл 2.
Mitmdump может считать уже сохраненную информацию о клиентских запросах из файла, воспроизвести эти запросы повторно, а результаты сохранить в новый файл:
$ mitmdump -nc <файл 1> -w <файл 2>
Эта функция может оказаться полезной при тестировании некоторых веб-приложений.
Заключение
В этой статье мы дали краткий обзор возможностей mitmproxy. Для желающих узнать больше приводим несколько ссылок: