2010-03-08 32 views
4

我正在學習計算機安全課,並且還有一項額外的功勞分配,用於將可執行代碼插入緩衝區溢出。我有我想要操作的目標程序的c源代碼,並且我已經到了可以成功覆蓋當前函數堆棧幀的eip的地步。但是,我總是遇到分段錯誤,因爲我提供的地址總是錯誤的。問題是當前函數在pthread中,因此堆棧的地址似乎總是在程序的不同運行之間改變。是否有任何方法可以在pthread中查找堆棧地址(或者用於估計pthread中的堆棧地址)? (注意:pthread_create的第二個參數爲空,因此我們不是手動分配堆棧地址)對於緩衝區溢出,使用pthread時,堆棧地址是什麼?

回答

0

不知道更多關於應用程序的信息,有點難以理解,但首先想到的是heap spraying

7

我建議閱讀有關利用緩衝區溢出漏洞的優秀(如果有點過時的)文章/教程Smashing The Stack For Fun And Profit

這裏是一個簡要摘錄:

的問題是,我們不知道在 程序,我們正在試圖利用代碼的存儲空間(與下面的字符串 吧)會放置。其中一種方法是使用JMP和CALL 指令。 JMP和CALL指令可以使用IP相對尋址,即 ,這意味着我們可以跳到當前IP的偏移量,而不需要 知道我們要跳轉到的內存中的確切地址。


您可以檢索堆棧指針的一個位內聯彙編的當前值。 Smashing The Stack For Fun And Profit中的所有示例溢出main中的一個緩衝區,但您可以輕鬆地使用相同的技術來從pthread調用的函數中溢出緩衝區。下面的代碼基於文章(overflow1.c)中的一個示例進行構建,以表明使用pthread可以使用相同的技術。您將使用的實際技術取決於您嘗試利用的目標程序。


/* get value of sp off the stack - not essential to example */ 
unsigned long get_sp() 
{ 
    __asm__("movl %esp,%eax"); /* equiv. of 'return esp;' in C */ 
} 

int foo() 
{ 
    char buffer[96]; 

    /* overflow buffer to overwrite return address */ 
    /* and place code to be executed into buffer. */ 
    ... 

    return 0; 
} 

void *thread(void *arg) 
{ 
    printf("thread stack 0x%x\n", get_sp()); 

    foo(); 

    return NULL; 
} 

int main(int argc, char **argv) 
{ 
    printf("main stack 0x%x\n", get_sp()); 

    pthread_t t; 
    pthread_create(&t, NULL, thread, NULL); 
    pthread_join(t, NULL); 

    return 0; 
} 
+0

我其實讀那篇文章。我將不得不再次研究它,但是不是引用了在緩衝區內獲取「/ bin/sh」地址的引用嗎?我們還不得不重寫這個eip,以便它指向最初的跳轉指令嗎? – t2k32316 2010-03-08 23:02:29

+0

這個例子中,片段使用'strcpy()'建立起來以溢出一個字符緩衝區。溢出將覆蓋堆棧上的返回地址(保存的IP),以便它指向緩衝區內的JMP指令。 JMP指令跳轉到調用'/ bin/sh'的'execve()'的CALL指令,該指令全部被複制到緩衝區中作爲shellcode。後面的文章建議用NOP指令填充溢出緩衝區的前端,這樣返回地址只需要指向NOP中的某處。 – jschmier 2010-03-09 15:37:17

+0

謝謝你,jschmier,感謝你的迴應。我的TA提到,通過使用pthreads,程序可以有效地執行堆棧隨機化,作爲緩衝區溢出的預防技術。 JMP和CALL指令的方法只有在返回地址更改爲指向緩衝區中的代碼後纔可用。但是,由於程序使用pthreads,我不知道用什麼內存地址來覆蓋返回地址。 – t2k32316 2010-03-10 18:46:30