Новости МирТесен

voinkiber@bk.ru


Эксплуатация повреждения стека, пример 2013 года

Поделиться:

Эксплуатация повреждения стека, пример 2013 года

Главная цель данной статьи — показать пример успешной эксплуатации переполнения стека в защищенном приложении, выполняющемся в современной Linux-системе

image

Автор: Benjamin Randazzo

Каждый год появляются новые механизмы безопасности, поэтому эксплуатировать уязвимости к переполнению стека становится все сложнее. Техника повреждения стека впервые была описана Элиасом Леви, также известным как Aleph One, в его статье «Smashing the Stack for Fun and Profit», опубликованной в журнале Phrack magazine [1], и за эти годы она претерпела немало изменений. В наши дни обнаружение подобной уязвимости уже не гарантирует возможности успешной ее эксплуатации. Главная цель данной статьи — показать пример успешной эксплуатации переполнения стека в защищенном приложении, выполняющемся в современной Linux-системе.

Я предполагаю, что вы уже знакомы с такими техниками эксплуатации переполнения буфера, как ROP или ret2plt. В противном случае, советую прочесть несколько Интернет-статей на эту тему. Мой интерес привлекла статья «Scraps of notes on remote stack overflow exploitation» [2], опубликованная в 2010 году. Автор статьи, Адам Зеброки (aka pi3) приводил пример эксплоита для написанного им же уязвимого сервера. Я собираюсь использовать некоторые методы, описанные в его статье: они действительно хорошо объяснены. Его уязвимое приложение вызывает функцию system() из libc. Данная функция вызвает командную строку и запускает в ней команду, переданную в качестве аргумента. Вот прототип функции system:

int system(const char *command); [3]

Ее использование в статье Адама не представляет большого интереса: функция лишь печатает «start» в стандартный поток вывода. В целях демонстрации он создал идеальные условия для эксплуатации уязвимости. После нахождения стековой канарейки и сохраненного значения EIP ему «оставалось только» выполнить атаку типа return-into-call-system с аргументом, который являлся контролируемым буфером, ранее помещенным в стек. Однако, как он заметил, это не играет большой роли… поскольку теперь мы собираемся эксплуатировать уязвимость сервера, не вызывая system()!

Уязвимое приложение

Для демонстрации мы исследуем и эксплуатируем самодельный уязвимый сервер, полный исходный код которого можно найти здесь. Он ожидает соединений на порту 3333 и спрашивает у клиента код для получения доступа к «Банку Франции». Я скомпилировал его следующей командой: gcc -m32 -Wl,-z,relro,-z,now -pie -fstack-protector-all -o server server.c

Я использовал опцию -m32, потому что я запущу этот сервер на 64-битной машине под управлением Debian (с версией ядра 3.7), а демонстрацию хочу провести на 32-битной архитектуре. Далее я рассмотрю причины такого выбора. Давайте проверим, насколько защищены система и наш сервер:

$ cat /proc/sys/kernel/randomize_va_space
2

ASLR включена в системе по умолчанию, а переменная randomize_va_space имеет значение 2. Так что, в данном случае мы имеем полную рандомизацию адресного пространства (стека, кучи, разделяемых библиотек и т. д.). Мы также можем проверить защищенность приложения, используя скрипт checksec.sh [4] :

$ wget -q trapkit.de/tools/checksec.sh
$ chmod +x checksec.sh
$ ./checksec.sh

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Новости МирТесен