forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   C++ (http://forum.boolean.name/forumdisplay.php?f=22)
-   -   Переполнение буфера - модификация стека (http://forum.boolean.name/showthread.php?t=15572)

impersonalis 01.10.2011 00:43

Переполнение буфера - модификация стека
 
Код:

#include<iostream.h>
#include<string.h>
#include<conio.h>

void F1(){
        cout<<"hello"<<endl;
        getch();
}

char mbf[13];

int main(){
        char t[4];
        for(int i=0;i<8;i++)mbf[i]=1;
        ((int*)(&mbf))[2]=int(&F1);
        mbf[12]=0;
        strcpy(t,mbf);
        return 0;
}

Пример эксплуатации уязвимости «переполнение буфера в стеке».
Ну как "эксплуатации уязвимости" - скорее демонстрация того, как переполнение буфера, может поменять стек таким образом, что изменится поведение атакуемой программы. В данном случае программа "нападает" сама на себя (мазохизм), так что я не несу ответственности за какие-либо противоправные действия, которые вы можете совершить под влияниям данной статьи (или после доработки приводимых кодов). Приводимый материал и фрагмент кода призваны были показать студентам (т.е. я - показывал им), как важно контролировать границы записи при работе со строками.
Функция strcpy не контролирует размер переданных в неё данных, в связи с чем, копируемая строка mbf будет записана не только в отведенную область памяти строки t, но и далее, что перезапишет значение адреса возврата, хранящееся в стеке. После завершения (штатного!) функции копирования в регистры EIP и EBP будут вытолкнуты ложные (отличающиеся от сохранённых ранее) данные. Программа будет продолжена по адресу, помещённому в регистр EIP (в данном случае адрес функции F1, которая нигде не вызывается явно).
Кто забыл основы архитектуры:
EIP____Адрес команды, которая будет выполнена процессором
ESP____Указывает на адреса данных, которые будут вынуты из стека
EBP____Указатель на базу (для удобства адресации)

При вызове функции main в стек будет помещено значение адреса возврата. Стек растёт вниз, т.е. самое первое значение, размещённое в стеке, имеет бОльший адрес (конкретные числовые значения нам не важны, но для удобства обозначим логически связанные группы байтов последовательностями, поименованными с префиксом #).
#A
#A
#A
#A
ESP хранит адрес вершины стека (т.е. на 4 байта ниже, т.к. они уже заняты адресом возврата из main). В EBP хранится нечто.
Далее в стек выталкивается значение регистра EBP.
#A
#A
#A
#A
#B
#B
#B
#B
В регистр EBP сохраняется состояние (значение) регистра ESP. Затем в программе объявляется локальный массив размером 4 байта. Массив также записывается в стек. Регистр ESP уменьшается ещё на 4 байта. Регистр EBP по-прежнему хранит состояние регистра ESP на момент «начала» функции.
#A
#A
#A
#A
#B
#B
#B
#B
#M
#M
#M
#M
Теперь, если мы разместим в массиве нуль-терминированную строку «123» (элементы которой адресуются возрастающими индексами), то стек примет вид:
#A
#A
#A
#A
#B
#B
#B
#B
NULL
'3'
'2'
'1'
Дальнейшее присвоение значений элементам строки приведёт к перезаписи последовательности #B (значение регистра EBP на момент начала выполнения функции main), и #A (адрес возврата из функции main, который инструкция RET вытолкнет в регистр EIP).

Программа после копирования строк вызвает функцию F1, выход из которой крешит приложение (ещё бы - стек то расфигачили).

ЗЫЖ SBJoker верно уточняет, что с хр сп2 в винде существует нативная защита от выполнения данных, а современные камни от интел и амд обладают и аппаратной.
Тем не менее, пример в посте работает и под сп3: фактически он выполняет не данные, а инструкции (т.к. в стек записали адрес функции, а не шеллкод) и, сверх того, не посягает на чужую память.

impersonalis 01.10.2011 17:59

Ответ: Переполнение буфера - модификация стека
 
Придумалось что-то:
я в твой стек свой шелкод пихал!

Желающим понять механизм более детально, рекомендую /для начала/ прочитать номера 2 и 3 журнала ][акер от 2003 года (скачать pdf можно легально отсюда: тык). Статья "Переполнение буфера в стеке" (2 части).

ISergey 04.10.2011 00:19

Ответ: Переполнение буфера - модификация стека
 
Луче книгу по ASM почитать..

impersonalis 04.10.2011 00:52

Ответ: Переполнение буфера - модификация стека
 
Угу. Например, самоучитель от Крупник-а А.
Неплохо для начала.

impersonalis 16.07.2013 12:42

Ответ: Переполнение буфера - модификация стека
 
Продолжая тему, порекомендую [1] разделы A.1 и C.1 (приложения). Кроме того, и в основном тексте книги упоминается (и доказывается на практике), что эксплуатировать дыры в безопасности ОС, можно приёмами 20-летней давности. Главная проблема (после говнокода) – политика отсутствия поддержки механизма DEP (защиты от выполнения данных) по умолчанию (режим OptIn). Подключить DEP можно несколькими путями.
Проверять наличие защиты (до кучи ещё и наличие защиты ASLR) автор [1] рекомендует при помощи утилиты Sysinternals Process Explorer или BinScope Binary Analyzer.
Виндовый DEP может быть реализован аппаратно на совместимых процессорах при помощи NX-бита. (Проблема переполнения буфера на стеке существует и для Linux – там так же есть поддержка NX-бита и его программная эмуляция посредством ExecShield и PaX [вот такой наш pax крутой!] для старых камней).
См. ещё (защита от срыва стека):
SecurityCookies
Stack-Smashing Protection (SSP)
Stack Canaries


Часовой пояс GMT +4, время: 21:33.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot