2014-09-29 35 views
1

我正在研究緩衝區溢出,並且我試圖跳到函數'confused',然後通過執行緩衝區在main的最後打印出「done」溢出。如何「乾淨地」在緩衝區溢出攻擊後終止程序

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

int i, n; 
void confused(int i) { 
    printf("**Who called me? Why am I here?? *** %x\n ", i); 
    ; 
} 

void shell_call(char *c) { 
    printf(" ***Now calling \"%s\" shell command *** \n", c); 
    system(c); 
} 

void victim_func(){ 
    int a[4]; 
    printf("\nEnter n: "); scanf("%d",&n); 
    printf("~~~~~~~~~~~~~ values and address of n locations ~~~~~~~~~~"); 
    for (i = 0;i <n ;i++) 
    printf ("\n a[%d] = %x, address = %x", i, a[i], &a[i]); 
    printf("\nEnter %d HEX Values \n", n); 

    // Buffer Overflow vulnerability HERE! 

    for (i=0;i<n;i++) scanf("%x",&a[i]); 
    printf("Done reading junk numbers\n") 
} 

int main() { 
    printf("\n ~~~~~~~~~~~~~~~~~ Info Menu ~~~~~~~~~~~~"); 
    printf("\n addrss of main %x", main); 
    printf("\n addrss of shell_cal %x", shell_call); 
    printf("\n addrss of confused %x", confused); 
    victim_func(); 
    printf("\n done"); 
    return 0; 
} 

我所做的是我把7 N,以及第六十六進制值我在主插入的printf的困惑和第七地址的地址。它在混淆函數後成功地打印出「完成」,但程序返回到main的開頭。我認爲程序在打印出「完成」後會終止。

我只是想知道我做錯了什麼,或者它應該這樣做。

+0

您應該研究生成的彙編代碼,也許可以使用獨立的彙編程序來獲取包含程序集和機器代碼的完整*清單*。 – 2014-09-29 06:08:51

+0

當你的代碼寫入任何一個x大於3的[x]時,你的代碼會對堆棧進行破壞。函數返回地址存儲在堆棧中。你的代碼加入了存儲在堆棧上的返回地址(和其他東西)。 – user3629249 2014-09-30 15:54:33

+0

你是什麼意思的堆棧是'毆打'?這是否意味着代碼覆蓋了包含返回地址的堆棧,因此無法完全返回? – ShiShKebab 2014-09-30 18:21:33

回答

0

您可以隨時在shell代碼中調用exit()來終止程序。但是,你不能用system()來做,因爲system()會創建一個子進程,最終返回給父進程。您需要使用程序集直接調用exit()。

+0

感謝您的回答。但是你能詳細說明一下嗎?當代碼中沒有exit()地址時,如何直接調用exit()? – ShiShKebab 2014-09-29 16:02:50

+0

您可以像爲shell_call()一樣打印exit()的地址。 – 2014-09-29 16:04:39

+0

大多數子功能都沒有被調用,只有他們的地址正在被使用。問題是堆棧被被調用的子函數(victom_func)中的代碼破壞了。 – user3629249 2014-09-30 15:57:12