пятница, 23 марта 2018 г.

Получение root на Mikrotik с USB портом

Вдохновившись прочтением презентации Kirils Solovjovs по поводу получения прав root и запуску своих приложений на RouterOS, надумал наконец поднять на своем RB951G-2HnD что-нибудь интересное, вроде полноценного bind9.

В версиях до 6.41 для получения рутованного shell было достаточно создать файл /nova/etc/devel-login (достигалось это путем создания файла бэкапа конфигурации, его исправления и последующей загрузки на устройство, см код тут, а в еще более старых версиях OS, как поступали китайские товарищи, можно было просто выполнить команду "/tool sniffer save file-name=../../nova/etc/devel-login"), однако, в последних версиях этот вариант был прикрыт. Вместо него теперь проверяется наличие пакета "option" при вводе логина devel.
Kirils обновил свою jailbreak tool, но мне его подход не нравится - рутер необходимо загрузить со специального образа, потом он патчит в прошивке файл libumsg.so и делает ряд других изменений на файловой системе устройства.

Мой девайс имеет USB порт, поэтому я решил вспомнить древний хак, который использовал еще когда занимался реверсингом телевизоров Samsung: вставить USB флешку, отформатированную в ext3, на которой создан symlink на корневой каталог. Проверил - работает.

Опишу подробнее.
1. Берем USB флешку (или HDD), отформатированную в EXT3. Желательно отформатировать ее в самом устройстве.
2. Подключаем ее к ПК, и в полноценном Linux (WSL для Windows 10 пока не понимает EXT3) пишем:
  1. ln -s / /USB_disk_mount_point/root
где "USB_disk_mount_point" - папка монтирования флешки.
3. Подключаем флешку в рутер.
4. Заходим на рутер по SFTP. Открываем папку "disk1", в ней заходим в нашу "root", и видим корень рутера:

5. Заходим в папку "pckg", создаем в ней папку "option".
6. Заходим на устройство по telnet. Логин: devel, пароль - как у учетной записи администратора:
Команды "ls" здесь нет, но кнопку TAB никто не отменял. При желании можно использовать "полноценный" busybox, собранный для Big Endian MIPS отсюда.
7. ......
8. PROFIT.

Так как мы не создали реальный пакет "option", а обманули код функции nv::hasPackage(const string*), которая просто проверяет наличие файла/папки с заданным именем в "/pckg", то при перезагрузке созданная нами папка "option" исчезнет. Необходимо автоматизировать её создание при ребуте. Делается это просто - создаем задачу, которая создает файл "/pckg/option". Например, для этого можно использовать такой скрипт:

  1. {
  2. /system scheduler
  3. add comment="" disabled=no start-time=startup interval=0 name=onboot\ 
  4.     on-event=createpkg\
  5.     policy=reboot,read,write,policy,test,password,sniff,sensitive     
  6. /system script
  7. add name=createpkg owner=admin policy=\
  8.     reboot,read,write,policy,test,password,sniff,sensitive source=\
  9.     ":delay 10\r\n\
  10.     /tool sniffer save file-name=disk1/root/pckg/option"
  11. }


Микротик может легко закрыть данную "дыру", поправив код FTP сервера таким образом, чтобы он игнорировал symbolic links. А также поправить работу с файлами из скриптов, добавив флаг O_NOFOLLOW при вызове функции open(), или "нормализуя" путь и отсекая всё, что выходит за разрешенные рамки - но это наверняка что-нибудь да поломает. Так что, думаю, еще хоть с пол года, но данная "дыра" просуществует.

Чтобы не держать USB флешку постоянно вставленной - можно создать symlink во внутреннем каталоге устройства, зайдя на него по telnet и выполнив команду:
  1. ln -s / /rw/disk/root
В таком случае необходимо так же поправить путь в скрипте шедулера с "disk1/root/pckg/option" на "root/pckg/option".


Обновление:
Алгоритм, предложенный в данной статье для получения интерактивного SHELL с правами рута более не работает. Начиная с версии 6.42 поменялся способ проверки наличия пакета option. Теперь не просто проверяется наличие файла /pckg/option, а дополнительно осуществляется проверка, что он является symbolic link в папку /bndl/.
Однако, по прежнему работает автоматический запуск скриптов, как я описал тут. Достаточно в скрипт добавить строки:
  1. rm -rf /pckg/option
  2. ln -s /bndl/dhcp /pckg/option
и мы снова получаем SHELL.