
MikroTik удалённый джейлбрейк для v6.x.x
______ ____ _____ _____ _ _ | ____/ __ \_ _|/ ____| | | | | |__ | | | || | | (___ | |_ ___ __| | | __|| | | || | \___ \| __/ _ \/ _` | | | | |__| || |_ ____) | || __/ (_| | |_| \____/_____|_____/ \__\___|\__,_| # FOISted: удалённый джейлбрейк MikroTik # Описание FOISted — это эксплойт для двух пост-аутентификационных уязвимостей в RouterOS от MikroTik. Он позволяет удалённо выполнить джейлбрейк RouterOS версий с 6.34 (2016) по 6.49.6 (последний выпуск v6). Этот репозиторий содержит скрипт эксплойта для устройств на x86. Уязвимость существует и на других версиях устройств; написание ropchain оставлено читателю в качестве упражнения :) Дополнительную информацию можно найти в нашем посте в блоге о внутренностях RouterOS: https://margin.re/blog/pulling-mikrotik-into-the-limelight.aspx # Использование **Автоматически:** ```console $ python3 exploit.py -H <router_ip> -u <username> -p <password> ``` Затем: ```console $ nc <router_ip> 1337 ``` Скрипт эксплойта сам определит версию RouterOS и автоматически развернёт подходящую ropchain. Примечание: сейчас поддерживается только x86 RouterOS. Если ваша версия по какой-то причине не определяется, вы можете указать её явно: ```sh -v <version> # e.g. 6.49.6 ``` Если вы запускаете это на более новых версиях RouterOS, чем 6.49.6 (последняя на момент публичного релиза), вашей версии RouterOS может не быть в базе гаджетов (`./db`). Вместо этого вы можете передать путь к `/nova/bin/www`, и скрипт эксплойта автоматически попытается найти подходящие гаджеты для ropchain: ```sh -f /path/to/nova/bin/www ``` # Как это работает? FOISted использует две уязвимости в RouterOS v6 для удалённого выполнения кода. В этом разделе мы рассмотрим базовые сведения о IPC в RouterOS и обсудим обе уязвимости. Примечание: этот раздел по большей части представляет собой сокращённую версию нашего [полного поста в блоге](https://margin.re/blog/pulling-mikrotik-into-the-limelight.aspx). Обязательно загляните туда за подробностями! ## IPC в RouterOS Внутри RouterOS от MikroTik программы общаются друг с другом с помощью собственного протокола IPC. Фактические пакеты данных — это Nova Messages (внутри — `nv::message`). Они существуют в псевдо-JSON формате (до 6.38) и в сериализованном бинарном формате:  Каждый процесс имеет фиксированный адрес внутри системы RouterOS; например, `/nova/bin/user` находится по адресу `13`, а `/nova/bin/www` — по адресу `70`. Кроме того, каждая программа может регистрировать обработчики, реализующие определённую функциональность в подпространстве имён. Например, у `/nova/bin/user` есть обработчик по адресу `4`, который выступает в роли конечной точки «login» и выполняет аутентификацию для других сервисов:  IPC-общение — ключевая часть работы RouterOS. Оно используется для: - выполнения аутентификации - обновления/получения параметров конфигурации - отправки частых обновлений о состоянии процессов (например, сетевой статистики) - управления доступом пользователей - уведомления процессов об отключении клиента - ... и многого другого В ходе нашего реверс-инжиниринга мы написали внутренний инструмент трассировки сообщений, который позволяет визуализировать все сообщения, которыми обменивается роутер во время работы. В следующем демо вы можете увидеть все сообщения, которыми мы обмениваемся при перелистывании страниц веб-интерфейса: https://youtu.be/Em1hVWnbzQ4 [смотреть](https://youtu.be/Em1hVWnbzQ4) ## Баг 1: FoisHandler Веб-интерфейс RouterOS реализован бинарником `/nova/bin/www`. Однако отдельные страницы могут обрабатываться отдельными библиотеками-«сервлетами», реализующими функциональность в отдельных разделяемых библиотеках. Например, сервлет `jsproxy.p` обрабатывает запросы к `/jsproxy`, а сервлет `winbox.p` — запросы к `/winbox`, и т.д. Эти сервлеты — библиотеки, которые загружаются в `/nova/bin/www` при _первом_ обращении к ним. Например, при первой загрузке `/jsproxy` библиотека `jsproxy.p` загружается в адресное пространство. В процессе загрузки этой библиотеки мы заметили в трассировщике сообщений кое-что интересное:  А именно, мы обнаружили сообщение, которое отправлялось _из_ бинарника www обработчику №2 самого www. Это уже подозрительно, поскольку IPC в RouterOS предназначен для _**меж**процессного взаимодействия_, а не для общения внутри одного и того же процесса... Кроме того, мы заметили, что два аргумента, судя по всему, были виртуальными указателями (32-битный x86), что вызвало наш интерес, поскольку это было очень необычно. Исследовав фактические функции внутри обработчика №2 `/nova/bin/www`, мы находим функцию `FoisHandler::cmdUnknown`, которая запускается при получении сообщений такого типа. Удивительно, но эта функция извлекает параметр `0x11` из сообщения и _вызывает его как функцию_, используя два других параметра в качестве аргументов! Итак, очевидно, что если мы сможем отправить контролируемое сообщение, которое попадёт в этот обработчик, мы сможем вызвать любую нужную функцию. А оттуда уже довольно легко перейти к ropchain и сделать что-то более серьёзное. ## Отправка IPC-сообщений Существует несколько способов отправлять внутренние IPC-сообщения, будучи пользователем RouterOS. По сути, все внешние клиенты позволяют отправлять произвольные сообщения после аутентификации: - Winbox (доступен на порту `8291`) -- используется клиентом `winbox.exe` - MAC Telnet -- используется для подключения, когда у роутера нет IP-адреса - WebFig -- используется веб-интерфейсом Эти интерфейсы различаются способом выполнения первоначального аутентификационного рукопожатия, но после аутентификации позволяют пользователю проксировать произвольные Nova Messages во внутреннюю систему. Смотрите наш [пост в блоге](https://margin.re/blog/mikrotik-authentication-revealed.aspx) и [репозиторий](https://github.com/MarginResearch/mikrotik_authentication) по реверс-инжинирингу криптографических протоколов Winbox и MAC Telnet! В данной реализации эксплойта мы используем конечную точку WebFig как основной механизм связи. Смотрите `webfig.py` — нашу реверс-инженерную реализацию клиента. Однако при попытке вызвать нашу уязвимую конечную точку `FoisHandler` возникает проблема: Каждый обработчик в RouterOS может задавать битовую маску «policy», определяющую, каким пользователям разрешено его вызывать. Оказывается, у `FoisHandler` политика равна `0x80000000`, что означает доступ только изнутри (т.е. сообщения от других системных процессов). Будучи администратором, через GUI мы можем установить максимальную битовую маску прав только `0x7fffe`, чего недостаточно. ## Баг 2: Повышение привилегий Это подводит нас ко второму багу: повышению привилегий с администратора до «супер-администратора». Хотя GUI позволяет установить битовую маску прав только `0x7fffe`, внутри он на самом деле просто отправляет IPC-сообщение, в одном из полей которого содержится значение битовой маски:  Так что мы можем просто подделать собственное сообщение, установив значение битовой маски прав в `0xffffffff`! Как только мы это сделаем, у нас появится неограниченный доступ к любой конечной точке в системе! ## Реализация эксплойта Наш эксплойт начинается с загрузки двух файлов в систему по FTP: - `stage2`: содержит генератор reverse shell, слушающий порт 1337 - `busybox`: предоставляет нам полноценную среду оболочки Затем эксплойт выполняет повышение привилегий, чтобы получить доступ к конечной точке `FoisHandler`. Наконец, мы отправляем специально сформированное сообщение для перехода к ropchain, встроенной в сообщение. Ropchain вычисляет адреса `chmod` и `execve` в `uClibc` и выполняет: - `chmod 0777 stage2` - `execve stage2` Как только `stage2` запущен, вы можете подключиться к порту 1337 и получить оболочку! # Часто задаваемые вопросы (FAQ) ## Могут ли другие использовать это для взлома моего роутера? Нет, для эксплуатации обеих этих уязвимостей требуются учётные данные администратора. ## На каких версиях это работает? Уязвимости существуют по крайней мере с 6.27 (самая ранняя версия, которую нам удалось скачать) до самой последней v6: 6.49.6. Веб-интерфейс был переработан в RouterOS v7, и уязвимый обработчик был полностью удалён. Наш POC написан для x86. Скрипт эксплойта работает (проверено!) со всеми версиями RouterOS с 6.34 по 6.49.6.