2017-04-07 36 views
3

我已經研究了這個問題,我可以找到最接近的答案是這樣的。 gdb - debugging with piped input (not arguments)發送管道輸入GDB在斷點,而不是最初

我需要做這個人究竟要求什麼,但是,我需要能夠發送輸入後,已經看過我的程序運行的一部分。

這就是我要找的代碼在GDB

#define SECRET1 0x44 
#define SECRET2 0x55 

int main(int argc, char *argv[]) 
{ 
char user_input[100]; 

int *secret; 
int int_input; 
int a, b, c, d; /* other variables, not used here.*/ 

/* The secret value is stored on the heap */ 
secret = (int *) malloc(2*sizeof(int)); 

/* getting the secret */ 
secret[0] = SECRET1; secret[1] = SECRET2; 

printf("The variable secret’s address is 0x%8x (on stack)\n", &secret); 
printf("The variable secret’s value is 0x%8x (on heap)\n", secret); 
printf("secret[0]’s address is 0x%8x (on heap)\n", &secret[0]); 
printf("secret[1]’s address is 0x%8x (on heap)\n", &secret[1]); 

printf("Please enter a decimal integer\n"); 
scanf("%d", &int_input); /* getting an input from user */ 

printf("Please enter a string\n"); 
scanf("%s", user_input); /* getting a string from user */ 

/* Vulnerable place */ 
printf(user_input); 
printf("\n"); 

/* Verify whether your attack is successful */ 
printf("The original secrets: 0x%x -- 0x%x\n", SECRET1, SECRET2); 
printf("The new secrets:  0x%x -- 0x%x\n", secret[0], secret[1]); 

return 0; 
} 

我試圖執行我的虛擬機上的格式化字符串攻擊。爲此,我需要知道祕密存儲的地址。該程序告訴我這通過輸出與這些線

printf("The variable secret’s address is 0x%8x (on stack)\n", &secret); 
    printf("The variable secret’s value is 0x%8x (on heap)\n", secret); 
    printf("secret[0]’s address is 0x%8x (on heap)\n", &secret[0]); 
    printf("secret[1]’s address is 0x%8x (on heap)\n", &secret[1]); 

攻擊的性質要求我送非ASCII十六進制值與第2個scanf的輸入,所以我不能簡單地鍵入輸入自己。我已經完成了在這裏用perl設置我的輸入,

[email protected]:/tmp$ perl -e 'print "5\x0a"; print "\x08\xb0\x04\x08%x.%x.%x.%x.%x.%x.%x";' > /tmp/input 

我然後運行

$gdb ./vul_prog < /tmp/input 

我已經得到我的方法在內存隨機化是關閉的,因爲我可以運行的環境下工作編程一次,查看內存地址,然後更改perl腳本,然後再次運行它。但是,隨着內存隨機化,我無法知道地址將在我運行之前的位置,所以我需要能夠在創建和發送我的輸入之前看到程序的一部分,它告訴我地址​​已經運行。

我試圖這樣做,看起來最直觀的方式,但我只是得到一個語法錯誤。

Starting program: /home/ramtest/Downloads/vulprog 
The variable secret’s address is 0xbfffefd8 (on stack) 
The variable secret’s value is 0x 804b008 (on heap) 
secret[0]’s address is 0x 804b008 (on heap) 
secret[1]’s address is 0x 804b00c (on heap) 
Please enter a decimal integer 
1 
Please enter a string 

Breakpoint 2, 0x0804858f in main() 
(gdb) c > /tmp/input 
A syntax error in expression, near `> /tmp/input'. 
(gdb) c < /tmp/input 
A syntax error in expression, near `< /tmp/input'. 

是否有可能對我來說,設置GDB斷點我提示我輸入正確的前,然後輸入莫名其妙發送到/ tmp /輸入信息?

如果是這樣,我該怎麼辦?

任何幫助,將不勝感激。

回答

1

只需使用run命令。我會通過將/bin/cat廣發行,並在其main()打破演示,標準輸入重定向:

例子:

$ gdb /bin/cat 
GNU gdb (GDB) Fedora 7.12.1-47.fc25 
[ ... ] 
(gdb) b main 
Breakpoint 1 at 0x1bc0 
(gdb) run </etc/issue 
Starting program: /usr/bin/cat </etc/issue 

Breakpoint 1, 0x0000555555555bc0 in main() 
(gdb) c 
Continuing. 
\S 
Kernel \r on an \m (\l) 

[Inferior 1 (process 18190) exited normally] 
(gdb) 

你應該能夠gdb下啓動程序,之前設置一個斷點scanf,然後run它與標準輸入從一個空文件重定向。我不希望你的程序試圖在標準輸入之前讀取其標準輸入,所以它不會在其重定向標準輸入中看到文件結束條件。

當斷點打你,你應該有你的內存地址,然後準備好您的有效載荷,並簡單地將其附加到零長度文件,然後

c 

執行,那麼應該繼續並嘗試閱讀現在可在其標準輸入上使用有效載荷。

這種技術甚至不需要調試器的一種變體就是使用一個命名管道,該管道事先打開,然後用從命名管道重定向的標準輸入來運行該程序。預期的結果是程序打印內存地址,然後阻塞從管道讀取數據的時間。此時,您可以準備好您的有效載荷,並將其寫入管道。

+0

謝謝,我會測試一下 – vergilEther

+0

工作就像一個魅力。謝謝! – vergilEther