2012-09-20 58 views
0
#include <stdlib.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <string.h> 

#define MAX 3 
#define ARG "cat .passwd" 
integer main(integer argc, char ** argv) 
{ 
char * names[] = {"strlen", "atoi", "printf", "puts"}; 
void (*reachable_functions[])(char *) = {strlen, atoi, printf, puts}; 
void (*unreachable_functions[])(char *) = {system}; 
integer i, index = 0; 

for(i=1; i<argc; i++) 
{ 
    index += strlen(argv[i]); 
} 

if(index <= MAX) 
{ 
    (reachable_functions[MAX-1])("Calling "); 
    (reachable_functions[MAX-1])(names[index]); 
    (reachable_functions[MAX-1])(".\n"); 
    (reachable_functions[index])(ARG); 
} 
else 
{ 
    (reachable_functions[MAX])("Out of bounds !\n"); 
} 

return 0; 
} 

我可以得到一個分段錯誤,但不可能調用無法訪問的函數!?! 我知道有整數的問題,但我不能利用它.... :( 有沒有辦法調用它?Thx這個C代碼有什麼弱點? (整數...)

+0

您是否嘗試用'gcc -Wall -g'(改進它直到沒有警告)編譯您的程序並使用'gdb'和'valgrind'調試它? –

+1

如果你使用'typedef int integer',我不記得在C. –

+0

中有一個類型'整數',它可能會更好;) – Nippey

回答

3

如果您傳遞足夠長度的足夠的參數,總和長度可以溢出(不知道殼能否其實處理這些參數如果整型是32位,而應爲16位整數的工作)。

溢出符號的整數(我想integer應該int)是未定義的行爲,所以在這種情況下會發生什麼取決於編譯器和平臺(可能還有月亮的相位),但是總和可能會轉換爲負數,在這種情況下,根據編譯器如何排列數組,呼叫

(reachable_functions[index])(ARG); 

實際上可能會調用「無法訪問」功能。這是更多未定義的行爲,索引負數索引的數組,但這是一個可能的漏洞。

爲了防止利用(儘可能的未定義的行爲允許),人們可以投index要在比較無符號類型,

if((unsigned int)index <= MAX) 
在所有合理的實施方案中,其中的 unsigned int寬度等於該的

int,這保證index確實是非負的(同樣,在發生未定義行爲後,標準不再保證程序行爲),因爲負數轉換爲大於INT_MAX的數字。

如果一個人是偏執的人,也可以投入索引操作。