2015_лекции / Переполнение буфера
.pdfПереполнение стека
void main(int argc, char* argv[]){
char buffer[4]; |
// вот он наш буфер |
strcpy(buffer, argv[1]); // ага, а вот тут мы просто что
//то копируем в буфер!
}
1)Скомпилируем и соберем программу gcc –w test.c –o test
2)Вызовем программу test aaaaaaaabbbb Segmentation fault.
Изменение состояния стека
а) нормальное состояние |
|
б) переполнение буфера |
||||||
|
|
|
|
|
|
|
|
|
|
|
<адрес |
|
bbbb |
||||
|
|
возврата> EIP |
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
cтарый EBP |
|
|
|
aaaa |
|
|
|
|
|
|
|
|
|
|
|
buffer |
aaaa |
Виды переполнения буфера (исходя из цели
атаки)
на запись
на чтение
Переполнение буфера при записи seq_write(char *p)
{
char buff[8];
…
strcpy(buff, p);
}
Переполнение буфера при чтении idx_write(int i)
{
char buff[]="0123456789";
…
return buff[i];
}
Цель «затирания»
Указатели
Cкалярные переменные
Буфера
Пример затирания скалярной переменной: var_demo(float *money_account)
{
char buff[MAX_BUF_SIZE];
float buks = CURRENT_BUKS_RATE; printf("input money:"); gets(buff);
if (atof(buff)<0) ошибка! введите положительное значение
…
*money_account -= (atof(buff) * buks );
}
Переполнение буфера: ошибки 2-го поколения
Переполнение на 1 байт void vuln (char *foobar){
char buffer[512];
for (int i = 0; i <= 512 ; i++) buffer[i] = foobar[i];
}
void main (it argc, char* argv[]){ if (argc== 2) vuln(argv[1]);
}
Переполнение буфера: ошибки 2-го поколения Переполнение кучи
#include <stdio.h> #include <stdlib.h> #include <string.h>
void main(int argc, char **argv){ int i=0,ch;
FILE *f;
static char buffer[16], *szFilename; szFilename = "C:\\harmless.txt"; ch = getchar();
while (ch != EOF) { buffer[i] = ch; ch = getchar(); i++; }
f = fopen(szFilename, "w+b"); fputs(buffer, f);
fclose(f); }
Стек при нормальном выполнении программы
адрес |
Переменная |
Значение |
|
|
|
0x00300ECB |
argv1 |
|
|
|
|
… |
… |
… |
|
|
|
0x00407034 |
*szFilename |
C:\\harmless.txt |
|
|
|
0x00407680 |
buffer |
|
|
|
|
0x00407690 |
szFilename |
0x00407034 |
|
|
|
Стек при искусственно созданных условиях: argv1 = «С:\\autoexec.bat»
buffer = “XXXXXXXXXXXXXXXХ00300ECB”
адрес |
Переменная |
Значение |
|
|
|
0x00300ECB |
argv1 |
С:\\autoexec.bat |
|
|
|
… |
… |
… |
0x00407034 |
*szFilename |
C:\\harmless.txt |
0x00407680 |
buffer |
XXXXXXXXXXXXXXXХ |
0x00407690 |
szFilename |
0x00300ECB |
Переполнения буфера – изменение указателей на функции
static char buffer[32] = \";
int main(int argc, char **argv){ strcpy(buf, argv[1]); printf(buf);
return 0;}
Расположение секций ELF файла
Idx |
Name |
Size |
|
|
|
13 |
rodata |
… |
14 |
data |
00000040 |
|
|
|
17 |
dtors |
00000008 |
|
|
|
18 |
got |
00000024 |
|
|
|
21 |
bss |
00000018 |
|
|
|
Схематичное представление виртуальных функций объекта
Схема уязвимости указателя виртуальной функции