Статьи

tcpdump: обучение чтению пакетов UDP

Фил и я провели часть пятничного дня, настраивая statsd :

Сетевой демон, который работает на платформе Node.js и прослушивает статистику, такую ​​как счетчики и таймеры, отправляемую по UDP, и отправляет агрегаты одной или нескольким подключаемым внутренним службам.

Мы настроили его на прослушивание порта по умолчанию 8125, а затем использовали netcat для отправки пакетов UDP, чтобы посмотреть, работает ли он так:

echo -n "blah:36|c" | nc -w 1 -u -4 localhost 8125

Мы использовали tcpdump для захвата любых пакетов UDP через порт 8125, например:

tcpdump -i lo udp port 8125 -vv -X

Чтобы кратко объяснить варианты, которые мы передали ему:

  • -i lo только перехватывает пакеты по локальной петле, т.е. пакеты, отправленные на локальный хост
  • udp означает, что будут перехватываться только пакеты UDP. Другие типы пакетов, которые мы могли бы перехватить, могут быть, например, tcp или icmp.
  • -vv просто дает нам более подробный вывод
  • -X выводит данные в пакетах UDP в формате ASCII, а также в шестнадцатеричном виде. Если бы мы просто хотели последнее, мы могли бы использовать опцию -x

Вот как выглядит одно из сообщений, полученных tcpdump:

13:16:40.317636 IP (tos 0x0, ttl 64, id 58103, offset 0, flags [DF], proto UDP (17), length 37)
    localhost.48358 > localhost.8125: [bad udp cksum 7c8f!] UDP, length 9
0x0000:  4500 0025 e2f7 4000 4011 59ce 7f00 0001  E..%..@[email protected].....
0x0010:  7f00 0001 bce6 1fbd 0011 fe24 626c 6168  ...........$blah
0x0020:  3a33 367c 63                             :36|c

Последние три строки этого вывода детализируют заголовок IP, заголовок UDP и данные в пакете. Следующая диаграмма весьма полезна для понимания того, что определяет каждая часть заголовка IP:

IP-заголовок

Источник: WTCS.org

Эта диаграмма определяет вещи в терминах битов, тогда как вывод tcpdump в шестнадцатеричном формате. Каждый блок из 4 шестнадцатеричных цифр эквивалентен 16 битам.

В этом случае нам может быть интересна пара частей заголовка IP.

Первые 4 бита / 1 цифра определяют версию IP, которая в данном случае равна 4, поскольку мы используем IPv4.

Следующие 4 бита определяют длину Интернет-заголовка — количество 32-битных слов в заголовке. В этом случае значение равно 5, поэтому мы знаем, что общая длина IP-заголовка будет 160 бит (5 * 32 = 160).

Следующие несколько битов не очень интересны, но мы можем видеть исходный IP-адрес со смещением 96 бит и покрывать следующие 32 бита:

0 × 0000: 4500 0025 e2f7 4000 4011 59ce 7f00 0001

Мы знаем, что это будет представлять IPv4-адрес, поэтому он будет представлен как «xxxx», где максимальное значение x составляет 255.

В этом случае, поскольку мы просто отправляем пакеты локально, это переводится в 127.0.0.1:

  • 7f => 127
  • 00 => 0
  • 00 => 0
  • 01 => 1

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

0 × 0010: 7f00 0001 bce6 1fbd 0011 fe24 626c 6168

Теперь мы рассмотрели 160 бит, что означает, что заголовок IP завершен, и мы можем перейти к полезной нагрузке IP, которая начинается с заголовка UDP:

Udp заголовок

Источник: ciscoskills.net

Мы начнем с порта источника, который является ‘bce6’ или 48358 в десятичном формате . Мы также можем видеть это значение во 2-й строке вывода tcpdump.

Следующие 16 бит / 4 цифры — это порт назначения, который равен «1fbd» или 8125 в десятичном формате — именно то, что мы ожидали.

Следующие 32 бита / 2 блока из 4 цифр определяют длину и контрольную сумму, но после этого мы достигаем части данных пакета, которая должна содержать «blah: 36 | c».

Слово «бла» определяется так:

626c 6168

00 × 62 — это 98 в десятичном виде, и мы можем использовать таблицу кодирования UTF-8, чтобы увидеть, что 98 отображается на букву «b».

00x6c = 108 или буква ‘l’, 00 × 61 — 97 или буква ‘a’ и 00 × 68 — 104 или буква ‘h’

Мы переносим в последнюю строку остальные данные, которые мы хотели отправить в statsd:

0x0020:  3a33 367c 63

Он следует той же схеме, где 00x3a — 58 или символ ‘:’ и т. Д.

И теперь у меня есть немного лучшее представление о том, как читать вывод tcpdump, чем когда я начал писать это! Как обычно, любые советы или подсказки приветствуются.

Я нашел эту статью полезной для первоначального понимания, как читать вывод, но я думаю, что диаграммы выше работают лучше всего! « Анатомия пакета данных » TechRepublic также дает хорошее объяснение.