2014-01-16 229 views
2

安全漏洞,通過使緩衝區溢出,我們可以覆蓋其中標誌值0被保存,所以甚至不正確的密碼會破解密碼的記憶..關於strcpy的

這將如何在內部發生的呢?有人可以請詳細解釋..實際上這將如何發生在記憶中?

#include<stdio.h> 

int main(int argc, char *argv[]) 
{ 
int flag = 0; 
char passwd[10]; 

memset(passwd,0,sizeof(passwd)); 

strcpy(passwd, argv[1]); 

if(0 == strcmp("LinuxGeek", passwd)) 
{ 
    flag = 1; 
} 

if(flag) 
{ 
    printf("\n Password cracked \n"); 
} 
else 
{ 
    printf("\n Incorrect passwd \n"); 

} 
return 0; 

}

+0

不那麼相關:在strcpy()之前,您不需要將memset設置爲零。 – moeCake

回答

6

請記住,從理論上來看,如果存儲在passwd串溢出,它調用未定義的行爲,結果是不可預知的。實際上,在許多將局部變量存儲在堆棧中的現代平臺上,如果編譯器將flag放置得高於passwd緩衝區,則它可能會被strcpy調用溢出。

I.e.你的籌碼看起來是這樣的:

| ...  | 
+------------+ 
| flag  |/\ 
+------------+ | 
| passwd[10] | | increasing addresses 
| ...  | 

如果你寫了超過10個字節passwdstrcpy只是寫了flag

請注意,行爲因編譯器,編譯器,平臺而異。這個解釋涵蓋了普通系統上發生的事情,但是知道理論上可以有一個不使用堆棧的平臺,所以這個解釋不適用。

+0

所以,答案是..它可能會也可能不會......也因此在編譯器依賴的局部變量的存儲..我認爲他們存儲爲聲明.. –

+0

是的,它是由編譯器來選擇它們放置在哪裏。 – tangrs

3

C中的局部變量通常分配在堆棧上。堆棧往往在內存中向下增長,因此'flag'的存儲將在分配給'passwd'的存儲之後立即存儲。

strcpy不檢查正在複製的數據量是否會溢出到正在複製數據的緩衝區。所以,想象的argv [1]是11個字符究竟,這是會發生什麼:

  • 前10個字符將進入passwd文件
  • 焦炭11將進入存儲的第一個字節爲標誌
  • 終止空字符將進入標記的第二個存儲字節

因此,標誌將不爲零。

確切的行爲會因編譯器而異 - 但這是一種典型的情況。

使用strncpy來避免這種情況。