筆記 | 計(jì)算機(jī)系統(tǒng)基礎(chǔ):09-不得不防的緩沖區(qū)溢出攻擊唧席!

零. 課程要點(diǎn):
  • 緩沖區(qū)溢出
  • 緩沖區(qū)溢出攻擊
  • 緩沖區(qū)溢出防范

學(xué)完了數(shù)據(jù)的內(nèi)存結(jié)構(gòu),以及函數(shù)調(diào)用的底層過程,我們就來看一下在各種操作系統(tǒng)和應(yīng)用軟件中廣泛存在的漏洞:緩沖區(qū)溢出展鸡。

一. 緩沖區(qū)溢出

首先,緩沖區(qū)是什么埃难?

緩沖區(qū)是一塊連續(xù)的計(jì)算機(jī)內(nèi)存區(qū)域莹弊,可以是堆棧(自動變量)、堆(動態(tài)內(nèi)存)和靜態(tài)數(shù)據(jù)區(qū)(全局或靜態(tài))涡尘。在C語言中忍弛,通常使用字符數(shù)組和內(nèi)存分配函數(shù)實(shí)現(xiàn)緩沖區(qū)。如下圖所示:

可執(zhí)行文件的存儲器映像

那么什么是緩沖區(qū)溢出考抄?

緩沖區(qū)溢出就是指當(dāng)計(jì)算機(jī)程序向緩沖區(qū)內(nèi)填充的數(shù)據(jù)位數(shù)超過了緩沖區(qū)本身的容量细疚,溢出的數(shù)據(jù)覆蓋在其它的數(shù)據(jù)或受保護(hù)空間中。

由于C語言沒有數(shù)組越界檢查機(jī)制川梅,當(dāng)向局部數(shù)組緩沖區(qū)里寫入的數(shù)據(jù)超過為其分配的大小時(shí)疯兼,就會發(fā)生緩沖區(qū)溢出。舉個(gè)例子:

double fun(int i)
{
    volatile double d[1] = {3.14};
    volatile long int a[2];
    a[i] = 1073741824;
    return d[0];
}

當(dāng)調(diào)用這個(gè)函數(shù)時(shí)贫途,我們發(fā)現(xiàn)結(jié)果如下:

fun(0) = 3.14
fun(1) = 3.14
fun(2) = 3.1399998664856
fun(3) = 2.00000061035156
fun(4):Segmentation fault

上面就是一個(gè)典型的對數(shù)組的越界訪問吧彪,為什么會出現(xiàn)上面的結(jié)果?只需要看一下棧中的數(shù)據(jù)內(nèi)容就能明白:

棧中的數(shù)據(jù)

當(dāng)i=0i=1時(shí)丢早,1073741824存儲于正確的位置姨裸,但是當(dāng)i=2時(shí),a[2] = 1073741824,雖然我們認(rèn)為沒有定義a[2]傀缩,但是根據(jù)前面的知識那先,我們知道數(shù)組元素可以使用指針來訪問,因此對數(shù)組的引用沒有邊界約束扑毡,因此數(shù)據(jù)覆蓋了d[0]的地方胃榕,造成了錯(cuò)誤盛险。如果i更大瞄摊,那就有可能在受保護(hù)的地方寫入了數(shù)據(jù),造成程序崩潰甚至被劫持苦掘。

二. 緩沖區(qū)溢出攻擊

造成緩沖區(qū)溢出的原因是沒有對棧中作為緩沖區(qū)的數(shù)組的訪問進(jìn)行越界檢查换帜。緩沖區(qū)溢出是一種非常普遍、非常危險(xiǎn)的漏洞鹤啡,在各種操作系統(tǒng)惯驼、應(yīng)用軟件中廣泛存在。利用緩沖區(qū)溢出攻擊递瑰,可導(dǎo)致程序運(yùn)行失敗祟牲、系統(tǒng)關(guān)機(jī)、重新啟動等后果抖部。

在前面的學(xué)習(xí)中我們知道在函數(shù)調(diào)用過程中说贝,會把返回地址入棧,并在函數(shù)調(diào)用結(jié)束后取出并跳轉(zhuǎn)慎颗。如果利用緩沖區(qū)溢出將函數(shù)返回地址修改為指向一段精心安排的惡意代碼乡恕,從而改變程序正常流向,則可達(dá)到危害系統(tǒng)安全的目的俯萎。最常見的手段是通過制造緩沖區(qū)溢出使程序運(yùn)行一個(gè)用戶shell傲宜,再通過shell執(zhí)行其它命令。若該程序有root或suid執(zhí)行權(quán)限夫啊,則攻擊者就獲得一個(gè)有root權(quán)限的shell函卒,進(jìn)而可對系統(tǒng)進(jìn)行任意操作。

舉個(gè)例子:

緩沖區(qū)溢出攻擊

上面的代碼原意是想打印出第一個(gè)參數(shù)撇眯,但是只分配了16個(gè)字節(jié)的大小报嵌。當(dāng)main函數(shù)調(diào)用outputs時(shí),會先保存返回地址叛本,然后保存EBP舊值沪蓬,重新形成棧底。然后分配16個(gè)字節(jié)的變量来候,并將參數(shù)入棧跷叉,準(zhǔn)備調(diào)用strcpy函數(shù)。

若strcpy復(fù)制了25個(gè)字符到buffer中,并將hacker首址置于結(jié)束符‘\0’前4個(gè)字節(jié)云挟,則在執(zhí)行strcpy后梆砸,hacker代碼首址被置于main棧幀返回地址處,當(dāng)執(zhí)行outputs代碼的ret指令時(shí)园欣,便會轉(zhuǎn)到hacker函數(shù)實(shí)施攻擊帖世。

即假定hacker首址為0x08048411,那么我們構(gòu)造一個(gè)字符串作為參數(shù)傳入:

char code[]=
"0123456789ABCDEFXXXX"
"\x11\x84\x04\x08"
"\x00";

int main(void) {
    char *argv[3];
    argv[0]="./test";
    argv[1]=code;
    argv[2]=NULL;
    execve(argv[0],argv,NULL);
    return 0;
}

就可以轉(zhuǎn)到hacker函數(shù)實(shí)施攻擊沸枯。

三. 緩沖區(qū)溢出防范
函數(shù) 危險(xiǎn)性 解決方案
gets 最高 禁用gets(buf)日矫,改用fgets(buf, size, stdin)
strcpy 檢查目標(biāo)緩沖區(qū)大小,或改用strncpy绑榴,或動態(tài)分配目標(biāo)緩沖區(qū)
strcat 改用strncat
sprintf 改用snprintf哪轿,或使用精度說明符
scanf 使用精度說明符,或自己進(jìn)行解析
sscanf 使用精度說明符翔怎,或自己進(jìn)行解析
fscanf 使用精度說明符窃诉,或自己進(jìn)行解析
vfscanf 使用精度說明符,或自己進(jìn)行解析
vsprintf 改為使用vsnprintf赤套,或使用精度說明符
vscanf 使用精度說明符飘痛,或自己進(jìn)行解析
vsscanf 使用精度說明符,或自己進(jìn)行解析
streadd 確保分配的目標(biāo)參數(shù)緩沖區(qū)大小是源參數(shù)大小的四倍
strecpy 確保分配的目標(biāo)參數(shù)緩沖區(qū)大小是源參數(shù)大小的四倍
strtrns 手工檢查目標(biāo)緩沖區(qū)大小是否至少與源字符串相等
getenv 不可假定特殊環(huán)境變量的長度
realpath 高(或稍低容握,實(shí)現(xiàn)依賴) 分配緩沖區(qū)大小為PATH_MAX字節(jié)宣脉,并手工檢查參數(shù)以確保輸入?yún)?shù)和輸出參數(shù)均不超過PATH_MAX
syslog 高(或稍低,實(shí)現(xiàn)依賴) 將字符串輸入傳遞給該函數(shù)之前唯沮,將所有字符串輸入截成合理大小
getopt 高(或稍低脖旱,實(shí)現(xiàn)依賴) 將字符串輸入傳遞給該函數(shù)之前,將所有字符串輸入截成合理大小
getopt_long 高(或稍低介蛉,實(shí)現(xiàn)依賴) 將字符串輸入傳遞給該函數(shù)之前萌庆,將所有字符串輸入截成合理大小
getpass 高(或稍低,實(shí)現(xiàn)依賴) 將字符串輸入傳遞給該函數(shù)之前币旧,將所有字符串輸入截成合理大小
getchar 若在循環(huán)中使用該函數(shù)践险,確保檢查緩沖區(qū)邊界
fgetc 若在循環(huán)中使用該函數(shù),確保檢查緩沖區(qū)邊界
getc 若在循環(huán)中使用該函數(shù)吹菱,確保檢查緩沖區(qū)邊界
read 若在循環(huán)中使用該函數(shù)巍虫,確保檢查緩沖區(qū)邊界
bcopy 確保目標(biāo)緩沖區(qū)不小于指定長度
fgets 確保目標(biāo)緩沖區(qū)不小于指定長度
memcpy 確保目標(biāo)緩沖區(qū)不小于指定長度
snprintf 確保目標(biāo)緩沖區(qū)不小于指定長度
strccpy 確保目標(biāo)緩沖區(qū)不小于指定長度
strcadd 確保目標(biāo)緩沖區(qū)不小于指定長度
strncpy 確保目標(biāo)緩沖區(qū)不小于指定長度
vsnprintf 確保目標(biāo)緩沖區(qū)不小于指定長度
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市鳍刷,隨后出現(xiàn)的幾起案子占遥,更是在濱河造成了極大的恐慌,老刑警劉巖输瓜,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瓦胎,死亡現(xiàn)場離奇詭異芬萍,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)搔啊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門柬祠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人负芋,你說我怎么就攤上這事漫蛔。” “怎么了旧蛾?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵莽龟,是天一觀的道長。 經(jīng)常有香客問我蚜点,道長轧房,這世上最難降的妖魔是什么拌阴? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任绍绘,我火速辦了婚禮,結(jié)果婚禮上迟赃,老公的妹妹穿的比我還像新娘陪拘。我一直安慰自己,他們只是感情好纤壁,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布左刽。 她就那樣靜靜地躺著,像睡著了一般酌媒。 火紅的嫁衣襯著肌膚如雪欠痴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天秒咨,我揣著相機(jī)與錄音喇辽,去河邊找鬼。 笑死雨席,一個(gè)胖子當(dāng)著我的面吹牛菩咨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播陡厘,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼抽米,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了糙置?” 一聲冷哼從身側(cè)響起云茸,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎谤饭,沒想到半個(gè)月后标捺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體胖笛,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年宜岛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了长踊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 37,997評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡萍倡,死狀恐怖身弊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情列敲,我是刑警寧澤阱佛,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站戴而,受9級特大地震影響凑术,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜所意,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一淮逊、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧扶踊,春花似錦泄鹏、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至分井,卻和暖如春车猬,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背尺锚。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工珠闰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人缩麸。 一個(gè)月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓铸磅,卻偏偏與公主長得像,于是被迫代替她去往敵國和親杭朱。 傳聞我的和親對象是個(gè)殘疾皇子阅仔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 官網(wǎng) 中文版本 好的網(wǎng)站 Content-type: text/htmlBASH Section: User ...
    不排版閱讀 4,367評論 0 5
  • 緩沖區(qū)溢出(Buffer Overflow)是計(jì)算機(jī)安全領(lǐng)域內(nèi)既經(jīng)典而又古老的話題。隨著計(jì)算機(jī)系統(tǒng)安全性的加強(qiáng)弧械,傳...
    Chivalrous閱讀 1,327評論 0 5
  • 原文地址:https://github.com/JuanitoFatas/slime-user-manual#24...
    四月不見閱讀 3,104評論 0 2
  • 第5章 引用類型(返回首頁) 本章內(nèi)容 使用對象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,212評論 0 4
  • 計(jì)算機(jī)系統(tǒng)漫游 代碼從文本到可執(zhí)行文件的過程(c語言示例):預(yù)處理階段八酒,處理 #inlcude , #defin...
    willdimagine閱讀 3,560評論 0 5