Как перехватить tcp upd для игр
Перейти к содержимому

Как перехватить tcp upd для игр

  • автор:

Как разобрать сетевой протокол мобильной MMORPG

За годы игры в одну мобильную ММОRPG у меня накопился некоторый опыт по ее реверс-инжинирингу, которым я хотел бы поделиться в цикле статей. Примерные темы:

  1. Разбор формата сообщений между сервером и клиентом.
  2. Написание прослушивающего приложения для просмотра трафика игры в удобном виде.
  3. Перехват трафика и его модификация при помощи не-HTTP прокси-сервера.
  4. Первые шаги к собственному («пиратскому») серверу.

Требуемые инструменты

Для возможности повторения шагов, описанных ниже, потребуются:

  • ПК (я делал на Windows 7/10, но MacOS тоже может подойти, если пункты ниже там доступны);
  • Wireshark для анализа пакетов;
  • 010Editor для парсинга пакетов по шаблону (не обязательно, но позволяет быстро и легко описывать формат сообщений);
  • само мобильное устройство с игрой.

Разбор формата сообщений между сервером и клиентом

Для начала, нам необходимо видеть трафик мобильного устройства. Сделать это достаточно просто (хотя я очень долго доходил до этого очевидного решения): на нашем ПК создаем точку доступа Wi-Fi, подключаемся к ней с мобильного устройства, выбираем в Wireshark нужный интерфейс — и весь мобильный трафик у нас перед глазами.

Зайдя в игру и подождав некоторое время, чтобы запросы, не связанные с самим игровым сервером, прекратились, можно наблюдать следующую картину:

На данном этапе мы уже можем использовать фильтры Wireshark, чтобы видеть только пакеты между игрой и сервером, а также только с полезной нагрузкой:

tcp && tcp.payload && tcp.port == 44325 

Если встать в тихом месте, вдали от других игроков и NPC, и ничего не делать, можно увидеть постоянно повторяющиеся сообщения от сервера и клиента (размером 76 и 84 байт соответственно). В моем случае минимальное количество разнообразных пакетов посылалось на экране выбора персонажа.

Периодичность запроса от клиента очень похожа на пингование. Возьмем несколько сообщений для проверки (3 группы, сверху — запрос с клиента, под ним — ответ сервера):

Первым делом бросается в глаза идентичность пакетов. 8 дополнительных байт у ответа при переводе в десятичную систему очень похожи на метку времени в секундах: 5CD008F816 = 155713765610 (из первой пары). Сверяем часы — да, так и есть. Предыдущие 4 байта совпадают с последними 4 байтами в запросе. При переводе получаем: A4BB16 = 4217110 , что также очень похоже на время, но уже в милисекундах. Оно примерно совпадает со временем с момента запуска игры, и скорее всего так и есть.

Осталось рассмотреть первые 6 байт запроса и ответа. Легко заметить зависимость значения первых четырех байт сообщения (назовем этот параметр L ) от размера сообщения: ответ от сервера больше на 8 байт, значение L тоже увеличилось на 8, однако размер пакета больше на 6 байт значения L в обоих случаях. Также можно заметить что два байта после L сохраняют свое значение как в запросах от клиента, так и от сервера, а учитывая, что их значение отличается на один, можно с уверенностью сказать, что это код сообщения C (связанные коды сообщений скорее всего будут определены последовательно). Общая структура понятна достаточно, чтобы написать минимальный шаблон для 010Editor:

  • первые 4 байта — L — размер полезной нагрузки сообщения;
  • следующие 2 байта — C — код сообщения;
  • сама полезная нагрузка.
struct Event < uint payload_length ; ushort event_code ; byte payload[payload_length] ; >; 

Значит, формат сообщения пинга клиента: послать локальное время пинга; формат ответа сервера: послать то же время и время отправки ответа в секундах. Вроде не сложно, да?

Попробуем разобрать пример посложнее. Стоя в тихом месте и спрятав пакеты пинга, можно найти сообщения телепорта и создания предмета (craft). Начнем с первого. Владея данными игры я знал какое значение точки телепорта искать. Для тестов я использовал точки со значениями 0x2B , 0x67 , 0x6B и 0x1AF . Сравним со значениями в сообщениях: 0x2B , 0x67 , 0x6B и 0x3AF :

Непорядок. Видны две проблемы:

  1. значения не 4-х байтовые, а разного размера;
  2. не все значения совпадают с данными из файлов, причем в данном случае разница равна 128.
  • непонятное 0x08 перед ожидаемым значением;
  • 4-х байтовое значение, на 4 меньшее L (назовем его D . Это поле появляется далеко не во всех сообщениях, что немного странно, но там, где оно есть, зависимость L — 4 = D сохраняется. С одной стороны, для сообщений с простой структурой (как пинг) оно не требуется, но с другой — выглядит оно бесполезным).

Ожидаемые значения 14183 и 14285 тоже не соответствуют действительным 28391 и 28621, но разница тут уже намного больше 128. Проведя много тестов (в том числе и с другими типами сообщений) выяснилось, что чем больше ожидаемое число, тем больше разница между значением в пакете. Что было странно, так это то, что значения до 128 оставались сами собой. Поняли, в чем дело? Очевидная ситуация для тех, кто уже сталкивался с этим, а мне, по незнанию, пришлось два дня разбирать этот «шифр» (в конечном итоге во «взломе» помог анализ значений в бинарном виде). Описанное выше поведение называется Variable Length Quantity (значение переменной длины) — представление числа, в котором используется неопределенное количество байт, где восьмой бит байта (бит продолжения) определяет наличие следующего байта. Из описания очевидно, что чтение VLQ возможно только в порядке Little-Endian. По совпадению все значения в пакетах в таком порядке.

Теперь, когда мы знаем как получить исходное значение, можно написать шаблон для типа:

struct VLQ < local char size = 1; while(true) < byte obf_byte; if ((obf_byte & 0x80) == 0x80) < size++; >else < break; >> FSeek(FTell() - size); byte bytes[size]; local uint64 _ = FromVLQ(bytes, size); >; 

И функцию преобразования массива байтов в целочисленное значение:

uint64 FromVLQ(byte bytes[], char size) < local uint64 source = 0; local int i = 0; local byte x; for (i = 0; i < size; i++) < x = bytes[i]; source |= (x & 0x7F) * Pow(2, i * 7); // Бинарный сдвиг > return source; >; 

Но вернемся к созданию предмета. Опять появляется D и снова 0x08 перед меняющимся значением. Последние два байта сообщения 0x10 0x01 подозрительно похожи на количество предметов крафта, где 0x10 имеет роль, схожую с 0x08 , но по-прежнему непонятную. Зато теперь можно написать шаблон для этого события:

struct CraftEvent < uint data_length ; byte marker1; VLQ craft_id ; byte marker2; VLQ quantity ; >; 

Который будет выглядеть вот так:

И все равно это были простые примеры. Посложнее будет разобрать событие движения персонажа. Какую информацию мы ожидаем увидеть? Как минимум координаты персонажа, куда он смотрит, скорость движения и состояние (стоит, бежит, прыгает и т.д.). Так как строк в сообщении не видно, состояние, скорее всего, описывается через enum . Путем перебора вариантов, попутно сравнивая их с данными из файлов игры, а также через множество тестов, можно найти три XYZ вектора при помощи вот такого громоздкого шаблона:

struct MoveEvent < uint data_length ; byte marker; VLQ move_time ; FSkip(2); byte marker; float position_x ; byte marker; float position_y ; byte marker; float position_z ; FSkip(2); byte marker; float direction_x ; byte marker; float direction_y ; byte marker; float direction_z ; FSkip(2); byte marker; float speed_x ; byte marker; float speed_y ; byte marker; float speed_z ; byte marker; VLQ character_state ; >; 

Зеленая тройка оказалась координатами местоположения, желтые тройки, скорее всего, показывают куда смотрит персонаж и вектор его скорости, а последнее одиночное — состояние персонажа. Можно заметить постоянные байты (маркеры) между значениями координат ( 0x0D перед значением X , 0x015 перед Y и 0x1D перед Z ) и перед состоянием ( 0x30 ), которые подозрительно похожи по смыслу на 0x08 и 0x10 . Проанализировав много маркеров из других событий оказалось, что он определяет тип следующего за ним значения (первыми тремя битами) и семантическмй смысл, т.е. в примере выше если поменять местами вектора, сохранив при этом их маркеры ( 0x120F перед координатами и т.д.), игра (теоретически) должна нормально распарсить сообщение. С учетом этой информации, можно добавить пару новых типов:

struct Packed < VLQ marker ; // Маркер тоже оказался VLQ! local uint size = marker.size; // Некоторые сообщения не содержат значения смещения (в списках, например) и там приходится использовать вот такой вычисленный размер структуры switch (marker._ & 0x7) < case 1: double v; size += 8; break; // Из анализа других событий case 5: float v; size += 4; break; default: VLQ v; size += v.size; break; >>; struct PackedVector3 < Packed marker ; Packed x ; Packed y ; Packed z ; >; 

Теперь наш шаблон сообщения движения значительно сократился:

struct MoveEvent < uint data_length ; Packed move_time ; PackedVector3 position ; PackedVector3 direction ; PackedVector3 speed ; Packed state ; >; 

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

struct PackedString < Packed length; char str[length.v._]; >; 

Теперь, зная примерный формат сообщений, можно написать свое прослушивающее приложение для удобства фильтрации и анализа сообщений, но это уже тема для следующей статьи.

Upd: спасибо aml за подсказку, что описанная выше структура сообщений является Protocol Buffer, а также Tatikoma за ссылку на полезную соответствующую статью.

перехват TCP потока

перевожу сокет в режим получения всех пакетов в сети
sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
.
WSAIoctl(sock, SIO_RCVALL.
.
слушаю сокет, получаю ip пакеты. пакеты идущие с не нужного мне ip адреса/порта отбрасываю

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

но в итоге столкнулся с проблемой, которую никак не могу побороть.
в случае если параллельно с работой сниффера я включаю к примеру закачку файла какого со скорость 100-2000 кб в секунду, то сниффер умирает. умирание заключается в следующем один или несколько пакетов от сервера каким-то образом теряются. не доходят то сокета(после долгих часов отладки пришел к такому выводу). тсп стек перестает собирать пакеты, буфер tcp пакетов в стеке заполняется до отказа, и происходит завершение работы программы.

и теперь собственно сами вопросы:
1. правильно ли я реализую перехват TCP потока? на сколько оправдан/неоправдан этот метод?
2. отчего может происходить пропуск пакета(ов) на сокете? наткнулся на информацию, что у каждого сокета есть некий буффер, в котором скапливаются несчитанные пакеты. подозреваю дело в этом буффере. можно ли его увеличить? информации по этому поводу к сожалению не нашел
пробовал повышать приоритет потока вплоть до realtime. результат был заметен — чтобы убить программу с потоком сниффера приоритета realtime надо гораздо сильнее нагрузить сеть
3. есть ли какие альтернативы реализации вручную tcp стека? можно ли было сделать как-то иначе?
4. стал пробовать переделывать с чистых сокетов на использование pcap библиотеки. но почитав документцию, посмотрев примеры понял что будет в принципе то же самое — настройка фильтра на перехват tcp пакетов, затем прогон всех пакетов через tcp-стек. или я не прав?

пожулуй все
спасибо за внимание

#1
16:01, 29 ноя 2006

Ну реализовывать tcp стек не надо.
Можно попробовать либу libpcap для перехвата.

#2
11:08, 30 ноя 2006

но как настроить фильтры pcap на перехват tcp потока? я пробовал примерно такой фильтр ставить, tcp && src port 45665
пакеты перехватываются, но опять же это лишь та же последовательность пакетов, которую я получаю через сокеты. и эти данные надо пропускать через tcp стек

как с помошью средствт pcap реализовать tcp-стек? может быть, я неправильный фильтр задаю? смотрел примеры к winpcap, искал в гугле информацию по этому поводу, ничего полезного не нахожу. может быть не то ищу?

#3
21:23, 30 ноя 2006

В данном случае проблема действительно в переполнении буфера приёма.

Правильное решение, гарантирующее отсутствие потерь пакетов:
Вклиниться между сервером и клиентом. Т.е. сначала пакет получает перехватчик, обрабатывает и только затем отдаёт клиенту. Если что-то потерялось, то сервер всё равно перешлёт заново, т.к. клиент тоже не получит этих пакетов и не подтвердит их приём.
Чтобы, что-то посоветовать, необходима информация о конфигурации сети. Клиент, сервер, перехватчик запущены на отдельных компах, или например клиент и перехватчик запущены на одном компе?

Простое решение увеличить размер буфера приёма у перехватчика:
Чревато тем, что если клиент константно обрабатывает пакеты от сервера быстрее чем перехватчик, то никакого буфера не хватит.
Увеличить буфер можно, например, через вызов WSARecv. Этой функции надо передавать НЕСКОЛЬКО структур WSABUF (dwBufferCount>1). Либо вызвать её несколько раз (сокеты естественно асинхронные). Вообщем смысл в том, что нужно не допускать ситуации, когда при обработке текущего пакета у сокетов нет буфера, куда читать следующий пакет. Т.е. пока читается (обрабатывается, анализируется) текущий пакет, в сокетах уже ожидает заполнения следующий буфер.

С WinPCap ситуация будет действительно аналогичная RAW сокетам.

#4
15:55, 1 дек 2006

Спасибо за ответ.

> Чтобы, что-то посоветовать, необходима информация о конфигурации сети. Клиент, сервер, перехватчик запущены на отдельных компах, или например клиент и перехватчик запущены на одном компе?
Сервер запущен в интернете. клиент и перехватчик запускаются на одной машине.

> Вклиниться между сервером и клиентом. Т.е. сначала пакет получает перехватчик, обрабатывает и только затем отдаёт клиенту.
Подскажите, каким образом можно организовать такую работу с сокетом?

> Простое решение увеличить размер буфера приёма у перехватчика:
Попробую так сделать.

> С WinPCap ситуация будет действительно аналогичная RAW сокетам.
В этом не уверен. В документации pcap написано, что настраиваемые фильтры pcap(фильтроваться будет по src ip и src port) работают быстрее, чем вызов recv для каждого постороннего udp и tcp пакета. Проверить еще не успел, на выходных обязательно выясню это.

#5
19:15, 1 дек 2006

moridin
>Подскажите, каким образом можно организовать такую работу с сокетом?
1. Использовать библиотеку WinpkFilter (http://www.ntndis.com/w&p.php?id=7) Масса примеров и документации.
Это позволит вклиниться между сетевой картой и приложением на самом низком уровне. Необходима реализация TCP стека.

2. Использовать Winsock Layered Service Provider (LSP).
http://www.microsoft.com/msj/0599/LayeredService/LayeredService.aspx
http://www.codeproject.com/useritems/Windows_WinSock2_LSP.asp
http://www.inf.tsu.ru/library/DiplomaWorks/CompScience/2006/ishina/diplom.pdf
Это позволит вклиниться непосредственно между клиентом и библиотекой сокетов. Т.е. перехватчик будет обрабатывать вызовы, например функции recv вызванной клиентом. Т.е. сначала результат recv получит перехватчик, а затем он отдаст результат клиенту. Реализация TCP стека не требуется.

4. Подменить ws2_32.dll своей вызывающей настоящую Ws2_32.dll.

5. Пропатчить exe клиента чтобы он линковался со специальной dll вместо Ws2_32.dll (модификация метода 4).

Короче многое можно на эту тему придумать.

Снифферы и не только. Выбираем инструмент для перехвата и анализа трафика

Ана­лиз тра­фика — важ­ней­ший этап тес­тирова­ния на про­ник­новение (или даже взло­ма). В переда­ваемых по сети пакетах мож­но обна­ружить мно­го инте­рес­ного, нап­ример пароли для дос­тупа к раз­ным ресур­сам и дру­гие цен­ные дан­ные. Для перех­вата и ана­лиза тра­фика исполь­зуют­ся сниф­феры, которых челове­чес­тво при­дума­ло великое мно­жес­тво. Сегод­ня мы погово­рим о самых популяр­ных сниф­ферах под вин­ду.

Теория

Что­бы перех­ватывать тра­фик, ана­лиза­торы могут исполь­зовать перенап­равле­ние пакетов или задей­ство­вать так называ­емый Promiscuous mode — «нераз­борчи­вый» режим работы сетево­го адап­тера, при котором отклю­чает­ся филь­тра­ция и адап­тер при­нима­ет все пакеты незави­симо от того, кому они адре­сова­ны. В обыч­ной ситу­ации Ethernet-интерфейс филь­тру­ет пакеты на каналь­ном уров­не. При такой филь­тра­ции сетевая кар­та при­нима­ет толь­ко широко­веща­тель­ные зап­росы и пакеты, MAC-адрес в заголов­ке которых сов­пада­ет с ее собс­твен­ным. В режиме Promiscuous все осталь­ные пакеты не отбра­сыва­ются, что и поз­воля­ет сниф­феру перех­ватывать дан­ные.

Те­оре­тичес­ки мож­но собирать вооб­ще все пакеты в сег­менте локаль­ной сети, где уста­нов­лен сниф­фер, одна­ко в этом слу­чае дан­ных для пос­леду­юще­го ана­лиза будет слиш­ком мно­го, да и фай­лы жур­налов быс­тро рас­пухнут до совер­шенно неп­рилич­ных раз­меров. А мож­но нас­тро­ить при­ложе­ние таким обра­зом, что­бы оно отлавли­вало тра­фик толь­ко опре­делен­ных про­токо­лов (HTTP, POP3, IMAP, FTP, Telnet) или ана­лизи­рова­ло лишь пер­вые 100 байт каж­дого пакета, где обыч­но и содер­жится самое инте­рес­ное: адрес целево­го хос­та, логины и пароли. Сов­ремен­ные сниф­феры могут слу­шать в том чис­ле и зашиф­рован­ный тра­фик.

Не­ред­ко ана­лиза­торы тра­фика при­меня­ются в «мир­ных» целях — для диаг­ности­ки сети, выяв­ления и устра­нения непола­док, обна­руже­ния вре­донос­ного ПО или что­бы выяс­нить, чем заняты поль­зовате­ли и какие сай­ты они посеща­ют. Но имен­но при иссле­дова­нии безопас­ности сетево­го перимет­ра или тес­тирова­нии на про­ник­новение сниф­фер — незаме­нимый инс­тру­мент для раз­ведки и сбо­ра дан­ных. Сущес­тву­ют сниф­феры для раз­личных опе­раци­онных сис­тем, кро­ме того, подоб­ное ПО мож­но уста­новить на роуте­ре и иссле­довать весь про­ходя­щий через него тра­фик. Сегод­ня мы погово­рим о наибо­лее рас­простра­нен­ных популяр­ных ана­лиза­торах тра­фика для плат­формы Microsoft Windows.

Wireshark

  • Про­изво­дитель: Wireshark Foundation
  • Сайт:https://www.wireshark.org
  • Ли­цен­зия: бес­плат­но

Об этой прог­рамме зна­ет, навер­ное, каж­дый, кто хотя бы раз стал­кивал­ся с задачей ана­лиза тра­фика. Популяр­ность Wireshark впол­не оправдан­на: во‑пер­вых, дан­ный про­дукт бес­пла­тен, во‑вто­рых, его воз­можнос­тей впол­не хва­тает для решения самых насущ­ных воп­росов, каса­ющих­ся перех­вата и ана­лиза переда­ваемых по сети дан­ных. Про­дукт поль­зует­ся зас­лужен­ной популяр­ностью у вирус­ных ана­лити­ков, реверс‑инже­неров, сис­темных адми­нис­тра­торов и, безус­ловно, пен­тесте­ров.

Что такое Wireshark, знает, наверное, каждый

Этот ана­лиза­тор име­ет рус­ско­языч­ный интерфейс, уме­ет работать с боль­шим количес­твом сетевых про­токо­лов (перечис­лять здесь их все лишено смыс­ла: пол­ный спи­сок мож­но най­ти на сай­те про­изво­дите­ля). В Wireshark мож­но разоб­рать каж­дый перех­вачен­ный пакет на час­ти, прос­мотреть его заголов­ки и содер­жимое. У при­ложе­ния очень удоб­ный механизм навига­ции по пакетам, вклю­чая раз­личные алго­рит­мы их поис­ка и филь­тра­ции, есть мощ­ный механизм сбо­ра ста­тис­тики. Сох­ранен­ные дан­ные мож­но экспор­тировать в раз­ные фор­маты, кро­ме того, сущес­тву­ет воз­можность авто­мати­зиро­вать работу Wireshark с помощью скрип­тов на Lua и под­клю­чать допол­нитель­ные (даже раз­работан­ные самос­тоятель­но) модули для раз­бора и ана­лиза тра­фика.

По­мимо Ethernet, сниф­фер уме­ет перех­ватывать тра­фик бес­про­вод­ных сетей (стан­дарты 802.11 и про­токол Bluetooth). Тул­за поз­воля­ет ана­лизи­ровать тра­фик IP-телефо­нии и вос­ста­нав­ливать TCP-потоки, под­держи­вает­ся ана­лиз тун­нелиро­ван­ного тра­фика. Wireshark отлично справ­ляет­ся с задачей декоди­рова­ния про­токо­лов, но, что­бы понять резуль­таты это­го декоди­рова­ния, надо, безус­ловно, хорошо раз­бирать­ся в их струк­туре.

К недос­таткам Wireshark мож­но отнести то, что вос­ста­нов­ленные потоки не рас­смат­рива­ются прог­раммой как еди­ный буфер памяти, из‑за чего зат­рудне­на их пос­леду­ющая обра­бот­ка. При ана­лизе тун­нелиро­ван­ного тра­фика исполь­зует­ся сра­зу нес­коль­ко модулей раз­бора, и каж­дый пос­леду­ющий в окне прог­раммы замеща­ет резуль­тат работы пре­дыду­щего — в ито­ге ана­лиз тра­фика в мно­гоуров­невых тун­нелях ста­новит­ся невоз­можен.

В целом Wireshark — не прос­то популяр­ный, но очень доб­ротный про­дукт, поз­воля­ющий отсле­дить содер­жимое гуля­ющих по сети пакетов, ско­рость их переда­чи, най­ти «проб­лемные мес­та» в сетевой инфраструк­туре. Но в отли­чие от ком­мерчес­ких при­ложе­ний здесь нет удоб­ных инс­тру­мен­тов визу­али­зации. Кро­ме того, с помощью Wireshark не так уж и прос­то, нап­ример, выловить из тра­фика логины и пароли, а это одна из типич­ных задач при тес­тирова­нии на про­ник­новение.

CommView

  • Про­изво­дитель: TamoSoft
  • Сайт:https://www.tamos.ru/products/commview/
  • Ли­цен­зия: плат­ный, покуп­ка лицен­зии или под­писка

Сре­ди сущес­тву­ющих ныне сниф­феров CommView — один из самых ста­рых и зас­лужен­ных ветера­нов, об этом про­дук­те «Хакер» пи­сал еще в 2001 году. Про­ект жив и по сей день, активно раз­вива­ется и обновля­ется: пос­ледняя на текущий момент вер­сия датиро­вана 2020 годом. Нес­мотря на то что про­дукт плат­ный, про­изво­дитель пред­лага­ет ска­чать три­ал, который поз­воля­ет пос­мотреть работу при­ложе­ния на прак­тике — проб­ная вер­сия сниф­фера перех­ватыва­ет тра­фик в течение пяти минут, пос­ле чего про­сит денег.

CommView — заслуженный «ветеран» в мире снифферов

Прог­рамма име­ет рус­ско­языч­ный интерфейс, что может стать опре­деля­ющим фак­тором при выборе сниф­фера для поль­зовате­лей, не вла­деющих англий­ским. Глав­ное пре­иму­щес­тво CommView — воз­можность гиб­ко нас­тро­ить пра­вила филь­тра­ции пакетов: мож­но выб­рать отдель­ные про­токо­лы, которые будет отсле­живать при­ложе­ние, сор­тировать пакеты по ряду приз­наков, нап­ример по раз­меру или заголов­ку. Ассорти­мент под­держи­ваемых про­токо­лов так­же весь­ма велик: сниф­фер уме­ет работать с самыми рас­простра­нен­ными прик­ладны­ми про­токо­лами, а так­же выпол­нять реконс­трук­цию TCP-сес­сии и UDP-потока. При этом CommView поз­воля­ет ана­лизи­ровать тра­фик вплоть до пакетов про­токо­лов самого низ­кого уров­ня — TCP, UDP, ICMP, а так­же прос­матри­вать «сырые» дан­ные. Прог­рамма показы­вает заголов­ки перех­вачен­ных пакетов, собира­ет под­робную ста­тис­тику IP-тра­фика. Сох­ранен­ные дан­ные мож­но экспор­тировать в 12 раз­личных фор­матов, начиная с .txt и .csv и закан­чивая фай­лами дру­гих ана­лиза­торов вро­де Wireshark.

По­мимо тра­фика на сетевой кар­те, CommView может монито­рить соеди­нения по VPN, а так­же тра­фика, про­ходя­щего через модемы — ана­лого­вые, мобиль­ные, ADSL, ISDN и дру­гие, для чего в сис­тему уста­нав­лива­ется спе­циаль­ный драй­вер. Есть воз­можность перех­вата VoIP-тра­фика и сес­сий SIP-телефо­нии. В сос­тав при­ложе­ния вхо­дит генера­тор пакетов, с помощью которо­го мож­но отпра­вить на задан­ный Ethernet-интерфейс пакет ука­зан­ной дли­ны, с про­изволь­ными заголов­ками и содер­жимым. Есть так­же доволь­но удоб­ный прос­мот­рщик лог‑фай­лов, поз­воля­ющий откры­вать фай­лы жур­налов в отдель­ном окне сниф­фера и выпол­нять поиск по их содер­жимому.

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

Intercepter-NG

Это тоже очень ста­рый и убе­лен­ный седина­ми инс­тру­мент — впер­вые «Хакер» на­писал о нем еще в 2012 году. C тех пор раз­рабаты­ваемый нашими сооте­чес­твен­никами про­ект не толь­ко не исчез с прос­торов интерне­та, как мно­гие его кон­курен­ты, но даже активно раз­вивал­ся и совер­шенс­тво­вал­ся — пос­ледняя акту­аль­ная редак­ция сниф­фера датиро­вана 2020 годом. Сущес­тву­ет вер­сия прог­раммы для Android в виде .APK-фай­ла и даже кон­соль­ная вер­сия это­го инс­тру­мен­та для Unix.

Присоединяйся к сообществу «Xakep.ru»!

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

Перехват и модификация TCP / IP трафика на лету с помощью Trudy

Существует несколько отличных инструментов для перехвата сетевого трафика. Так, Scapy и Wireshark — прекрасные решения для организации пассивного сниффинга, а Scapy, к тому же, способен отправлять дополнительные пакеты.

В случае, если вам необходимо перехватить траффик в позиции посредника (Man-in-the-Middle), вы можете использовать такие популярные инструменты, как Fiddler, Burp Suite или OWASP ZAP. Это хорошие решения, однако, они ориентированы только на протоколы HTTP(S). Но какое программное обеспечение использовать, если вам нужно модифицировать общий не-HTTP-трафик?

Так, например, если вам необходимо проанализировать трафик системы обмена сообщениями Telegram, который использует свой собственный протокол MTProto, работающий прямо поверх TCP/IP-пакетов (другими словами, HTTP или HTTPS вообще не используется), то в данном случае упомянутые выше инструменты не подойдут.

Одним из инструментов со схожими функциональными возможностями является Ettercap. Он предоставляет простой интерфейс фильтрации, позволяющий изменять передаваемые данные. К сожалению, Ettercap требует, чтобы фильтры были написаны на его собственном языке, что существенно ограничивает количество пользователей, способных полноценно использовать его для своих нужд.

Двумя другими инструментами, на которые вы также можете обратить свое внимание, являются: Mallory и Trudy. Программное обеспечение Mallory можно найти на github ( https://github.com/intrepidusgroup/mallory ), и о нем упоминали еще в далеком 2010 году на конференции Black Hat USA ( https://www.youtube.com/watch?v=0ZquG1p0eKA ). С тех пор много воды утекло, и в настоящее время данный проект, похоже, заброшен. Поэтому в рамках данной статьи мы основное внимание уделим второму программному инструментарию — Trudy, автором которого является @kelbyludwig, а исходный код данного программного обеспечения также доступен на github ( https://github.com/praetorian-code/trudy ).

Перехват и модификация трафика с помощью Trudy

Перехват трафика с помощью Trudy

Программное обеспечение Trudy может перехватить и модифицировать любой трафик TCP, а его создатели, когда работали над реализацией проекта, скорее всего, были вдохновлены программным обеспечением Mallory, упомянутым чуть выше. Как говорится в документации, Trudy является «прозрачным прокси-сервером (transparent proxy), который может изменять и сбрасывать трафик для произвольных TCP-соединений». Весь трафик направляется через Trudy, который применяет так называемые модули для его модификации.

Модули Trudy представляют собой ориентированные на конкретную функциональность предварительно запрограммированные части кода, которые пользователь может модифицировать для получения необходимого ему результата. Также Trudy предоставляет интерфейсы для этих модулей ( https://github.com/praetorian-code/trudy/blob/master/module/module.go ). Поскольку Trudy написан на Go, то все модули и их интерфейсы также должны быть написаны на Go. Для маршрутизации трафика и правильной настройки среды доступна подготовленная виртуальная машина.

Настройка виртуальной машины для подмены трафика

Виртуальная машина устанавливает все необходимое программное обеспечение и сам Trudy. Затем она направляет весь трафик в Trudy и из него, используя утилиту iptables. Trudy получает весь трафик, модифицирует его на основе используемого модуля, а затем отправляет трафик обратно в Интернет (более детально смотрите на рисунке 1).

Перехват и модификация TCP / IP трафика

Рисунок 1. Trudy получает весь трафик, модифицирует его на основе используемого модуля, а затем отправляет трафик обратно в Интернет.

Модули Trudy

Использовать модули Trudy довольно просто. Trudy вызывает определенные методы в фиксированном порядке, каждый из которых предназначен для одного конкретного действия:

  • Deserialize () — преобразует необработанную полезную нагрузку в известную структуру данных (например, HTTP).
  • Drop () — если возвращено значение «true», весь пакет отбрасывается.
  • DoMangle () — если возвращено значение «true», вызывается метод Mangle ().
  • Mangle () — изменяет полезную нагрузку.
  • DoIntercept () — если возвращено значение «true», данные отправляются в интерпретатор Trudy.
  • DoPrint () — если возвращено значение «true», вызывается метод PrettyPrint().
  • PrettyPrint () — печатает данные в формате, удобном для человеческого восприятия.
  • Serialize () — преобразует данные обратно в необработанную полезную нагрузку, если они ранее были «десериализованы».
  • BeforeWriteToClient (p pipe.Pipe) — функция, которая вызывается перед отправкой данных клиенту.
  • BeforeWriteToServer (p pipe.Pipe) — функция, которая вызывается перед отправкой данных северу.
  • AfterWriteToClient (p pipe.Pipe) — функция, которая вызывается после отправки данных клиенту.
  • AfterWriteToServer (p pipe.Pipe) — функция, которая вызывается после отправки данных северу.

Пример изменения (подмены) трафика с помощью Trudy

Предлагаем вашему вниманию простой пример модуля, который искажает весь входящий трафик, полученный с IP-адреса «139.59.129.86» через порт 80. Он делает это путем перезаписи всей полезной нагрузки TCP / IP в нули. Основная часть модуля использует функции DoMangle () и Mangle () (более детально смотрите на рисунке 2).

Пример изменения (подмены) трафика с помощью Trudy

Рисунок 2. Основная часть модуля Trudy, который подменяет на нули весь входящий трафик, полученный с IP-адреса «139.59.129.86» через порт 80, использует функции DoMangle () и Mangle ()

Так, как видно на примере, функция DoMangle () ограничивает подмену указанным IP-адресом, а Mangle () выполняет всю фактическую работу по превращению этого трафика в нули.

После настройки Trudy по этому примеру модуля, мы можем попытаться получить доступ к сайту с указанным IP-адресом через обычный браузер. Запрос будет отправляться нормально, но ответ будет перезаписан нулями. Браузер явно не сможет разобрать ответ и, в конечном итоге, истечет время ожидания.

Мы можем подтвердить это с помощью WireShark. На рисунке 3 показан измененный ответ. Зона, отмеченная синей линией, — полезная нагрузка TCP / IP, полная нулей, как и ожидалось. При этом заголовки TCP / IP (часть битов вне синей рамки), остались нетронутыми.

Проверка результатов работы модуля Trudy, выполненная с помощью WireShark

Рисунок 3. Проверка результатов работы модуля Trudy, выполненная с помощью WireShark.

Весь модуль вы можете найти здесь: https://bit.ly/3gdtqHW

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

Подобным образом вы можете легко использовать Trudy для множества других задач по перехвату и модификации трафика TCP / IP в эфире.

Появились вопросы или нужна консультация? Обращайтесь!

Антон Кочуков

Вечный параноик, Антон Кочуков.

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *