Разбор месяца про ret2libc и ASLR

В этой статье мы разберем пример эксплуатации переполнения буфера на стеке посредством составления ROP-цепочки. Данная задача была опубликована в сообществе SPbCTF — в рамках разбора, посвященного атакам типа ret2libc и методам обхода ASLR.

_config.yml

Вначале отключим рандомизацию адресного пространства в текущей операционной системе:

_config.yml

Загрузим исполняемый файл в IDA Pro и изучим листинг функции main:

_config.yml

Таким образом, исходный код программы содержит ряд уязвимостей:

  • функция форматированного вывода printf используется без спецификаторов формата, то есть имеется уязвимость форматной строки;
  • для считывания данных из стандартного ввода применяется функция gets, которая не позволяет установить ограничение на размер считываемой строки, то есть имеется уязвимость переполнения буфера на стеке.

Отобразим кадр стека функции main в IDA Pro:

_config.yml

Теперь запустим исполняемый файл и прочитаем значение из стека с помощью функции printf:

_config.yml

Для проведения атаки ret2libc необходимо получить адрес какой-либо функции из библиотеки libc:

_config.yml

Откроем ассемблерный листинг функции main в отладчике gdb:

_config.yml

Запустим программу в отладчике для нахождения требуемого адреса:

_config.yml

В качестве седьмого параметра на стеке используется адрес, указывающий на инструкцию xor r8d, r8d функции __GI__IO_setvbuf:

_config.yml

Загрузим файл динамической библиотеки в IDA Pro и убедимся в корректности этого адреса памяти:

_config.yml

Создадим первую версию эксплойта и вычислим базовый адрес libc через уязвимость форматной строки:

_config.yml

_config.yml

Таким образом, полезная нагрузка имеет следующую структуру:

  • 128 байтов «‎мусора» (заполнение буфера format)
  • 8 байтов «‎мусора» (перезапись значения регистра rbp)
  • адрес инструкции ret (выравнивание стека)
  • адрес гаджета pop rdi; ret (вызов функции system в cdecl)
  • адрес строки /bin/sh (передача аргумента в функцию system)
  • адрес функции system (запуск оболочки)

С помощью консольных утилит получим адреса гаджетов и строки /bin/sh:

_config.yml

Имеем аналогичный результат при использовании IDA Pro:

_config.yml

_config.yml

_config.yml

Затем найдем адрес функции system в файле динамической библиотеки:

_config.yml

Итак, соберем вместе все этапы эксплуатации уязвимости:

_config.yml

Запустим эксплойт и получим shell на удаленной машине:

_config.yml

Полный код эксплойта доступен на GitHub

Written on March 4, 2022