IO Ninja – программируемый эмулятор терминала-сниффер (часть 2)

в 1:34, , рубрики: broadcast, named pipes, pcap, serial, tcp, udp, Блог компании Tibbo, отладка, Сетевые технологии, системное администрирование, эмулятор терминала

io ninjaДанная статья является продолжением предыдущей, вводной статьи, в которой речь шла о мотивации и истории создания терминала/сниффера IO Ninja, и было немного рассказано про встроенные возможности нашего продукта. Продолжим рассказ о том, что доступно «из коробки», но с более практическим уклоном.

IO Ninja изначально задумывалась как утилита типа «всё-в-одном», и в комплект поставки входит большое количество встроеных плагинов для работы со всеразличными транспортами в разных режимах. Однако вместо сухого перечисления списка плагинов и их возможностей я решил продемонстрировать маленькую выборку задач из жизни, с которыми в нашей компании сталкивались на практике, и с которыми общеизвестные терминалы и мониторы справляются хуже, чем IO Ninja (а чаще не справляются вообще).

Перенаправление TCP в Serial

tcp-to-serial link settingsПользователи Unix-подобных систем хорошо знакомы с возможностью перенаправления выхода одной программы на вход другой. Связывание сессий (Session Linking) в IO Ninja предоставляет похожий функционал. Различие заключается в том, что вместо однонаправленного каскада данных, как в случае Unix pipes, связываение двух сессий «закорачивает» выход одной на вход другой и наоборот (при этом в лог записываются все передаваемые данные). Тем самым появляется возможность использовать IO Ninja в качестве универсального посредника для перенаправления и/или прослушивания.

Допустим, к компьютеру через последовательный интерфейс (serial) подключено устройство. Открываем IO Ninja и запускаем сессию Serial. Открываем и конфигурируем последовательный порт (возможно, посылаем несколько тестовых команд устройству, дабы убедиться, что оно живо-здорово).

Далее запускаем сессию TCP Listener, выбираем интерфейс и TCP порт, на котором будем слушать. Связываем наши две сессии Serial и TCP Listener через диалог настроек и – вуаля! Теперь к нашему последовательному устройству можно подсоединяться по TCP с любого другого компьютера!

tcp-to-serial link

Поиск устройств в локальном сегменте с помощью UDP broadcast

Типовым методом автообнаружения устройств в сети является широковещательная UDP рассылка некоего эхо-запроса и последующий сбор ответных пакетов – так, в частности, работает автообнаружение у всех встраиваемых модулей, производимых нашей компанией. IO Ninja может быть использована в качестве широковещательного UDP терминала для общения в режиме «one-to-many».

Открываем UDP Socket, прописываем в качестве адреса 255.255.255.255 (или же subnet-broadcast типа 192.168.1.255), и рассылаем эхо-запрос. В результате мы видим список всех устройств в локальном сегменте. Далее, если это необходимо, мы можем продолжать общение с каким-то конкретным устройством.

device auto-discovery

Кстати, обратите внимание на кнопочку с компасом. При работе с UDP (и в особенности на стороне сервера) часто требуется запоминать адрес, с которого пришёл пакет, и отвечать именно туда – соединения-то нет! В принципе, ничто не мешает копировать адрес из лога и вставлять его в поле ввода “Remote address”. Но зачем делать руками то, что можно переложить на машину? Жмём компас, и получаем требуемую автоматизацию – UDP-сессия будет автоматически перенастраивать Remote address.

Сохранение части входного потока в файл

Иногда во время отладки требуется сохранить кусок принятых данных в файл. Это может быть, например, блок, который надо отправить в неизменном виде в этой или какой-то другой сессии, может быть, это переданный удалённым узлом файл, может быть ещё что-то третье.

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

  • Данные могут быть бинарными и содержать непечатаемые символы;
  • Данные могут быть «размазаны» между несколькими пакетами;
  • Нужен нам, как правило, не весь входной поток, а строго определённый блок (а значит, простым перенаправлением потока в файл проблема тоже решается не совсем чисто).

IO Ninja выгодно отличается наличием лога в виде «шестнадцатеричной простыни» со склеиванием входящих пакетов – это позволяет выполнить именно то, что нам надо.

ssh log save as file

Выделяем нужный блок данных (поглядывая, если надо, на статус-бар – там отображается смещение и длина выделенного блока), сохраняем в файл, и потом используем. Например, пересылаем его по другой сессии:

midnight commander on tcp listener

Приём TCP соединений с помощью TCP Listener

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

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

google chrome on tcp listener

Отметим, что в TCP Listener также имеется возможность выбора: принимать или нет новые входящие соединения, если соединение уже имеется в наличии. Данная опция может быть крайне полезной в ситуациях, когда клиент устанавливает множество вторичных соединений на один и тот же адрес (как, например, многие web-браузеры)

Прослушивание TCP соединений с помощью TCP Proxy

IO Ninja включает в себя плагин Network Sniffer – основанный на PCap сетевой сниффер для прослушивания сетевых соединений. Однако, в ряде случаев значительно удобнее использовать другой встроенный плагин, а именно TCP Proxy.

TCP Proxy – это комбинация TCP Connection и TCP Listener, которая позволяет организовать посредника для TCP соединений. Удобство данного подхода заключается в том, что он сразу даёт чистый лог потоков данных в реальном времени (вместо лога в виде пакетов, из которых потоки данных надо ещё потом восстановить). Помимо этого, данная модель работает и там, где прослушивание с помощью сниффера может быть затруднительно (с определёнными моделями сетевых свичей, Wi-Fi карточек и т.д.)

Создаём сессию TCP Proxy, конфигурируем серверную и клиентскую стороны и запускаем наш прокси-сервер. Любое подсоединение к данному серверу породит вторичное подсоединение с клиентской стороны нашего прокси, при этом все данные принятые на клиентской стороне, будет переданы на серверную и наоборот. В этом смысле TCP Proxy напоминает связывание сессий, но специально заточенное под TCP и вследствие этого более удобное.

ftp sniffing with tcp proxy

Отладка Windows Named Pipes

IO Ninja может быть использована в качестве инструмента для отладки достаточно распространённого подхода к IPC (Inter-Process Communication) в Windows – named pipes. В частности, так общаются некоторые наши Windows-драйвера с сопутствующими сервисами и приложениями.

Для эмуляции серверной стороны вашего приложения (той, где вызывается ConnectNamedPipe), запустите Named Pipe Listener. Данный плагин позволяет принимать входящие named pipe-соединения, которые будут исходить от вашего клиентского приложения/сервиса.
После установления соединения вы можете общаться с клиентом, анализируя лог полученных запросов и отсылая ему ответные пакеты (созданные, например, в строителе пакетов).

Для эмуляции клиентской стороны (той, где вызывается CreateFile) используется плагин Generic File.

named pipe to tdevmon

Помимо отладки named pipes (или FIFOs в *nix), данный плагин также может быть использован для чтения и записи в драйверы нестандартных устройств.

Кратко коснёмся вопроса прослушивания named pipes. Предположим, имеется приложение или драйвер, использующие pipes для IPC. Если вы можете каким-то образом настраивать адрес named pipe на клиентской стороне, то появляется возможность прослушивания pipe-соединений с помощью посредника (аналогично TCP Proxy).

Как именно?
Пусть отлаживаемая система устанавливает pipe соединение на \.pipedebuggee_pipe_server. Выбираем какое-нибудь незанятое имя pipe, например, \.pipemy_pipe_proxy. Настраиваем клиентскую сторону отлаживаемой системы на этот наш \.pipemy_pipe_proxy. В IO Ninja открываем пару Pipe Listener и Generic File, связываем их. В Pipe Listener прописываем \.pipemy_pipe_proxy, жмём Listen. В Generic File прописываем \.pipedebuggee_pipe_server, жмём Open. Посредник готов.

Со временем в будущих версиях IO Ninja будет также добавлено полноценное прослушивание named pipes без организации man-in-the-middle (в качестве первого приближения, скорее всего, через user-mode API hooking, а впоследствии – через file system filter).

Отправка «битых» фреймов для тестирования

Необходимость в отправке «битых» или иным образом специально сформированных Ethernet фреймов встречается не столь часто и может казаться относящейся, скорее, к разряду экзотики. Тем не менее данный функционал востребован в ряде вполне себе реальных сценариев. Например, в нашей практике это было необходимо во время отладки реализации TCP/IP стека у производимых нашей компанией встраиваемых модулей; другой реалистичной областью приложения могут быть задачи, стоящие перед специалистами по сетевой безопасности, разработчиками firewall-ов и т.д.

Открываем сессию Network Sniffer, выбираем интерфейс и фильтр захвата, запускаем захват. В строителе пакетов подготавливаем необходимый фрейм – например, можно воспользоваться встроенной библиотекой шаблонов пакетов TCP/IP, или же просто скопировать какой-то из захваченных фреймов в шестнадцатеричный редактор и подправить нужные поля.

inject frame with network sniffer

Нажимаем Send, и любовно составленный нами фрейм отправляется выполнять боевое задание!

Заключение

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

В следующей части статьи мы перейдём к с самому интересному – к программируемости IO Ninja и открываемых этим новых возможностях.

Автор: vovkos

Источник

Поделиться новостью

* - обязательные к заполнению поля