Создание Wireshark плагина для расшифровки EGTS

Введение

Бывает ситуация когда надо посмотреть данные в сетевом дампе, а Wireshark не поддерживает такой протокол и вместо данных в нем можно видеть только набор байт.

первичный дамп

В таком случаем при наличии спецификации можно написать свой парсер протокла, что я и покажу на примере протокола EGTS, о разборе которого я писал ранее.

Создание плагинов в wireshark

Плагины в Wireshark для произвольных протоколов можно делать двумя способами:

  1. С помощью динамических библиотек на языке С.
  2. C помощью Lua плагинов

Про первый способ, как создавать библиотеку можно прочитать на Habr’e. Для себя я выбрал второй способ изза меньших трудозатрат.

Также надо отметить, что если писать планины на С, то придется пересобирать wireshark что мне делать не очень хотелось.

Работа с lua плагинами

Первым шагом нужно убедиться что включена поддержка Lua. Для этого в директори с глобальными настройками в файле init.lua нужно убедиться чт enable_lua = true.

После этого добавляем файл плагина c расширением lua в папку с плагинами, путь до которой можно посмотреть в меню About.

При старте wireshark палинг будет загружен.

Создание плагина для EGTS

Первое что необходимо сделать это объявить объект протокола:

local egts_proto = Proto("egts", "EGTS")

Далее, если нужна кофигурация плагина из мею настроек, то нужно добавить default_settings:

local default_settings =
{
    port = 20629
}

После того как настройки заданы необходимо задасть поля протокола:

local header =
{

    prv      = ProtoField.new("ProtocolVersion", "egts.prv", ftypes.UINT8, nil, base.DEC),
    skid     = ProtoField.new("SecurityKeyID", "egts.skid", ftypes.UINT8, nil, base.DEC),
    prf      = ProtoField.new("Prefix", "egts.prf", ftypes.UINT8, nil, base.DEC, 0xc0),
    ...
}

egts_proto.fields = header

Функция ProtoField.new создает прототип поля в дереве вывода и имеет следующие параметры:

  • имя поля в дереве вывода
  • синоним для поиска из интерфейса Wireshark
  • тип поля
  • псевдоним отображения (необязательно)
  • тип для вывода (необязательно)
  • маска для получения значения по смещению (необязательно)

Теперь для разбора протокола необходито задать функцию dissector:

function egts_proto.dissector(tvbuf, pktinfo, root)
    dissect_tcp_pdus(tvbuf, root, MIN_HEADE_LENGHT, get_egts_length, dissect_egts_pdu)
    local bytes_consumed = tvbuf:len()
    return bytes_consumed
end

Тут видно что вызывается функция dissect_tcp_pdus, которая отвечает за разбивку фреймов в tcp, так как пакет tcp может собедражать в себе несколько фреймов. С помощью данной функции происходит разбиение пакетов по секциям, что актуально только для tcp. В функцию объект пакета в байтах (tvbuf), объект дерева для вывода в интерфейсе (root), размер заголовка пакета, функция для вычисления длины tcp пакета и функция парсинга пакета.

Для функции получения длины сигнатура содержит объект TvbRange с данными (tvbuf), объект с информацией о пакете (pktinfo) и смещение.

Функция для парсинга примает следующие параметры: объект TvbRange, объект Pinfo c информацией о пакете (pktinfo) и объект дерева пакета (root).

После того как парсер написан необходимо добавить его в таблицу декодировщиков:

DissectorTable.get("tcp.port"):add(default_settings.port, egts_proto)

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

Полный плагин можно посмотреть на Github

Для отладки плагина используется функция print(), сначала открывается wireshark, в нем открывается lua консоль, а потом загружете файл дампа и в Lua консоли пойдут сообщения.

Заключение

В итоге получилось следующее:

первичный дамп

Задача написания плагина для Wireshark на Lua, довольно тривиальная задача и все основная работа сводится именно к описанию данных в самом протоколе.

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

Ссылки

  1. Packet Dissection
  2. Пишем плагин-диссектор для Wireshark
  3. Lua Support in Wireshark
  4. Wireshark Developer’s Guide
 
comments powered by Disqus