Разбор месяца про ret2libc и ASLR
В этой статье мы разберем пример эксплуатации переполнения буфера на стеке посредством составления ROP-цепочки. Данная задача была опубликована в сообществе SPbCTF — в рамках разбора, посвященного атакам типа ret2libc и методам обхода ASLR.
Вначале отключим рандомизацию адресного пространства в текущей операционной системе:
Загрузим исполняемый файл в IDA Pro и изучим листинг функции main
:
Таким образом, исходный код программы содержит ряд уязвимостей:
- функция форматированного вывода
printf
используется без спецификаторов формата, то есть имеется уязвимость форматной строки; - для считывания данных из стандартного ввода применяется функция
gets
, которая не позволяет установить ограничение на размер считываемой строки, то есть имеется уязвимость переполнения буфера на стеке.
Отобразим кадр стека функции main
в IDA Pro:
Теперь запустим исполняемый файл и прочитаем значение из стека с помощью функции printf
:
Для проведения атаки ret2libc необходимо получить адрес какой-либо функции из библиотеки libc:
Откроем ассемблерный листинг функции main
в отладчике gdb:
Запустим программу в отладчике для нахождения требуемого адреса:
В качестве седьмого параметра на стеке используется адрес, указывающий на инструкцию xor r8d, r8d
функции __GI__IO_setvbuf
:
Загрузим файл динамической библиотеки в IDA Pro и убедимся в корректности этого адреса памяти:
Создадим первую версию эксплойта и вычислим базовый адрес libc через уязвимость форматной строки:
Таким образом, полезная нагрузка имеет следующую структуру:
128
байтов «мусора» (заполнение буфераformat
)8
байтов «мусора» (перезапись значения регистраrbp
)- адрес инструкции
ret
(выравнивание стека) - адрес гаджета
pop rdi; ret
(вызов функцииsystem
в cdecl) - адрес строки
/bin/sh
(передача аргумента в функциюsystem
) - адрес функции
system
(запуск оболочки)
С помощью консольных утилит получим адреса гаджетов и строки /bin/sh
:
Имеем аналогичный результат при использовании IDA Pro:
Затем найдем адрес функции system
в файле динамической библиотеки:
Итак, соберем вместе все этапы эксплуатации уязвимости:
Запустим эксплойт и получим shell на удаленной машине:
Полный код эксплойта доступен на GitHub