十八、內(nèi)存
作者:Peter Yaworski
譯者:飛龍
協(xié)議:CC BY-NC-SA 4.0
描述
緩沖區(qū)溢出是一個(gè)場(chǎng)景,其中程序向緩沖區(qū)或內(nèi)容區(qū)域?qū)懭霐?shù)據(jù),寫(xiě)入的數(shù)據(jù)比實(shí)際分配的區(qū)域要多。使用冰格來(lái)考慮的話,你可能擁有 12 個(gè)空間,但是只想要?jiǎng)?chuàng)建 10 個(gè)。在填充格子的時(shí)候,你添加了過(guò)多的水,填充了 11 個(gè)位置而不是 10 個(gè)。你就溢出了冰格的緩存區(qū)。
緩沖區(qū)溢出在最好情況下,會(huì)導(dǎo)致古怪的程序行為,最壞情況下,會(huì)產(chǎn)生嚴(yán)重的安全漏洞。這里的原因是,使用緩沖區(qū)移除,漏洞程序就開(kāi)始使用非預(yù)期數(shù)據(jù)覆蓋安全數(shù)據(jù),之后會(huì)調(diào)用它們。如果這些發(fā)生了,覆蓋的代碼會(huì)是和程序的預(yù)期完全不同的東西,這會(huì)產(chǎn)生錯(cuò)誤。或者,惡意用戶能夠使用移除來(lái)寫(xiě)入并執(zhí)行惡意代碼。
這里是來(lái)自 Apple 的一個(gè)圖片:
這里第一個(gè)例子展示了可能的緩沖區(qū)溢出。strcpy接受字符串Larger,并將其寫(xiě)入到內(nèi)存,無(wú)論分配的可用空間(白色格子),以及將其寫(xiě)入非預(yù)期的內(nèi)容中(紅色格子)。
越界讀取
除了越過(guò)分配的內(nèi)容寫(xiě)入數(shù)據(jù)之外,另一個(gè)漏洞時(shí)越過(guò)內(nèi)容邊界讀取數(shù)據(jù)。這是一類緩沖區(qū)溢出,因?yàn)閮?nèi)容被越界讀取,這是緩存區(qū)不允許的。
越界讀取數(shù)據(jù)漏洞的一個(gè)著名的近期示例,是 OpenSSL Heartbleed 漏洞,在 2014 年 4 月發(fā)現(xiàn)。在發(fā)現(xiàn)的時(shí)候,大約 17%(500K)的互聯(lián)網(wǎng)安全服務(wù)器,由可信授權(quán)機(jī)構(gòu)頒發(fā)證書(shū),被認(rèn)為存在此漏洞。
Heartbleed 可以利用來(lái)盜取服務(wù)器的私鑰,回話數(shù)據(jù),密碼,以及其他。它通過(guò)向服務(wù)器發(fā)送“Heatbleed 請(qǐng)求”消息來(lái)執(zhí)行,服務(wù)器會(huì)向請(qǐng)求者發(fā)送相同信息。消息包含長(zhǎng)度參數(shù)。那些漏洞服務(wù)器會(huì)基于長(zhǎng)度參數(shù)為消息分配內(nèi)存,而不驗(yàn)證消息的真實(shí)大小。
因此,Heartbleed 消息通過(guò)發(fā)送小型消息以及較大的長(zhǎng)度參數(shù)來(lái)利用,存在漏洞的接受者會(huì)讀取額外數(shù)據(jù),這超出了為消息分配的內(nèi)存長(zhǎng)度。這里是來(lái)自維基百科的圖片:
雖然緩沖區(qū)溢出需要更詳細(xì)的分析,讀取越界和 Heartbleed 超出了本書(shū)的范圍。如果你對(duì)它們感興趣,這里是一些不錯(cuò)的資源:
內(nèi)存截?cái)?/h3>
內(nèi)存截?cái)嗍且环N技巧,用于通過(guò)使代碼執(zhí)行一些不常見(jiàn)或者非預(yù)期的行為,來(lái)發(fā)現(xiàn)漏洞。它的效果類似于緩沖區(qū)溢出,其中內(nèi)容在不該暴露的時(shí)候暴露了。
一個(gè)例子是空字節(jié)注入。這發(fā)生在提供了空字節(jié)%00或者十六進(jìn)制的0x00,并導(dǎo)致接收程序的非預(yù)期行為時(shí)。在 C/C++,或低級(jí)編程語(yǔ)言中,空字節(jié)表示字符串的末尾,或者字符串的終止符。這可以告訴程序來(lái)立即停止字符串的處理,空字節(jié)之后的字節(jié)就被忽略了。
當(dāng)代碼依賴字符串長(zhǎng)度時(shí),它的影響力十分巨大。如果讀取了空字節(jié),并停止了處理,長(zhǎng)度為 10 的字符串就只剩 5 了。例如:
thisis%00mystring
這個(gè)字符串的長(zhǎng)度應(yīng)該為 15,暗示如果字符串以空字節(jié)終止,它的長(zhǎng)度為 6。這對(duì)于管理自己的內(nèi)存的低級(jí)語(yǔ)言是有問(wèn)題的。
現(xiàn)在,對(duì)于 Web 應(yīng)用,當(dāng) Web 應(yīng)用和庫(kù)、外部 API 以及其它用 C 寫(xiě)成的東西交互的時(shí)候,這就有關(guān)系了。向 URL 傳入%00可能使攻擊者操作更廣泛服務(wù)器環(huán)境中的 Web 資源。尤其是當(dāng)編程語(yǔ)言存在問(wèn)題的時(shí)候,例如 PHP,它是使用 C 語(yǔ)言編寫(xiě)的。
OWASP 鏈接
查看 OWASP 緩沖區(qū)溢出,OWASP 為緩沖區(qū)覆蓋和溢出復(fù)查代碼,OWASP 檢測(cè)緩沖區(qū)溢出,OWASP 檢測(cè)堆溢出,OWASP 檢測(cè)棧溢出,OWASP 嵌入空字符。
示例
1. PHPftp_genlist()
難度:高
URL:無(wú)
報(bào)告鏈接:https://bugs.php.net/bug.php?id=69545
報(bào)告日期:2015.5.12
獎(jiǎng)金:$500
描述:
PHP 編程語(yǔ)言使用 C 語(yǔ)言寫(xiě)成,C 語(yǔ)言自己管理內(nèi)存。像上面描述的那樣,緩沖區(qū)溢出允許惡意用戶寫(xiě)入應(yīng)該為不可訪問(wèn)的內(nèi)存,并可能執(zhí)行遠(yuǎn)程代碼。
這里,F(xiàn)TP 擴(kuò)展 的ftp_genlist()函數(shù)允許溢出,或者發(fā)送多于 ~4293MB 的數(shù)據(jù),它們會(huì)被寫(xiě)入到臨時(shí)文件中。
這使得分配的緩沖區(qū)太小,而不能存放寫(xiě)入臨時(shí)文件的數(shù)據(jù),在將文件內(nèi)容加載回內(nèi)存時(shí),這會(huì)造成堆溢出。
重要結(jié)論
緩沖區(qū)溢出是非常古老,知名的漏洞,但是在處理自己管理內(nèi)存的應(yīng)用時(shí),還是很普遍的,特別是 C 和 C++。如果你發(fā)現(xiàn),你正在處理基于 C 語(yǔ)言(PHP 用它編寫(xiě))的 Web 應(yīng)用,緩沖區(qū)溢出是一個(gè)明顯的可能性。但是,如果你剛起步,可能你需要花費(fèi)一些時(shí)間,來(lái)尋找和漏洞相關(guān)的簡(jiǎn)單注入,在更有經(jīng)驗(yàn)時(shí),再返回到緩沖區(qū)溢出。