簡體   English   中英

當進程被“堆棧緩沖區溢出”攻擊時會發生什么?

[英]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;
}

運行環境

  • 架構:i686
  • 操作系統:ubuntu 16.04 32bit
  • 編譯器:gcc
  • 關閉 ASLR(sysctl -w kernel.randomize_va_space=0)
  • 選項:gcc -z execstack -mpreferred-stack-boundary=2 -fno-stack-protector

但是我混淆了保存了哪些堆棧以及重疊了哪些記憶。
以上二進制代碼"\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 不要隨機化進程地址空間布局(或用於覆蓋返回地址的特定固定值不起作用)。

fpra最有可能是 RISC 架構,x86 沒有這樣的寄存器。

main返回(使用ret )時,執行流程被重定向,這就是ret所做的。
在英特爾的手冊中查看call / ret對是如何工作的,然后通過調試器進入一個調用來在實踐中查看它。
確保您了解調用約定並在每次執行時密切關注堆棧。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM