Перехват HTTPS – трафика

Однажды встретился на просторах интернета один клиент-серверный продукт название которого я приводить пока не буду, назовём его просто «продукт TH». Работал он по технологии похожей на Free2Play, но бесплатно предоставлял дай бог 10% от своего функционала, остальные плюшки только по платной подписке. Какое время (год или около того) я смиренно ждал решения со стороны, но в конце концов любопытство оказалось сильнее лени и я засел за более глубокое изучение этого продукта.

TH — дитя тотальной вебдванольности, клиентская часть в отдельности не представляет никакого интереса, весь цимес находится на серверной стороне в виде среднеразвитой социальной сети, форума и магазина. Всю информацию о наличии/отсутствии плюшек клиент получает оттуда же, остаётся только взять её, изучить содержание и изменить по потребностям. Сразу оговорюсь, конечной целью не было создание т.н. «локального сервера» или клона коммерческого сайта с целью извлечения прибыли, причиной был зуд в известном месте и обычное детское «а что там внутри».

А внутри оказалось, что общение клиента с сервером проходит через HTTPS-канал. Поэтому если ваше любопытство в этой области совпадает с моим, то ниже рассказ о довольно запутанном для новичка в этой области, но успешно раскрытом вопросе.

Теория

Первым делом залез в гугль с запросом “перехват https ssl трафика“, там весьма вежливо объяснили, что SSL вроде как и задумывался с целью пресечь такие вопросы. Недолгие поиски выдали утилиты типа arpspoof/dnsspoof и их аналоги, которые в общем и целом позволяют злоумышленнику (а именно это существительное чаще всего встречалось в поисковой выдаче) перехватить трафик и перенаправить его на свой, злоумышленнский, компьютер. Однако перенаправление интересовало в последнюю очередь, ибо направлять траф в никуда было ненужным, и что делать с захваченным HTTPS-трафиком пока было неясно.

Дальнейшие поиски натолкнули на технику MITM, Man In The Middle (Человек В Середине), или несколько иначе — Monkey In The Middle (упомянутая в названии Обезьяна В Середине). Есть и обзорная статья по этому поводу (1). Если вкратце, то трафик от клиента надо направить на обезьяну, которая представится SSL-сервером, вытащит зашифрованные данные и передаст их настоящему серверу представившись ему, в свою очередь, настоящим клиентом.

Для начала решил потренироваться «на кошках», ибо лезть с такими познаниями на баррикады реальных серверов было бы глупо и, наверное, заметно. В качестве кошки выступил Apache в виртуалке и первая попавшаяся CMS с SSL-авторизацией. Клиент в виде браузера соединяется с виртуальным апачем, задача-минимум — получить зашифрованные данные с веб-формы.

Первые шаги

На этом этапе вспомнилось, что на работе (и не только) мы использовали утилиту stunnel для разных тупых почтовых клиентов и FTP-утилит, которые не умели соединяться по защищённым протоколам. Утилита, так сказать, двойного действия, может сделать и обратную операцию — предоставить защищёное соединение для серверных программ без этой возможности. Так как виртуальный апач (сервер) в реальности был бы недоступен, то все утилиты должны располагаться локально. Клиент работает только под Windows, а по некоторому опыту я знал, что манипуляции с сетями и сопутствующими вещами в этой ОС представлены, мягко сказать, не самым лучшим образом. Поэтому была поднята вторая виртуалка с линуксом и установлен stunnel. Его задача — принимать запросы на 443 порт и редиректить их на сервер. Немного подумав понял, что редирект произойдет уже с расшифрованным трафиком, поэтому нужен второй stunnel, но уже в клиентском режиме, именно он и будет соединяться с сервером. Ниже два конфига для этих целей:

; конфиг для первого экземпляра, сервер ; конфиг для второго экземпляра, клиент
;virtual.apache — имя сервера
[https]
accept = 443
connect = 9999
client = yes
[https]
accept = 9999
connect = virtual.apache:443

Теперь нужно, чтобы клиент-браузер пошел логиниться не на сервер, а на нашу «обезьяну», для этого подойдет банальная строчка в файле hosts (на Windows машине):

#1.2.3.4 - IP-адрес сервера
1.2.3.4 virtual.apache

Проверил работу логинясь на защищенную веб-страничку, как и следовало ожидать браузер ругается на левый сертификат. Однако ругань эта риторическая, соединение проходит успешно, в логах виртуального апача ничего подозрительного не обнаружено. Немного осмелев поменял virtual.apache на mail.google.com и пошел проверять почту, все работало как и раньше. Наконец был прописан адрес реального сервера TH, запущен клиент и пару дней посидел ничего особенного не делая в целях проверки.

Вторые шаги

Теперь на виртуалке с линуксом между 443 и 9999 портами сновал в обе стороны расшифрованный трафик, оставалось его поймать для изучения. Гугль был непреклонен, для этой операции подходит только Wireshark и ничего кроме (коммерческие аналоги я не трогал). Поработав с ним некоторое время подумалось, что этот инструмент представляет собой слишком навороченный микроскоп, которым я собирался забить маленький гвоздик. Но главная цель была достигнута и сделаны некоторые выводы:

  • клиент соединяется только по определенному dns-имени
  • в клиенте конект на 443 порт зашит жестко
  • но на сервер можно соединяться и по обычному 80-му порту
  • обмен идет посредством JSON-строк

В процессе работы клиент постоянно что-то посылает и что-то получает, но Wireshark к режиму online не очень приспособлен, поэтому встал вопрос о более приспособленном инструменте. Гугль совершенно озадачил огромных количеством всяких «анализаторов http трафика», пришлось пробовать по-очереди множество вещей, пока не наткнулся на Fiddler. Для моих целей он оказался как нельзя лучше подходящим, одно русскоязычное описание чего стоит — Скриптуемый Отладочный Прокси. Причем декриптование SSL-трафика у него «из коробки» и включается одной галочкой. Fiddler при запуске может регистрировать себя в качестве WinInet Proxy, поэтому любые браузеры и им подобные программы сразу же можно изучать на предмет передаваемых данных. Заточен он конечно же на Web и работу с формами, ловит POST и GET запросы, вобщем понравился очень.

В случае с обычным браузером и stunnel, схема обмена будет такой:

браузер обезьяна сервер
соединение по HTTP на 80 порт —> соединение по HTTPS на 443 порт
замена HTTPS контента на HTTP <— передача серверного сертификата
обычное содержимое —> зашифрованное содержимое

Если же используется Fiddler с включенной опцией HTTPS Decrypt, то схема несколько меняется:

браузер обезьяна сервер
соединение по HTTPS на 443 порт —> соединение по HTTPS на 443 порт
передача сертификата Fiddler <— замена передача серверного сертификата
зашифрованное содержимое расшифровка —> зашифрованное содержимое

Браузер опять будет ругаться на несоответсвие сертификата, но в случае с Fiddler можно насильно добавить его самоподписанный сертификат к доверенным.

Однако клиент TH не расчитан на работу с прокси, о чем предупреждает и мануал. Это недоразумение довольно легко исправилось, также использовалась оплошность разработчиков позволивших соединяться на 80-й порт своего сервера, что позволило отказаться от виртуалки. Итоговая схема работы выглядит так:

  • в hosts добавлена строка
    127.0.0.1 адрес_сервера_TH.com
    клиент вместо своего сервера отправляется на локалхост
  • на локалхосте запущен stunnel с кофигом:
    [https]
    accept = 443
    connect = 8888

    принимает и расшифровывает траф, редиректит его на порт Fiddler-прокси
  • у Fiddler есть свой собственный hosts, который перекрывает системный, в нем запись:
    #1.2.3.4 - настоящий айпишник сервера
    1.2.3.4 адрес_сервера_TH.com
  • далее обмен идет уже по открытому каналу

То есть «обезьяна» вышла весьма простой, stunnel+Fiddler и всё это на одной машине. Далее было весьма прозаично, клиент посылает GET-запросы по простым поводам и POST по сложным, сервер отвечает, я провожу параллели между запросами/ответами и действиями в клиенте. с JSON-массивами легко работать в PHP, был написан простенький эмулятор сервера, все плюшки получены и испробованы, профит получен. Но не тут-то было…

Создаем сложности

Через некоторое время с очередным обновлением клиента дырка с открытым 80-м портом «перестаёт быть». То ли разработчиков смутили мои поползновения, то ли они взялись за голову, но старый способ уже не прокатывал. Тут и понадобилась оказавшаяся ненужной ранее виртуалка с линуксом. По сути задача была простой, перенаправить обычный трафик от Fiddler-а на копию stunnel, которая бы соединялась с реальным сервером, но пришлось поломать голову. Начало схемы копирует вышеприведенную, далее:

  • на машине с клиентом шлюзом по умолчанию прописана виртуалка
  • на виртуалке включен форвардинг
    echo "1" > /proc/sys/net/ipv4/ip_forward
  • там же iptables заворачивает любые конекты к 80-ому порту (от Fiddler-а) на локальный 8888
    iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8888
  • там же запущен stunnel в клиентском режиме, порт 8888 редиректит на реальный защищённый адрес сервера
    client = yes
    [https]
    accept = 8888
    connect = 1.2.3.4:443

Вуаля, теперь сервер даже не догадывается о наличии «обезьяны». Впрочем все остальные программы работающие по 80-му порту теперь тоже насильно заворачиваются на прокси, даже если не имеют такой возможности. Минусы только в том, что они гадят в логи, впрочем это дело легко фильтруется.

Напоследок

В целом схема мне не нравится, есть подозрение что можно сделать более элегантнее. Встречал минисерверы с перловыми скриптами имитирующие такой-же SSL-сервер и живущих на одной машине с клиентской частью, но эта магия мне недоступна. Простого редиректора портов под Windows не нашел, вернее не нашел в существующих утилитах аналога DNAT из iptables. Без него все соединения на 443-й порт будут направлены на изучаемый сервер, что не есть хорошо. Поэтому треьуется виртуалка с каким-нибудь никсом.

К тому же и в этом варианте есть изъян, если разработчики введут проверку соответствия сертификата, то «шеф, все пропало». В данное время после многих очередных обновлений клиентской части на сервер опять можно попасть по 80-му порту, а сертификат сервера на самом деле выписан на другой домен (на тот, где социалки/форумы/магазины), то есть даже браузер будет ругаться. Видимо ситуация разработчиков устраивает, либо продукт не пользуется дикой популярностью 😉

А Скриптуемый Отладочный Прокси в дальнейшем пригождался уже по работе, особенно его скриптуемость, довольно удобно модифицировать запросы по некоторым условиям.

P.S.
Конфиги в большей части писались по памяти, однако суть, я надеюсь, передают верно.

Материалы:
Понимание атак Man-in-the-Middle ARP Cache Poisoning
Понимание атак Man-in-the-Middle Подделка DNS
Понимание атак Man-in-the-Middle Перехват сеанса
Понимание атак Man-in-the-Middle Перехват SSL

Добавить комментарий

Войти с помощью: