Идентификация утилит ICMP

В настоящее время существует несколько специальных утилит, которые позволяют создавать ICMP датаграммы с заданными параметрами. Они могут использоваться для различных целей: собственно детектирование хоста (в том числе более продвинутое, чем просто ping), идентификация ОС и т.д. В данной статье будут рассматриваться особенности утилит, с помощью которых создаются различные ICMP-датаграммы. Если мы сможем определить используемую в конкретном случае утилиту, то соответственно сможем определить и тип ОС, на которой она выполняется (особенности ОС так или иначе будут влиять на ее работу).

В наше поле зрения попадут следующие утилиты ICMP:
— 'ping' , из набора iputils, идущего вместе с RedHat Linux ( kernel 2.2.14)
— HPING2 beta 54 от antirez ( http://sourceforge.net/projects/hping2 )
— Nemesis v1.1 от obecian (http://www.packetfactory.net/Projects/Nemesis) (http://www.packetninja.net/nemesis/)
— Icmpenum v1.1.1, от Simple Nomad (http://razor.bindview.com)
— SING v1.0 от Alfredo Andres Omella ( http://www.sourceforge.net/projects/sing)
Тип ICMP-сообщения, который мы будем определять во всех утилитах — ICMP Echo. Все утилиты в примерах будут выполняться под RedHat Linux, кernel 2.2.14.

Запрос ICMP Echo
RFC 792 — Internet Control Message Protocol (http://www.ietf.org/rfc/rfc0792.txt ) — определяет способы посылки запросов ICMP Echo. Посылающая сторона инициализирует идентификатор (он используется для уникальной идентификации еcho-запросов) и sequence number (в случае если один хост параллельно пингуется несколькими пакетами), кроме того в в поле данных пакета добавляются некоторые данные ( вообще говоря, произвольные), далее пакет отправляется на конкретный хост. Хосту-получателю необходимо только изменить тип датаграммы на Echo reply и вернуть ее отсылавшему ее хосту (а также контрольную сумму ICMP-заголовка).

Различия между утилитами
Тип Запросов Echo, которые использует утилита Linux ping.
Ниже приводится результат запроса Echo, который генерирует утилита ping из набора iputils (Redhat Linux based on Kernel 2.2.14):

[root@godfather sbin]# ping -c 2 y.y.y.y PING y.y.y.y (y.y.y.y) from x.x.x.x : 56(84) bytes of data. 64 bytes from hostname (y.y.y.y): icmp_seq=0 ttl=255 time=0.1 ms 64 bytes from hostname (y.y.y.y): icmp_seq=1 ttl=255 time=0.1 ms --- y.y.y.y ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.1/0.1/0.1 ms [root@godfather sbin]#
Дамп, который выдает снифер snort:
11/01-23:09:51.398772 x.x.x.x —> y.y.y.y ICMP TTL:64 TOS:0x0 ID:38 ID:1037 Seq:0 ECHO 9F 86 00 3A 85 15 06 00 08 09 0A 0B 0C 0D 0E 0F ...:............ 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F ................ 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F !"#$%&'()*+,-./ 30 31 32 33 34 35 36 37 01234567 11/01-23:09:51.398819 y.y.y.y -> x.x.x.x ICMP TTL:255 TOS:0x0 ID:39 ID:1037 Seq:0 ECHO REPLY 9F 86 00 3A 85 15 06 00 08 09 0A 0B 0C 0D 0E 0F ...:............ 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F ................ 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F !"#$%&'()*+,-./ 30 31 32 33 34 35 36 37 01234567
Ниже приведен посылаемый ICMP запрос:
11/01-23:09:52.391176 x.x.x.x —> y.y.y.y ICMP TTL:64 TOS:0x0 ID:40 ID:1037 Seq:1 ECHO A0 86 00 3A EB F7 05 00 08 09 0A 0B 0C 0D 0E 0F ...:............ 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F ................ 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F !"#$%&'()*+,-./ 30 31 32 33 34 35 36 37 01234567 11/01-23:09:52.391220 y.y.y.y -—> x.x.x.x ICMP TTL:255 TOS:0x0 ID:41 ID:1037 Seq:1 ECHO REPLY A0 86 00 3A EB F7 05 00 08 09 0A 0B 0C 0D 0E 0F ...:............ 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F ................ 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F !"#$%&'()*+,-./ 30 31 32 33 34 35 36 37 01234567
Необходимо помнить несколько важных фактов, которые используются для идентификации ОС. Ping (также как другие утилиты в unix) использует поле данных длиной 56 байт, поэтому общая длина IP-датаграммы составляет 84 байта. Начальное значение ICMP sequence number — 0 и приращение берется равным единице. Ping использует по умолчанию 64 в качестве значения для поля TTL в запросе ICMP echo.
Кроме того, следует учитывать то, как определяются значения IP ID. Трассировка использовалась непосредственно после загрузки системы. Первое значение IP ID, которое было использовано — двузначное десятичное число. Приращение — 1. ICMP ID утилиты ping определяется равным ID процесса, который порождается во время запуска ping.

HPING2
Утилита HPING2 позволяет генерировать специальные ICMP пакеты и просматривать ответы пингуемого хоста в стиле обычного утилиты ping. HPING2 поддерживает фрагментацию, позволяет определять размер и содержимое тела пакета и может использоваться для передачи файлов по поддерживаемым протоколам(для Linux и *BSD).
Далее приведет пример echo запроса, генерируемого HPING2:
— [root@godfather sbin]# hping2 -1 -c 2 y.y.y.y — default routing not present — HPING y.y.y.y (y.y.y.y): icmp mode set, 28 headers + 0 data bytes — 28 bytes from y.y.y.y: icmp_seq=0 ttl=255 id=36 rtt=0.8 ms — 28 bytes from y.y.y.y: icmp_seq=1 ttl=255 id=37 rtt=0.7 ms --- y.y.y.y hping statistic --- 2 packets tramitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.7/0.7/0.8 ms [root@godfather sbin]#
Соответственно дамп снифера snort:
By Martin Roesch (roesch@clark.net, www.snort.org)
11/01-23:08:48.338644 x.x.x.x -> y.y.y.y ICMP TTL:64 TOS:0x0 ID:14546 ID:1032 Seq:0 ECHO 11/01-23:08:48.338691 y.y.y.y -> x.x.x.x ICMP TTL:255 TOS:0x0 ID:36 ID:1032 Seq:0 ECHO REPLY
Обратите внимание на тот факт, что в теле пакета echo-запроса, генерируемого HPING2, по умолчанию не содержится данных. По умолчанию общий размер пакета — 28 байт. Как и обычный ping, HPING2 использует ID своего процесса в качестве значения поля ICMP ID.
[root@godfather /root]# ps aux | grep hping root 4826 0.0 0.4 1200 512 pts/1 S 19:57 0:00 [root@godfather /root]# 11/04-19:57:44.846703 x.x.x.x -> y.y.y.y ICMP TTL:64 TOS:0x0 ID:57750 ID:4826 Seq:20 ECHO In the sendicmp.c the program states: icmp ->un.echo.id = getpid();
Выше был приведен только первый запрос ICMP echo. Как же будет выглядеть второй?
11/01-23:08:49.331187 x.x.x.x -> y.y.y.y ICMP TTL:64 TOS:0x0 ID:19756 ID:1032 Seq:1 ECHO 11/01-23:08:49.331233 y.y.y.y —> x.x.x.x ICMP TTL:255 TOS:0x0 ID:37 ID:1032 Seq:1 ECHO REPLY 23:08:49.331187 > x.x.x.x > y.y.y.y: icmp: echo request (ttl 64, id 19756) 4500 001c 4d2c 0000 4001 2fb3 xxxx xxxx yyyy yyyy 0800 eefb 0804 0100
Сравнивая первую пару ICMP echo пакетов запрос-ответ со второй парой можно заметить, что они не идентичны. Различие присутствует по следующим параметрам:
— различные идентификационные номера в IP пакетах;
— используемые sequence numbers и их приращение относительно друг друга;
— контрольная сумма ICMP заголовка (изменяется поскольку меняется sequence number).
Можно также сделать вывод, что значение поля IP ID не синхронизируется с ID процесса ОС. В приведенных выше примерах, HPING2 использует для IP ID значения 14546 и 19756, в то время как ОС, соответствено, — 36 и 37 ( это легко проверить на локальной системе через loopback и убедиться, что значение IP ID вычисляется случайно)
Таким образом действительно полезный факт, касающийся HPING2, тот, что поле данных имеет нулевой размер.

Nemesis
Nemesis — набор утилит для генерации пакетов TCP/UDP/ICMP/ARP/DNS/RIP/IGMP/OSPF с заданными свойствами (Linux , xBSD, Solaris).
Соответственно приводится запрос ICMP echo, который генерируется одной из утилит набора. Дополнительно используются опции -vv (verbose mode — дополнительная информация ) , -с (ICMP code value — значение, которым будет забиваться поле данных)
[root@godfather /root]# nemesis-icmp -vv -i 8 -c 0 -S x.x.x.x -D y.y.y.y

ICMP Packet Injection -=- The NEMESIS Project 1.1(c) 1999, 2000 obecian
[IP] x.x.x.x > y.y.y.y [Type] ECHO REQUEST [Sequence number] 0 [IP ID] 0 [IP TTL] 254 [IP TOS] 0x18 [IP Frag] 0x4000 Wrote 48 bytes
ICMP пакет сгенерирован. Трассировка, полученная с помощью tcpdump:
00:27:16.153322 > x.x.x.x > y.y.y.y: icmp: echo request (DF) [tos 0x18] (ttl 254, id 29) 4518 0030 001d 4000 fe01 7e95 xxxx xxxx yyyy yyyy 0800 f7ff 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 00:27:16.153375 > y.y.y.y > x.x.x.x: icmp: echo reply [tos 0x18] (ttl 255, id 30) 4518 0030 001e 0000 ff01 bd94 yyyy yyyy xxxx xxxx 0000 ffff 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
Интересующая нас информация, которую можно испльзовать для идентифицикации Nemesis:
• значение поля TOS(type of service) установлено в 0x18(по умолчанию долно использоваться 0x00);
• бит DF;
• значение поля TTL — 254 (ОС, кторую мы используетм в нашем случае, использует по умолчанию значение 64 для пакетов ICMP echo);
• значение поля идентификатора ICMP равно нулю (ICMP_ID=0);
• значение поля ICMP Sequence Number равно нулю (ICMP_Seq=0);
• объем поля данных равен 20 байтам (в то время как Linux и другие unix клоны используют 56 байт, а Microsoft Windows — соответствено 32). Это означает, что по умолчанию, длина датаграммы, которую генерирует Nemesis для запросов ICMP echo, — 48 байт. Все 20 байт поля данных равны нулю.

Далее приведена вторая пара запросов ICMP echo:
00:27:23.294060 > x.x.x.x > y.y.y.y: icmp: echo request (DF) [tos 0x18] (ttl 254, id 31) 4518 0030 001f 4000 fe01 7e93 xxxx xxxx yyyy yyyy 0800 f7ff 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 00:27:23.294097 > y.y.y.y > x.x.x.x: icmp: echo reply [tos 0x18] (ttl 255, id 32) 4518 0030 0020 0000 ff01 bd92 yyyy yyyy xxxx xxxx 0000 ffff 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
Как можно заметить, вторая пара идентична первой за исключением значения идентификатора IP (который используется самой ОС) Контрольная сумма ICMP заголовка одинакова в обоих случаях, поскольку ICMP sequence number и идентификатор ICMP одни и те же.
Obecian обещает скоро выпустить новую версию (v2.0) Nemesis, в которой существенно расширятся возможности создания специфических пакетов.

Icmpenum
Icmpenum — демонстрационая утилита, написанная Simple Nomad. С ее помощью можно генерировать основные типы ICMP запросов: Echo, TimeStamp, Information.

Дамп ICMP echo:
[root@godfather /root]# ./icmpenum -i 1 IP_Address 11/04-19:40:22.256600 x.x.x.x -> y.y.y.y ICMP TTL:255 TOS:0x0 ID:666 ID:39426 Seq:0 ECHO 11/04-19:40:22.256662 y.y.y.y -> x.x.x.x ICMP TTL:255 TOS:0x0 ID:18 ID:39426 Seq:0 ECHO REPLY 19:40:22.256600 > x.x.x.x > y.y.y.y: icmp: echo request (ttl 255, id 666) 4500 001c 029a 0000 ff01 bb44 xxxx xxxx yyyy yyyy 0800 f565 029a 0000
Таким образом, можно сделать вывод, что размер генерируемого пакета всегда равен 28 байтам, причем поле данных — пустое. Сделаем другой запрос ICMP echo:
11/04-19:40:43.826947 x.x.x.x -> y.y.y.y ICMP TTL:255 TOS:0x0 ID:666 ID:39426 Seq:0 ECHO 11/04-19:40:43.826992 y.y.y.y -> x.x.x.x ICMP TTL:255 TOS:0x0 ID:19 ID:39426 Seq:0 ECHO REPLY
Значение IP ID всегда равно 0х029a (десятичное 666). ICMP sequence number всегда равен 0. IP TTL — 255. Таким образом, уже этих данных достаточно для идентификации icmpenum.

SING (Send ICMP Nasty Garbage)
SING — "швейцарский нож" ICMP. Данная утилита позволяет очень гибко определять параметры пакетов протокола ICMP (Linux, *BSD, Solaris). Вот пример отработки запроса ICMP :
[root@godfather /root]# sing -c 4 y.y.y.y SINGing to y.y.y.y (y.y.y.y): 16 data bytes 16 bytes from y.y.y.y: seq=0 ttl=255 TOS=0 time=0.169 ms 16 bytes from y.y.y.y: seq=1 ttl=255 TOS=0 time=0.155 ms 16 bytes from y.y.y.y: seq=2 ttl=255 TOS=0 time=0.136 ms 16 bytes from y.y.y.y: seq=3 ttl=255 TOS=0 time=0.136 ms --- y.y.y.y sing statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.136/0.149/0.169 ms [root@godfather /root]#
А вот дамп поступающих пакетов:
00:24:59.011868 > x.x.x.x > y.y.y.y: icmp: echo request (ttl 255, id 13170) 4500 0024 3372 0000 ff01 8a64 xxxx xxxx yyyy yyyy 0800 7cad 3c04 0000 2be6 e039 332e 0000 00:24:59.011908 > y.y.y.y > x.x.x.x: icmp: echo reply (ttl 255, id 25) 4500 0024 0019 0000 ff01 bdbd yyyy yyyy xxxx xxxx 0000 84ad 3c04 0000 2be6 e039 332e 0000
Следующая информация может использоваться для идентификации SING.
• IP TTL — 255 (для нашей Linux по умолчанию IP TTL равно 64)
• идентификатор ICMP — 0x3c04( 1084). ICMP ID равен значению ID процесса SING
• используются только 8 байт в поле данных, они в свою очередь используются для вычисления RTT. Следовательно, общая длина датаграммы с ICMP echo — 36 байт.
Трассировка tcpdump второй пары пакетов запрос-ответ:
00:25:00.004593 > x.x.x.x > y.y.y.y: icmp: echo request (ttl 255, id 13170) 4500 0024 3372 0000 ff01 8a64 xxxx xxxx yyyy yyyy 0800 d6c9 3c04 0100 2ce6 e039 d711 0000 00:25:00.004630 > y.y.y.y > x.x.x.x: icmp: echo reply (ttl 255, id 26) 4500 0024 001a 0000 ff01 bdbc yyyy yyyy xxxx xxxx 0000 dec9 3c04 0100 2ce6 e039 d711 0000
Вторая пара запросов ICMP Echo позволяет сделать вывод, что:
• значение IP ID используется одно и тоже;
• sequence number отличаются (приращение остается равным единице), поэтому контрольная сумма ICMP заголовка различна.

Способы идентификации ОС, на которой выполнялась утилита (на примере SING)
Если вы не хотите углубляться в исходные тексты, тогда необходимо учесть несколько фактов, которые помогут проидентифицировать ОС, на которой выполнялись разновидности утилиты ping. Рассмотрим эти факты на примере SING. Когда SING запускается из под Linux или xBSD, то она использует в качестве IP ID константу 0x3372. В данном случае исключение составляет Solaris, поскольку эта ОС не позволяет определять IP ID для пакета. Таким образом существует простой способ идентифицикации SING, когда она выполняется на Solaris.
Кроме того, можно использовать тот факт, что по умолчанию Solaris устанавливает в запросе ICMP бит DF (и в данном случае SING не исключение).
Значение поля ICMP ID определяется ID процесса SING в конкретной ОС. Если мы сможем для разных ОС примерно представить диапазон значений выделяемых процессу SING, то это также приблизит нас к решению поставленной задачи. Например, в Linux непосредственно после загрузки значение ICMP ID равно 3c04, FreeBSD cоответственно — 1b03 и Solaris — 7330 hex.

Другие типы запросов ICMP
Мы рассмотрели только один вид запросов ICMP — echo. Если принять во внимание другие типы , то это позволит дополнительно повысить точность идентификации конкретной используемой утилиты, но при этом необходимо учитывать, что echo — это единственный тип ICMP-сообщений, который поддерживают практически все ОС.

Различные опции в различных утилитах
Иногда, просматривая дамп трассировки ICMP датаграм, можно определенно слелать вывод, что значение для какого-либо поля было специально подобрано. Можно ли на основе этого идентифицировать используемую утилиту? 
В большинстве случаев — да. При этом неважно, какой конкретно тип ICMP-запроса используется, поскольку манипуляции со значениями полей остаются специфичными для каждой конкретной утилиты.

Мимикрия под различные ОС
Единственная утилита, обладающая данной способностью, которую я видел, — это SING.

Шаблоны снифера snort
Далее приводятся шаблоны snort для идентификации описанных в данной статье утилит. Использоване поля TOS добавлено в последней версии snort( при этом бит DF до сих пор не учитывается):
alert icmp !$HOME_NET any -> $HOME_NET any (msg:"SING Echo from LINUX/*BSD"; id:13170; itype: 8; dsize: 8;) alert icmp !$HOME_NET any -> $HOME_NET any (msg:"SING Echo from Sun Solaris"; itype: 8; dsize: 8;) alert icmp !$HOME_NET any -> $HOME_NET any (msg:"Nemesis v1.1 Echo"; content:"|0000000000000000000000000000000000000000|"; itype: 8;icmp_id: 0; icmp_seq: 0; dsize: 20;) alert icmp !$HOME_NET any -> $HOME_NET any (msg:"icmpenum v1.1.1"; id: 666; itype: 8;icmp_id: 666; icmp_seq: 0; dsize: 0;) alert icmp !$HOME_NET any -> $HOME_NET any (msg:"HPING2 Echo from LINUX/*BSD"; itype: 8; dsize:0;)
Информация данной статьи впервые была представлена на конференции Black Hat 2000 Amsterdam, 23-25 октября 2000 и доступна на сайте Black Hat:http://www.blackhat.com


Сетевые решения. Статья была опубликована в номере 01 за 2001 год в рубрике технологии

©1999-2024 Сетевые решения