No Leak, No Problem – Bypassing ASLR with a ROP Chain to Gain RCE
В статье исследуется обход ASLR с помощью ROP-цепи для получения RCE на современном IoT-устройстве — IP-камере INSTAR IN-8401 2K+. Автор, продолжая предыдущие исследования по эксплуатации ARM, извлек прошивку устройства, обнаружил неизвестную уязвимость и разработал сложный эксплойт. Согласно Shodan, в интернете доступно около 12 000 устройств INSTAR, что делает исследования актуальными для безопасности IoT.
Для анализа потребовался доступ к прошивке, который был получен через физический интерфейс UART. Несмотря на неудачные попытки получить root-доступ через прерывание загрузки (удалось получить доступ только к загрузчику U-Boot), автору удалось извлечь прошивку и провести ее анализ. Основной технический результат — создание ARM ROP-цепи, позволяющей обойти ASLR без утечки адресов, что приводит к неаутентифицированному выполнению произвольного кода на устройстве.
Комментарии (8)
- Обсуждение критикует статью за ложное представление "обхода ASLR", так как ASLR фактически отключен из-за отсутствия PIE (Position-Independent Executable), что делает адреса статичными.
- Основной метод, описанный в статье (использование адреса libc в GOT), рассматривается как избыточный, так как для ROP-эксплуатации можно было бы использовать гаджеты из не-ASLR секций.
- Отмечается техническая особенность цепочки ROP: она не требует интерактивности после получения адреса libc, что делает ее менее распространенным подходом по сравнению с базовыми ROP-цепями.
D4D4 🔥 Горячее
Коллега нашёл в ARM-дизассемблере кучу «лишних» инструкций d4d4 (bmi #-0x58), которые никогда не выполняются.
Минимальный пример:
00020100 <one>:
20100: 4770 bx lr
20102: d4d4 bmi …
bx lr возвращает из функции, так что d4d4 недостижима.
Мысль: выравнивание? Thumb-команды 16-битные, но компилятор не выравнивает функции на 32 бита.
Добавляем вторую функцию — d4d4 исчезает.
Третья — d4d4 снова появляется, но только после последней функции.
Смотрим объектный файл: компилятор d4d4 не вставляет. Значит, линковщик lld добивает секцию до 32-битной границы именно этой командой.
Меняем порядок файлов — «лишняя» инструкция перемещается в начало следующего модуля, подтверждая гипотезу.
GNU ld вместо d4d4 ставит нули.
Комментарии (49)
- Коммит 2017 года в OpenBSD закладывал «trapsleds» — заполнение «дырок» в исполняемых секциях инструкциями-ловушками (trap), чтобы сорвать NOP-sled-эксплойты.
- На ARM32/Thumb ожидалось 0xD4 (BRK) или 0xBE (BKPT), но в режиме Thumb та же последовательность байтов декодируется как условный переход назад, превращая «ловушку» в потенциальный ROP-гаджет.
- Это делает защиту нерабочей на Cortex-M (только Thumb), что участники признают ошибкой/«сломанной» митигацией.
- Некоторые считают, что описание механизма в коммит-сообщении достаточно, другие требуют комментариев в коде, чтобы избежать подобных недоразумений.