C語言的strcpy()函數與堆棧溢出


 

最近在一個帖子中看到一道題:


問:下面是一個簡單的密碼保護功能,你能在不知道密碼的情況下將其破解嗎?

#include<stdio.h> 
#include<string.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("apple", passwd)) { flag = 1; } if(flag) printf("\n Password cracked \n"); else printf("\n Incorrect passwd \n"); return 0; }

我個人感覺這道題對於我這種C語言半瓶子水的人來說還是挺有意思的,(╯▔皿▔)╯

 

其實答案也不難,就是利用了strcpy()函數的漏洞:

簡單來說就是用戶在向passwd數組傳值時沒有考慮會溢出的情況。如果用戶輸入的passwd足夠長,導致不僅溢出了passwd的空間而且還“侵犯”了flag變量的空間,造成flag的值不為0。最終也就導致了判斷的失效:passwd不匹配,但是flag不為0。

 

 

在程序設計中如何避免出現此情況
——

可能有同學發現,在運行上面的程序時,如果輸入的長度過長有可能會終止並報錯。

這其實是有的IDE在編譯時已經為你加入了一種檢測堆棧溢出的機制——stack protector機制。

<GCC中的堆棧保護技術>

 

gcc(4.9)中提供了關於stack protector機制的多個編譯選項:

-fstack-protector
  啟用堆棧保護,不過只為局部變量中含有 char 數組的函數插入保護代碼。

-fstack-protector-all
  啟用堆棧保護,為所有函數插入保護代碼。

stack-protector-strong
  在stack-protector基礎上,增加本地數組、指向本地幀棧地址空間保護。
stack
-protector-explicit   在stack-protector基礎上,增加程序中顯式屬性"stack_protect"空間。 -fno-stack-protector   禁用堆棧保護。

 

所以如果你的編譯器默認加入了此保護機制,你需要在gcc編譯時加入-fno-stack-protector,才能看到破解密碼的效果(●'◡'●)

進而可以很明顯的得到,要避免此種情況:

1 可以使用-fstack-protector或其它適合你的保護選項來避免堆棧的溢出。

2 從代碼編寫方面來看,可以更多的使用strncpy()結合strlen()的判斷。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM