2017-04-06 81 views
0

我有這樣的代碼是從用戶讀取輸入:此C用戶輸入代碼是否易受攻擊?

unsigned int readInput(char * buffer, unsigned int len){ 
    size_t stringlen = 0; 
    char c; 
    while((c = getchar()) != '\n' && c != EOF){ 
     if(stringlen < (len-1)){ 
      buffer[stringlen] = c; 
      stringlen++; 
     } 
    } 
    buffer[stringlen+1] = '\x00'; 
    return stringlen; 
} 

的char * BUFF的大小已經被設置爲len並已memset的含有「0」。此代碼是否容易受到任何漏洞攻擊?

+0

這段代碼運行多久,如果我餵它12 TB的數據?如果我將它掛接到'/ dev/zero',該怎麼辦? –

+0

這只是一個函數,爲什麼cout不是一個C函數,這是C代碼 – bi0phaz3

+0

就像任何輸入,如果你餵它12TB的數據,它將需要很長時間才能運行,但它不會受到攻擊會嗎?這隻會花費很長時間,它會丟失比長度更長的數據 – bi0phaz3

回答

1

根據平臺的不同,unsigned int可能太小而無法容納號碼13194139533312。對於C中的緩衝區大小,您應該始終使用size_t,但不這樣做可能是一個漏洞,是的。

此外,當然getchar()不返回char,所以這也被打破了。

我會說「是」,該代碼是脆弱的。

+0

那麼unsigned int是由我定義的,我有一個60的緩衝區長度。char name [60]; memset的(姓名,0,60); readInput(姓名,60); – bi0phaz3

+0

在代碼中靜態定義,是否仍然易受攻擊? – bi0phaz3

+0

嗯,我想可以肯定的是,60在'unsigned int'的範圍內,但是從函數的原型不清楚,所以這不是我想要回答的。 – unwind

1

您的代碼可能寫出界,葉未初始化數組元素:

char buf[10]; // uninitialized! 

readInput(buf, 10); // feed 12 TB of data 

,因爲你寫buf[10]這不確定的行爲。

readInput(buf, 10); // feed 8 bytes of data 

strlen(buf); 

由於您讀取了未初始化的值buf[8],因此存在未定義的行爲。

錯誤在於您分配空終止符的方式,該終止符使用錯誤的索引。它應該說:

buffer[stringlen] = '\0'; 
//  ^^^^^^^^^ 

因爲你計算len - 1,你的代碼也應該有一個前提條件,即len必須嚴格爲正。這是明智的,因爲你承諾產生一個以空字符結尾的字符串。

+0

如果(stringlen <(len-1))解決這個問題,不要認爲空終止符是一個問題。由於它是 bi0phaz3

+1

@ bi0phaz3:您當前的代碼將在60處終止,因爲之前的'stringlen ++'意味着'有價值59. –

+0

我剛纔看到@KerrekSB和我正在做同樣的說法。我們都是正確的:-P – TheGreatContini

1

假定緩衝區分配len字節,最突出的問題是:

buffer[stringlen+1] = '\x00'; 

這是因爲循環可以stringlen等於len-1退出,因此你寫信給buffer[len]。但是,您只應寫入指數高達len-1

因此,讓我們解決這個問題如下:

buffer[stringlen] = '\x00'; 

這是你真正想要的,因爲你還沒有寫buffer[stringlen]呢。

一個微妙的錯誤是,如果len是0(你可能會認爲這絕不應該發生),那麼len-1是MAXINT,因此(stringlen < (len-1))總是如此。因此,代碼將總是在0長度緩衝區上緩衝溢出。

+0

啊但是stringlen的最終值將是len-2,因爲循環中的len-1 – bi0phaz3

+0

@ bi0phaz3:不,當'stringlen'等於** len時循環退出-1'。 – TheGreatContini

+0

啊,如果我將它運行並保存爲+1,內存會發生什麼? – bi0phaz3

-1

你的問題是代碼是否容易受到攻擊。答案是否定的,它不是脆弱的,當然不是脆弱性的常見定義。

這是一些未知輸入(可能是敵手)和緩衝區之間的接口。你已經正確地包含了防止緩衝區溢出的機制,所以你的代碼是安全的。 [我們在這裏假設從getchar()開始的一切都不是你的問題的主題]。

代碼是否按預期工作是一個不同的故事,(其他人已經指出NULL在終止之前),但這不是你的問題。

+0

請注意,雖然此函數本身不易受到攻擊,但如果使用不當,系統可能會變得易受攻擊(例如,傳遞的長度大於緩衝區)。 – kozel

+0

對於downvoter等人來說:易受攻擊性與攻擊的敏感性並不等同於正確性,OP詢問了前者,但大多數回覆都是針對後者的,而特殊製作的輸入是否允許攻擊者接管機器爲什麼fgets使用int(而不是像snprintf那樣的size_t)?因爲它並不重要;即使它的de罰款len作爲無符號字符。代碼「char buf [16]; fgets(buf,256,stdin);」使fgets成爲一個易受攻擊的界面? – kozel

相關問題