2012-10-23 47 views
7

現代編譯器GCC功能非常強大,甚至可以防止編譯階段的緩衝區溢出,從而OS無法在堆棧空間上運行代碼。緩衝區溢出編譯器的藝術

例如:

void function(char *str) 
{ 
    char buffer[16]; 

    strncpy(buffer, str, 256); 
} 

void main() 
{ 
    char large_string[256]; 
    int i; 

    for(i = 0; i < 256; i++) 
    large_string[i] = 'A'; 

    function(large_string); 
} 

我可以得到神奇的0x41414141的唯一方法就是設置GCC編譯參數等類

gcc -fno-stack-protector -z execstack stackoverflow.c -o stackoverflow 

(我測試了它在Ubuntu 10.04 86透徹32位盒)

有什麼辦法可以繞過海灣合作委員會堆棧粉碎保護?

+0

你指的是哪個限制,爲什麼你想繞過它? –

+0

你想故意破壞堆棧嗎?爲什麼?而你的代碼有一個bug,順便說一句。你忘了NULL結束'large_string'。 'strcpy()'不會僅限於255個字節。 –

+0

我認爲你的意思是詢問是否可以繞過海灣合作委員會的堆棧保護,如果是的話,你應該編輯這個問題來說明問題。 – iabdalkader

回答

6

編譯時,你應該禁用堆棧保護:

gcc -fno-stack-protector -z execstack stackoverflow.c -o stackoverflow 

而且你可能也想禁用地址空間隨機化(ASLR):

sudo sh -c 'echo 0 > /proc/sys/kernel/randomize_va_space' 

現在你可以嘗試緩衝區溢出,我推薦閱讀Smashing the Stack for Fun and Profit

編輯:

就像我在我的評論說,這是安全的假設,它在你的作業接受禁用堆棧保護,但是,如果你想旁路你應該檢查SOF的相關金絲雀喜歡討論的堆棧保護這個問題:

Is there any way to bypass SSP (StackSmashing Protection)/Propolice?

+0

有沒有一種方法可以在沒有任何參數設置的情況下直接粉碎堆棧? – JustForTest

+0

您的任務要求利用緩衝區溢出我認爲可以放心地禁用堆棧保護是可以接受的,否則問題就更加複雜了。 – iabdalkader

+0

是的,我認爲是。只是很好奇,是否有辦法繞過這種強大的堆棧保護。另一方面,即使存在堆棧溢出漏洞,對於代碼來說這是安全的,因爲堆棧中的代碼不能在堆棧保護編譯之後運行(這種問題的最壞情況是程序終止,黑客無法通過它運行shellcode) – JustForTest

1

當然有辦法規避堆棧溢出保護(稱爲棧金絲雀),雖然它並不容易在你的例子。看到我的回答here有關堆棧金絲雀的一些弱點。

+0

你可以給這樣的堆棧金絲雀一個簡單的可行的例子 – JustForTest

+0

@JustForTest:恐怕不是。在你的例子中繞過堆棧的唯一方法是用相同的值覆蓋它。由於沒有內存泄漏漏洞,唯一的辦法就是暴力破解,這可能是不可行的...... – Job