關(guān)于Windows上地址空間布局隨機(jī)化防御機(jī)制的分析(下)
上篇給大家介紹關(guān)于Windows上地址空間布局隨機(jī)化防御機(jī)制的分析(上),這篇文章介紹了在Windows上實(shí)施的地址空間布局隨機(jī)化的一些歷史,并探討了Windows實(shí)施的一些功能和局限性。
將32位程序重新編譯為64位程序,以使地址空間布局隨機(jī)化更有效
盡管Windows的64位版本已經(jīng)成為主流十多年了,但32位版本的使用者仍然很多。有些程序確實(shí)需要保持與第三方插件的兼容性,比如web瀏覽器。有時(shí),開發(fā)團(tuán)隊(duì)認(rèn)為程序所需的內(nèi)存遠(yuǎn)遠(yuǎn)少于4 GB,因此32位代碼可以節(jié)省空間。甚至Visual Studio在支持構(gòu)建64位應(yīng)用程序之后,在一段時(shí)間內(nèi)還仍然支持32位應(yīng)用程序。
實(shí)際上,從32位代碼切換到64位代碼會(huì)產(chǎn)生很小但可觀察到的安全性好處。原因是隨機(jī)化32位地址的能力是有限的。至于具體原因,請(qǐng)觀察圖1中32位x86內(nèi)存地址的分解方式。更多詳細(xì)信息,請(qǐng)參見“物理地址擴(kuò)展”。
內(nèi)存地址分為多個(gè)組件,其中只有一些可以在運(yùn)行時(shí)輕松隨機(jī)化
操作系統(tǒng)不能簡(jiǎn)單地將地址的任意位隨機(jī)化,在頁面部分(0到11位)中隨機(jī)分配偏移量將打破程序?qū)?shù)據(jù)對(duì)齊的假設(shè)。頁面目錄指針(位30和31)也不能被更改,因?yàn)榈?1位是為內(nèi)核保留的,而第30位被物理地址擴(kuò)展用作存儲(chǔ)體交換技術(shù),以尋址2 GB以上的RAM,這使得32位地址中的14位不能被隨機(jī)化。
實(shí)際上,Windows只嘗試隨機(jī)化32位地址中的8位。這些是位從16到23,只影響地址的頁目錄條目和頁表?xiàng)l目部分。因此,在暴力情況下,攻擊者可能僅用256次猜測(cè)就能猜出EXE的基本地址。
將ASLR應(yīng)用于64位二進(jìn)制文件時(shí),Windows能夠隨機(jī)分配地址的17-19位(具體取決于它是DLL還是EXE)。圖2顯示了對(duì)于64位代碼,可能的基址數(shù)量以及相應(yīng)的暴力猜測(cè)數(shù)量如何顯著增加,這可以使端點(diǎn)保護(hù)程序或系統(tǒng)管理員可以在攻擊發(fā)生之前檢測(cè)出攻擊。
將32位代碼重新編譯為64位會(huì)大大增加可供地址空間布局隨機(jī)化選擇的基本地址數(shù)量
總結(jié)起來就是:
1. 必須處理不可信數(shù)據(jù)的軟件應(yīng)該始終編譯為64位,即使它不需要使用大量?jī)?nèi)存,也可以充分利用地址空間布局隨機(jī)化。
在暴力攻擊中,地址空間布局隨機(jī)化使攻擊64位程序的難度比攻擊完全相同程序的32位版本的難度至少高了512倍。
2. 即使是64位ASLR也會(huì)受到暴力攻擊,防御者必須集中精力檢測(cè)暴力攻擊,或者避免出現(xiàn)暴力攻擊可行的情況。
假設(shè)攻擊者每秒可以對(duì)一個(gè)脆弱的系統(tǒng)進(jìn)行十次暴力嘗試。在通常的情況下,由于多個(gè)實(shí)例正在運(yùn)行,目標(biāo)進(jìn)程保留在同一地址,攻擊者會(huì)在不到一分鐘的時(shí)間內(nèi)發(fā)現(xiàn)32位程序的基地址,而在數(shù)小時(shí)內(nèi)就會(huì)發(fā)現(xiàn)64位程序的基地址。64位暴力攻擊會(huì)產(chǎn)生更多的干擾,但是管理員或安全軟件需要注意并采取行動(dòng)。除了使用64位程序來提高地址空間布局隨機(jī)化的效率外,系統(tǒng)還應(yīng)避免重新生成崩潰程序,以避免讓攻擊者發(fā)現(xiàn)基址,為了以防萬一最好強(qiáng)制重新啟動(dòng),因此應(yīng)保證進(jìn)程崩潰后多次刷新地址空間。
3. 針對(duì)32位和64位版本的程序開發(fā)概念驗(yàn)證攻擊的研究人員應(yīng)首先關(guān)注32位,只要32位程序仍然有效,針對(duì)程序的32位變體的概念驗(yàn)證攻擊就可能更容易開發(fā)。由此產(chǎn)生的攻擊可能更可行且更有說服力,從而導(dǎo)致供應(yīng)商更快地修補(bǔ)程序。
Windows 10會(huì)比Windows 7更頻繁地重用隨機(jī)基址,這在某些情況下可能會(huì)使它變得容易受到攻擊
請(qǐng)注意,即使Windows系統(tǒng)必須確保一個(gè)DLL或EXE的多個(gè)實(shí)例都在相同的基址加載,系統(tǒng)也不需要在卸載DLL或EXE的最后一個(gè)實(shí)例時(shí)跟蹤基址。如果DLL或EXE再次被加載,它可以獲得一個(gè)新的基地址,這是我們?cè)谑褂肳indows 7時(shí)觀察到的行為。Windows 10可以以不同的方式工作,即使在DLL或EXE的最后一個(gè)實(shí)例被卸載后,它也可能至少在短時(shí)間內(nèi)保持相同的基址,與DLL相比,EXE更是如此。在多進(jìn)程調(diào)試器下重復(fù)啟動(dòng)命令行程序時(shí),可以觀察到這一點(diǎn)。但是,如果將該程序復(fù)制到新文件名然后啟動(dòng),它將收到一個(gè)新的基地址。同樣,如果經(jīng)過了足夠長(zhǎng)的時(shí)間,該程序?qū)⒓虞d到其他基址。當(dāng)然,重新啟動(dòng)會(huì)為所有DLL和EXE生成新的基地址。
總結(jié)起來就是:除了每次啟動(dòng)隨機(jī)化外,不要對(duì)Windows ASLR保證做任何假設(shè)。特別是,每當(dāng)加載給定EXE或DLL的第一個(gè)實(shí)例時(shí),不要依賴Windows 7的行為來隨機(jī)分配新的地址空間。不要以為Windows天生就能以任何方式防止針對(duì)地址空間布局隨機(jī)化的暴力攻擊,特別是對(duì)于32位進(jìn)程,在這種情況下,暴力攻擊可能需要256次或更少的猜測(cè)。
Windows 10對(duì)地址空間布局隨機(jī)化的利用更加積極,甚至對(duì)不與地址空間布局隨機(jī)化兼容的exe和dll也能進(jìn)行有效防護(hù),這可能使地址空間布局隨機(jī)化的應(yīng)用范圍更大
Windows Vista和Windows 7是最早支持地址空間布局隨機(jī)化的系統(tǒng),因此地址空間布局隨機(jī)化在設(shè)計(jì)之初在兼容性方面進(jìn)行了一些權(quán)衡。具體來說,這些舊的實(shí)現(xiàn)不會(huì)將地址空間布局隨機(jī)化應(yīng)用于沒有標(biāo)記為與地址空間布局隨機(jī)化兼容的映像,也不允許地址空間布局隨機(jī)化將地址推送到4 GB邊界以外。如果一個(gè)映像沒有選擇加入地址空間布局隨機(jī)化,這些Windows版本將繼續(xù)使用首選的基本地址。
可以使用Microsoft的增強(qiáng)緩解經(jīng)驗(yàn)工具包(通常稱為EMET)進(jìn)一步強(qiáng)化Windows 7,以更積極地將地址空間布局隨機(jī)化應(yīng)用于甚至未標(biāo)記為與它兼容的映像。 Windows 8引入了更多功能,可將ASLR應(yīng)用于不兼容地址空間布局隨機(jī)化的映像,以更好地使堆分配隨機(jī)化,并增加64位映像的熵位數(shù)。
總結(jié)起來就是:
1. 確保程序項(xiàng)目使用正確的鏈接器標(biāo)記來選擇最積極的地址空間布局隨機(jī)化實(shí)現(xiàn),并且不使用任何削弱地址空間布局隨機(jī)化的鏈接器標(biāo)記。
如下表所示,鏈接器標(biāo)記可能會(huì)影響地址空間布局隨機(jī)化應(yīng)用到映像的方式。請(qǐng)注意,對(duì)于Visual Studio 2012及更高版本,“+”標(biāo)記在默認(rèn)情況下已經(jīng)啟用,并且只要不使用“-”標(biāo)記,就會(huì)使用最佳的地址空間布局隨機(jī)化實(shí)現(xiàn)。使用Visual Studio 2010或更早版本(可能是出于兼容性原因)的開發(fā)人員需要檢查鏈接器支持的標(biāo)記,以及默認(rèn)情況下啟用的標(biāo)記。
鏈接器標(biāo)記可能會(huì)影響如何將ASLR應(yīng)用到映像
2. 啟用強(qiáng)制性地址空間布局隨機(jī)化和自下而上的隨機(jī)化,Windows 8和Windows 10包含一些可選的功能,可在未標(biāo)記為與地址空間布局隨機(jī)化兼容的映像上強(qiáng)制被啟用,并隨機(jī)分配虛擬內(nèi)存分配,以便重新建立基礎(chǔ)的映像來獲得隨機(jī)基址。當(dāng)EXE與ASLR兼容,但它使用的某個(gè)dll不兼容時(shí),這是很有用的。防御者應(yīng)該使這些特性能夠更廣泛地應(yīng)用地址空間布局隨機(jī)化,而且重要的是,它有助于發(fā)現(xiàn)任何剩余的不兼容地址空間布局隨機(jī)化的程序,以便可以對(duì)其進(jìn)行升級(jí)或替換。
ASLR將整個(gè)可執(zhí)行映像重新定位為一個(gè)單元
ASLR通過選擇一個(gè)隨機(jī)偏移量來重定位可執(zhí)行映像,并將其應(yīng)用于映像中與它的基本地址相關(guān)的所有地址。也意味著:如果EXE中的兩個(gè)函數(shù)位于地址0x401000和0x401100,那么即使在重新定位映像之后,它們之間仍然保持0x100字節(jié)的距離。很明顯,這很重要,因?yàn)閤86代碼中普遍存在相對(duì)調(diào)用和jmp指令。同樣,無論位于何處,位于0x401000處的函數(shù)將與映像的基本地址保持0x1000字節(jié)的距離。同樣,如果兩個(gè)靜態(tài)變量或全局變量在映像中相鄰,則在應(yīng)用地址空間布局隨機(jī)化后它們?nèi)詫⒈3窒噜?。相反,堆棧和堆變量以及?nèi)存映射文件不是映像的一部分,可以隨意隨機(jī)分配,而不需要考慮選擇的基址。
總結(jié)起來就是:
1. 可執(zhí)行映像中僅一個(gè)指針的泄漏就可以暴露整個(gè)映像的隨機(jī)地址。
ASLR最大的限制和煩人之處在于,一些看似無害的特性,如調(diào)試日志消息或堆棧跟蹤會(huì)泄漏映像中的指針,從而成為漏洞。如果攻擊者擁有相同程序或DLL的副本,并且可以觸發(fā)它產(chǎn)生相同的泄漏,那么他們可以計(jì)算地址空間布局隨機(jī)化和地址空間布局隨機(jī)化之前指針之間的差異來確定隨機(jī)化前后的偏移量。然后,攻擊者可以將該偏移量應(yīng)用到其攻擊有效載荷中的每個(gè)指針,以繞過地址空間布局隨機(jī)化。防御者應(yīng)該培訓(xùn)軟件開發(fā)人員關(guān)于指針暴露漏洞的知識(shí),以便他們認(rèn)識(shí)到這個(gè)漏洞的嚴(yán)重性,并且作為軟件開發(fā)生命周期的一部分,定期評(píng)估軟件的這些漏洞。
2. 某些類型的內(nèi)存損壞漏洞超出了ASLR能夠保護(hù)的范圍。
并不是所有的內(nèi)存損壞漏洞都需要直接實(shí)現(xiàn)遠(yuǎn)程代碼執(zhí)行,比如有這樣一個(gè)程序,它包含一個(gè)緩沖區(qū)變量,用于從網(wǎng)絡(luò)中接收不可信的數(shù)據(jù),以及一個(gè)標(biāo)記變量,該變量位于其后的內(nèi)存中。標(biāo)記變量包含一些位,這些位指定用戶是否已登錄以及該用戶是否為管理員。如果程序在接收緩沖區(qū)的末尾寫入數(shù)據(jù),則“標(biāo)記變量將被覆蓋,攻擊者可以同時(shí)設(shè)置已登錄和is-admin標(biāo)記。由于攻擊者無需知道或?qū)懭肴魏蝺?nèi)存地址,因此地址空間布局隨機(jī)化不會(huì)阻止攻擊。只有當(dāng)另一種強(qiáng)化技術(shù)(如編譯器強(qiáng)化標(biāo)志)重新排序變量,或者更好地使變量在程序中的位置獨(dú)立移動(dòng)時(shí),此類攻擊才會(huì)被阻止。
總結(jié)
地址空間布局隨機(jī)化是針對(duì)內(nèi)存破壞漏洞的核心防御措施,這篇文章介紹了在Windows上實(shí)施的地址空間布局隨機(jī)化的一些歷史,并探討了Windows實(shí)施的一些功能和局限性。通過閱讀這篇文章,防御者可以熟知如何構(gòu)建程序來更好地利用地址空間布局隨機(jī)化和Windows中提供的其他功能。不過地址空間布局隨機(jī)化的防御機(jī)制也不是完美的,攻擊者可以利用地址空間布局隨機(jī)化的限制,例如只在每次重啟時(shí)應(yīng)用地址空間隨機(jī)化和將整個(gè)映像重新定位為一個(gè)單元隨機(jī)化,從而使用暴力和指針泄漏攻擊來繞過地址空間隨機(jī)化的防護(hù)。
本文翻譯自:https://www.fireeye.com/blog/threat-research/2020/03/six-facts-about-address-space-layout-randomization-on-windows.html如若轉(zhuǎn)載,請(qǐng)注明原文地址。