2011-12-17 155 views
8

大家好,將shellcode聲明爲char []數組和char *之間的區別

我想學習基本的shellcoding,我跑過好奇的東西,我希望有人能向我解釋。我用兩種方法編譯了下面的代碼:將shellcode聲明爲數組和char *。當我將shellcode聲明爲一個數組時,linux檢測到我正在嘗試執行數據,並且在第一條指令中出現了段錯誤。但是,當我將shellcode聲明爲char *時,所有的shellcode都會執行,並且我得到一個「Hello world!」。編譯器如何以不同的方式處理這兩個聲明,以及爲什麼一個終結於不受保護的內存中的shellcode?提前致謝。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

/* This declaration ends in a segfault */ 
//char shellcode[] = 

/* This declaration ends in successful execution */ 
char* shellcode = 

/* Shellcode prints "Hello world!" and exits */  
"\xeb\x1f\x48\x31\xc0\x48\x31\xdb\x48\x31\xc9\x48\x31\xd2\xb0\x04\xb3\x01\x59\xb2\x0c\xcd\x80\x48\x31\xc0\xb0\x01\x48\x31\xdb\xcd\x80\xe8\xdc\xff\xff\xff\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x21"; 

int main() 
{ 
    void (*f)(); 
    f = (void (*)())shellcode; 
    (void)(*f)(); 
} 

回答

8

當您將其聲明爲char[]時,內存位於堆棧上。當您將其聲明爲char*併爲其分配字符串文字時,內存位於可執行映像本身中。 Linux不喜歡你在堆棧上執行代碼,但在你執行可執行映像的那一部分執行內存時沒問題。這是因爲它試圖避免某種類型的堆棧溢出攻擊,人們可以使用某些任意指令溢出堆棧然後執行它們。

您可以在Linux上使用mprotect來設置Windows上的內存區域或VirtualProtectEx的權限。這樣你可以明確地設置內存的權限是可執行的。

3

在你第一種情況:

char shellcode[] = 

這使串堆棧作爲本地陣列上的文字。堆棧和堆內存通常沒有執行權限(出於顯而易見的安全原因)。

在你的第二個案例:

char* shellcode = 

串住在靜態存儲器 - 通常在同一區域作爲程序二進制文件的其餘部分 - 這是可執行文件。