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

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

  • автор:

Полное руководство по сетевому программированию для разработчиков игр. Часть 3. UDP

Да! Раньше наш сокет был сухой и безжизненный, теперь мы заставим его шевелиться! В этой части мы (НАКОНЕЦ-ТО. ) узнаем, как отсылать и принимать данные (пока только по протоколу UDP).

Одноранговый обмен данными

Логически правильно начинать с простого и переходить к более сложному, поэтому мы начнем с UDP. Это, однако, вовсе не означает, что UDP менее важен, чем TCP, вовсе нет. Все зависит от того, что за игру ты хочешь сделать. Для некоторых игр/жанров больше подходит UDP, для других — TCP. Главное сделать правильный выбор («И почему я не послал его подальше и не взял синюю таблетку?! Расскажи он мне тогда все полностью — я бы засунул красную пилюлю ему в задницу!!» (с) Warner Bros — Матрица).

UDP. Что такое «одноранговая передача данных»? Это когда взаимодействуют компьютеры, которые имеют одинаковые права по управлению обменом данными и одинаковые приоритеты (peer-to-peer — «равный равному», не путать с point-to-point protocol). Взаимодействие по протоколу UDP можно сравнить с отправкой и приемом почты. Отправив пакет, остановить его движение нельзя. Как уже было сказано, этот протокол не гарантирует доставку данных, то есть, отправляя данные, надо иметь ввиду, что адресат может их и не получить. Что самое привлекательное в UDP, так это то, что на обоих концах маршрута низкоуровневый код обмена данными одинаков (здесь мы пока еще не рассматриваем UDP по схеме «клиент-сервер»).

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

1. Инициализируем (если надо) необходимые библиотеки и создаем сокет. В качестве второго параметра сокета надо передать константу SOCK_DGRAM — мы используем дэйтаграммы.

2. Если необходимо, привязываем сокет к определенному адресу и порту.

3. Отправляем/принимаем пакеты

4. Закрываем сокет и производим очистку

Допустим, нам надо, чтобы один peer передал другому две строки текста (две последовательности байт) – «AA» и «BBBB». А другой peer передал первому другие две строки – «CCC» и «DD». Вот, как это выглядит на схеме:

Обратите внимание, на то, что происходит с пакетами в Интернет. Как видим, каждая строка передается в своем собственном «конверте»-пакете. То есть они вполне самостоятельны и идут по сети отдельно друг от друга. Все логично.

Первый, второй и четвертый пункты нам уже ясны, и мы знаем как произвести соответствующие действия.

Для того чтобы отправить письмо, надо его написать и заполнить необходимые поля на конверте. Причем надо указать адрес места назначения и имя получателя. Применительно к сокетам это выглядит так: письмо — это наши данные, адрес — это IP адрес получателя, имя — это порт который прослушивает получатель на наличие входящих данных. Мы уже знаем, что адреса и порты у нас хранятся в адресных структурах. Однако наша обертка для адресных структур еще не завершена, мы должны добавить в нее возможность смены порта и адреса после вызова конструктора.

Вот как выглядят соответствующие методы:

// Listing 3.01 win & nix void _sock_addr::set_port ( unsigned short port) < address->sin_port = htons ( port); > void _sock_addr::set_ip ( const char * ip) < address->sin_addr.s_addr = inet_addr ( ip) if ( address->sin_addr.s_addr == INADDR_NONE) throw _sock_exception ( "_sock_addr::set_ip - the provided IP address seems to be invalid"); >

Для чего нам эти методы? Щас узнаем! 🙂 Дело в том, что они позволяют нам использовать одну и ту же адресную структуру для отправки дэйтаграмм разным адресатам, мы просто задаем нужные порт и адрес — и отправляем. Это позволяет нам избежать ненужных операций выделения/освобождения памяти.

Чтобы отправить кому-то дэйтаграмму надо знать адрес получателя. Для этого с получателем либо «договориться заранее» или отправителю должен быть известен адрес постоянного проживания. Если на компьютере получателя несколько сетевых интерфейсов – то он должен при помощи bind() выбрать один из них, иначе при автоматической привязке ему будет назначен какой-то из адресов, по которому пришла первая дэйтаграмма.

Вот так выглядит код для отправки сообщений по протоколу UDP на языке С:

// Linux & FreeBSD int sendto ( int s, const void * msg, int len, int flags, const struct sockaddr * to, int tolen); // Windows int sendto ( SOCKET s, const char * buf, int len, int flags, const struct sockaddr * to, int tolen);

Теперь посмотрим, что к чему. Первый параметр — это дескриптор сокета, через который надо отправлять данные. Следом идет указатель на последовательность байтов (второй параметр), которые составляют тело сообщения (наше письмо другому компьютеру). Дальше нам надо указать длину нашего сообщения (третий параметр). Затем идет число, которое определяет, каким образом система будет обслуживать данную дэйтаграмму (в большинстве случаев нас устроит способ обслуживания по умолчанию — значение 0). Как видно, четвертый параметр формируется из набора флагов, которые мы рассмотрим далее. Пятый параметр — это адресная структура, содержащая адрес и порт получателя дэйтаграммы. И, наконец, шестой параметр (tolen) — это длина указанной адресной структуры (мы уже знаем, что адресные структуры бывают разные, и, соответственно размер у них тоже варьируется). В качестве шестого параметра мы должны указать sizeof(struct sockaddr_in) (равно 16-ти на архитектуре Intel x86). Для чего указывать размер структуры? Очень просто — эта функция должна работать со всеми уровнями модели OSI, поэтому она не знает, с каким семейством адресов имеет дело — мы должны ей сказать об этом.

sendto возвращает количество отосланных байт. «Как?! Разве она не отсылает данные целиком и полностью?!» — спросишь ты. Ответ: да, этот вызов по отношению к дэйтаграммам всегда возвращает число, равное указанной в третьем параметре длине сообщения. В самом простом случае (который мы сейчас рассматриваем) функция sendto() возвратит либо длину отосланного сообщения, либо -1 (*nix) или SOCKET_ERROR (Windows) в случае ошибки при отсылке (напомню, что -1 и SOCKET_ERROR — одно и то же, но константу SOCKET_ERROR определяют разработчики winsock, и мы не будем этому противиться). Также возможно указать 0 в качестве длины сообщения, тогда и возврат будет равен нулю, что абсолютно легально для операционной системы. Но какой смысл в этом? Смысл, оказывается, все-таки есть, причем он вовсе не тривиален, поэтому мы отложим это на потом.

Для того, чтобы понять, что же все-таки делает sendto, мы вспомним, что когда мы создали сокет, система выделила место для буфера исходящих сообщений (пакетов). Функция sendto на самом деле ничего не отсылает, она лишь только помещает сообщение в вышеуказанный буфер. Дальнейшая судьба сообщения полностью зависит от системы. Размер буфера тоже определяется системой, исходя из пропускной способности интерфейса (сетевой карты), размера свободной памяти и других факторов. Мы имеем шанс получить на выходе из sendto -1, когда в буфере исходящих сообщений недостаточно места для помещения нового сообщения в очередь отправки. В этом случае надо проверить код ошибки, и в зависимости от него повторить попытку позднее.

Ранее мы говорили о том, что сокету вовсе не обязательно назначать «имя», система сама осуществит привязку при первом обращении к сокету. Если мы до сих пор не вызвали bind(), то во время вызова sendto() система выберет подходящий интерфейс (подходящий адрес с точки зрения оптимального маршрута сообщения, исходя из адреса получателя, указанного в sendto) и любой доступный порт из списка эфемерных (временных). Узнать порт и адрес, к которым привязан сокет можно при помощи функции getsockname().

Выглядит она так:

// Linux & FreeBSD int getsockname ( int s, struct sockaddr * name, int * namelen); // Windows int getsockname ( SOCKET s, struct sockaddr * name, int * namelen);

s — это дескриптор сокета, чье «имя» нам надо узнать. name — указатель на адресную структуру, куда будут записаны все данные об «имени» сокета. namelen — это длина структуры, которая была записана в name. После этого мы можем использовать поля этой структуры, чтоб узнать порт и адрес нашего сокета.

Все очень просто:

// Listing 3.02 win & nix // если мы уверены в том, что сокет был создан в семействе протоколов PF_INET, то // мы можем безбоязненно использовать следующий код: struct sockaddr_in * name = new struct sockaddr_in; int namelen = sizeof ( struct sockaddr_in); int error = getsockname ( sd, ( struct sockaddr *) name, &namelen); if ( error == -1) < // обработать ошибки > cout  "The socket IP address is: "  ntohs ( name->sin_port)  endl  "The socket port number is: "  inet_ntoa ( name->sin_addr)  endl;

Итак, теперь мы знаем, что успешный вызов sendto вовсе не означает успешную доставку сообщения адресату. Мы просто помещаем его в исходящую очередь. С этого момента мы уже не можем повлиять на его судьбу (вернее, можем, но пока еще не умеем :)) После этого система берет на себя обязательство по дальнейшему распоряжению отправкой дэйтаграммы. После отправки (после того, как сообщение покинет компьютер отправителя) сообщение будет зависеть от промежуточных компьютеров, до тех пор, пока не достигнет адресата.

Страницы: 1 2 Следующая »

31 июля 2003 (Обновление: 24 сен 2009)

Настройка сетевого адаптера для игр в Windows 10

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

Читайте также: Способы увеличения скорости интернета на ПК с Windows

Проверка текущей скорости интернета

Во время выполнения следующих шагов вам наверняка понадобится где-то проверять изменения. Можете использовать разные веб-сервисы по проверке скорости интернета, включая тот, который представлен на нашем сайте. Особое внимание уделяйте такому параметру как пинг, поскольку именно он оказывает основное влияние на импакт в играх.

Настройка сетевого адаптера для игр в Windows 10-01

Настраиваем сетевой адаптер для игр

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

Шаг 1: Обновление сетевых параметров

В первую очередь рекомендуется получить новые сетевые параметры для вашего адаптера. Осуществляется это напрямую через Windows 10 и может исправить ошибки или высокую задержку. Будут получены новые данные для IP, сбросятся настройки, а также удалится кеш DNS, что тоже иногда помогает избавиться от высокого пинга. Для реализации этого этапа в «Командной строке» понадобится поочередно выполнить несколько команд.

    Откройте «Пуск», отыщите «Командную строку» и запустите ее от имени администратора.

Настройка сетевого адаптера для игр в Windows 10-02

Настройка сетевого адаптера для игр в Windows 10-03

Настройка сетевого адаптера для игр в Windows 10-0

Настройка сетевого адаптера для игр в Windows 10-05

Настройка сетевого адаптера для игр в Windows 10-06

Настройка сетевого адаптера для игр в Windows 10-07

Настройка сетевого адаптера для игр в Windows 10-08

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

Шаг 2: Отключение протокола TCP/IPv6

Большинство современных провайдеров все еще работают с протоколом TCP/IPv4, который по умолчанию включен и настроен в Windows 10. Однако и TCP/IPv6 тоже включен, хотя почти всегда нет надобности использовать именно его. Такой протокол больше подходит для опытных пользователей и больших сетей. Например, когда компьютер должен иметь более одного IP-адреса или в сети используются новые технологии, не поддерживаемые на старой версии протокола. Поэтому, если у вас появились проблемы в играх, стоит отключить TCP/IPv6, чтобы приложения не пробовали ссылаться на него при отправке пакетов. Именно такое перераспределение пакетов между протоколами и приводит к повышению пинга. Отключение TCP/IPv6 осуществляется через настройки сетевого адаптера и выглядит следующим образом:

    Для начала откройте «Пуск» и перейдите в «Параметры», кликнув по значку с шестеренкой слева.

Настройка сетевого адаптера для игр в Windows 10-09

Настройка сетевого адаптера для игр в Windows 10-010

Настройка сетевого адаптера для игр в Windows 10-011

Настройка сетевого адаптера для игр в Windows 10-012

Настройка сетевого адаптера для игр в Windows 10-013

Шаг 3: Отключение параметров сетевого адаптера

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

    Снова перейдите к списку сетевых подключений так же, как это было показано в предыдущем шаге. Вызовите контекстное меню сетевого адаптера и выберите пункт «Свойства».

Настройка сетевого адаптера для игр в Windows 10-014

Настройка сетевого адаптера для игр в Windows 10-015

Настройка сетевого адаптера для игр в Windows 10-016

Настройка сетевого адаптера для игр в Windows 10-017

Настройка сетевого адаптера для игр в Windows 10-018

Настройка сетевого адаптера для игр в Windows 10-019

Настройка сетевого адаптера для игр в Windows 10-020

Настройка сетевого адаптера для игр в Windows 10-021

Шаг 4: Управление электропитанием сетевого адаптера

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

    Щелкните правой кнопкой мыши по «Пуску» и из появившегося контекстного меню выберите пункт «Диспетчер устройств».

Настройка сетевого адаптера для игр в Windows 10-022

Настройка сетевого адаптера для игр в Windows 10-023

Настройка сетевого адаптера для игр в Windows 10-024

Шаг 5: Обновление сетевого драйвера

Данный шаг не относится к основным, а выполнить его можно в том случае, если драйвер для сетевой карты вручную не устанавливался вовсе или а результате поиска обнаружилось, что для устройства регулярно выходят обновления. Новый драйвер, особенно если это касается подключения через Wi-Fi, может значительно ускорить сеть или решить старые проблемы совместимости. Его же есть смысл установить и с целью управления теми параметрами, которые были описаны выше, если в свойствах оборудования они не были обнаружены. Больше информации по этой теме вы найдете в другой статье на нашем сайте. В ней будут описаны все доступные методы обновления драйвера сетевого оборудования в Windows 10.

Настройка сетевого адаптера для игр в Windows 10-025

Если проблемы с пингом наблюдаются только в конкретной игре, в первую очередь проверьте качество интернет-соединения в ее настройках. Например, в настройках DOTA 2 есть блок «Соединение», где вы можете выставить «Низкое» или «Высокое» значение. Первый вариант повышает задержку, но делает игровой процесс плавнее. Нечто подобное есть и в некоторых других онлайн-проектах. Вероятно, ранее вы выставляли другое значение, и теперь оно не подходит под текущее качество интернет-соединения. Поменяйте его на противоположное.

Кроме того, прочитайте тематические форумы или самостоятельно задайте там вопрос. Еще можно написать в поддержку разработчика, поскольку иногда решение проблемы бывает не совсем очевидным. В некоторых случаях что-то придется прописать в самой игре, изменить параметры запуска или изменить специфическую настройку в Windows 10. Тут все зависит именно от того, в какой игре возникли проблемы с высокой задержкой (при условии, что в остальных все нормально).

Виктор Бухтеев Вам помогли мои советы?

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

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

Jumbo Frame

Jumbo Frame — Jumbo Packet — Большой кадр:
Использование этого параметра, наверно только гипотетически поможет снизить пинг в играх и наверно какая то выгода будет во время долгих массовых сражений и осад, когда в одну секунду генерируется очень приличное количество трафика. Дело в том, что использование больших кадров должно быть настроено у всех участников взаимодействия, как у клиента и сервера, так и транзитных узлов. Но за пределами вашего провайдера (да и у самого провайдера) mtu всегда примерно равен 1,5 кб плюс\минус десятки байтов. Если использовать его в локальных сетях (где можно точно проконтролировать эту настройку у всех), то там пинг зачастую и так достаточно низкий.
В чем плюс? Если использовать 9 кб у всех участников, вместо 1,5 кб, то для обсчета одного кадра потребуется в 6 раз реже задействовать процессор. Что должно лучше сказаться на прибавке фпс.
В чем минус? Если использовать его только на клиенте, при отсылке на остальных узлах пакет будет фрагментирован, в лучшем случаем на 6 частей, а при mtu Значение: Выкл.

Checksum Offload — IPv4 Checksum Offload — Контрольная сумма разгрузки IPv4:
Если ваш адаптер имеет такую функцию, то включите ее. Это позволит освободить центральный процессор от расчета и проверки контрольных сумм для отправляемых и принимаемых пакетов. Что должно положительно сказаться на фпс в игре. Но бывают и обратные случаи, когда отключение это функции позволяет улучшить пинг и снизить лаги. Так что, попробуйте поиграться с этим параметром, при наличии лагом и скачущего пинга.
Значение: Вкл для Tx и Rx

Speed & Duplex — Link Speed/Duplex Mode — Скорость и дуплекс
Тут нужно проверить, что у вас стоит 10\100\1 Гб дуплекс. При использовании режима полудуплекс, пинг становится выше.
Можете в этом убедиться, переключив режимы и пингануть любой сервер.
Значение: Дуплексный режим

Flow Control — Управление потоком
Данная настройка призвана решать проблему, когда входящий трафик приходит с такой скоростью, что создает угрозу переполнения буфера на сетевом оборудовании и тогда источнику отправляется команда, чтобы он выждал паузу и снова повторил отправку данных, через какой-то промежуток времени. Если же такой команды не послать, то из-за перегрузки часть данных просто потеряется, т.е. в игре это гарантированный лаг. Вроде бы хорошая и правильная и нужная функция, но только для тех кто скачивает большие объемы. В играх как правило трафик приходит не в таком интенсивном режиме. Если же кадр паузы будет послан, то одномоментно увеличится пинг. Т.е. если у вас в играх частые лаги и высокая сетевая задержка, попробуйте поиграться с этим параметром.
Значение: Выключить

Transmit Buffers — Буферы передачи / Receive Buffers — Буферы приема
Зачастую буфер приема имеет в настройках больший размер, так как трафика мы скачиваем больше, чем отдаем. Здесь главное придерживаться правила, что буфер приема минимум должен быть равен 100*mtu. Если mtu=1500 байт, то размер буфера должен быть не меньше 147 кб. Если будет меньше, то в массовых событиях в игре, с генерацией большого количества трафика, возможна потеря пакетов. Прямого влияние на пинг, данные настройки не оказывают. Скорее это касается лагов. Так что убедитесь, что данные параметры выставлены по умолчанию и не имеют слишком малого размера.
Для буфера передачи вполне подойдет заводское значение. Вряд ли на клиенте в игре можно на генерировать столько трафика, чтобы пакеты при этом не поместились в буфер.

TCP/UDP Checksum Offload IPv4/IPv6 — Контрольная сумма разгрузки TCP/UDP IPv4/IPv6
Чтобы узнать, дошел ли пакет до адресата целый и без ошибок, для проверки на другой стороне в него добавляют контрольную сумму, которая рассчитывается на основании данных пакета. Если у вас имеется данная функция в настройке, попробуйте ее включить для обоих типов трафика. Таким образом все вычисления будет проводить не процессор, а сетевой адаптер, что в итоге должно положительно сказаться на фпс в игре.
Значение: Rx & Tx Включить

Receive Side Scaling

Interrupt Moderation — Модерация прерывания
При получении одного пакета, сетевой адаптер вызывает прерывание. Когда идет интенсивный обмен трафиком такие прерывания создают нагрузку на процессор. И чтобы снизить ее, придумали накапливать события в течении какого-то времени и после этого вызывать прерывание (IRQ). Таким образом реже задействуя процессор. У такого способа есть свои плюсы, описанный ранее и так же можно сказать, что вся прелесть этой функции раскрывается для тех, кто много качает.
Из минусов, чтобы пакет был обработан, он ожидает, пока отработает таймер. Это то и добавляет пинга в игре.
Значение: Выключить
Receive Side Scaling — RSS — Получение бокового масштабирования
Это интересный и нужный механизм для обладателей многоядерных процессоров. При включении его, пакеты делятся по потокам и каждый поток может обрабатывать отдельный процессор. Т.е. задействуются все ядра, что должно положительно сказаться на производительности в целом и на пинге в частности. Если эта функция выключена, весь трафик обрабатывается одним ядром.
Но все эти преимущества будут, если драйвер написан без ошибок. Иначе, бывают случаи, когда после включения начинаются проблемы и деградация производительности. Если вы впервые включаете его, внимательно понаблюдайте за сетью какое-то время.
Значение: Включить

Large Send Offload IPv4/IPv6 — Giant Send Offload — Разгрузка при большой отправке IPv4/IPv6
Фрагментацией пакетов данных при отправке будет заниматься сетевой адаптер, а не программное обеспечение. В идеале аппаратное фрагментирование проходит быстрее, меньше задействуется процессор, что в итоге для любителей игр должно положительно сказаться на пинге и фпс.
Есть еще настройка Large Send Offload v2, она выполняет ту же функцию, только для пакетов покрупнее. Иногда ее включение плохо влияет на производительность сети.
Значение: Включить

И в заключении коротко про пинг и представленные настройки

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

Перехват и модификация 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 не будет опубликован. Обязательные поля помечены *