2013年12月26日 星期四

安全保護技術ASLR繞過啟示錄

原文:Link
譯者:Windbg
最近許多APT攻擊使用了新的技術繞過位址隨機化(ASLR),雖然位址隨機化是當前作業系統最有效的防護機制之一,但還不夠完善。在過去一年裡,我們發現了以下幾個有趣的繞過ASLR的技術:
   0x1:   使用未開啟ASLR的模組
   0x2:   修改BSTR長度/null結束符
   0x3:   修改陣列物件
注:標準BSTR是一個有長度首碼和null結束符的OLECHAR陣列。
下面詳細講解這些技術。

0×1:未開啟位址隨機化的模組
    載入一個未開啟位址隨機化的模組是最容易也是最流行的繞過位址隨機化保護的方法,在IE 0day中最常使用的兩個未開啟位址隨機化的模組是:MSVCR71.DLL HXDS.DLL
    JRE 1.6.x包含了一個老版本的C 運行庫 MSVCR71.DLL,編譯時沒有加上/DYNAMICBASE 編譯選項。預設情況下,win7+ie8  win7 +ie9 下,這個DLL會以固定位址載入到IE的進程中。
    MS Office 2010/2007中的 HXDS.DLL  編譯時也沒加上相關選項,該技術最先是在http://www.greyhathacker.net/?p=585提出,也是當前在IE 8/9 + win7 環境下使用最頻繁的過位址隨機化的方法,當流覽器載入一個帶try location.href = ms-help:// 語句的頁面時,這個DLL就會被載入。
下面的0day利用裡面,至少使用了其中一種技術繞過位址隨機化:
CVE-2013-3893
 CVE2013-1347 CVE-2012-4969 CVE-2012-4792
使用條件:
通過未開啟ASLR模組來繞過ASLR的方法要求被攻擊機器運行了較老的軟體如 JRE 1.6  或者 Office 2007/2010 ,升級到最新版的JAVA/OFFICE 就可以這種類型的攻擊。
0×2:修改BSTR長度/null 結束符
    這個技術是Peter Vreugdenhil 2010  Pwn2Own IE 8 上利用的,它只適用於可以覆寫記憶體的漏洞,例如緩衝區溢位,任意位址寫 對可控指標所指向的記憶體內容執行增加或減少操作的漏洞。
    任意位址寫入 類型的漏洞不能直接控制EIP,多數時候,這種類型的漏洞利用會覆寫程式重要的資料如函數指標來達到執行代碼的目的。對於攻擊者來說,他們可以隨意修改BSTR的長度,然後利用BSTR去控制超出邊界的記憶體,這樣就可以洩漏記憶體位址,精確找到可以構造ropdll 。一旦通過這種方式繞過了位址隨機化,也可以使用同樣的漏洞控制EIP
    為數較少漏洞可以用來修改BSTR的長度。例如,一些漏洞只能增加或減少指標一兩個位元組,這種情況下,攻擊者可以修改字串的null結束符使該字串和下一個物件連接起來,這樣下一個物件就成為該字串的一部分,而在這個物件中,一般可以找到和DLL基址相關的資訊。
CVE-2013-0640
Adobe XFA 0day利用中,使用了上述技術找到了AcroForm.api 的基址,動態的構造了rop鏈繞過ASLR DEP ,在這個漏洞裡,攻擊者可以將可控指標指向的內容減一,然後從虛函數表中調用函數。


想像一下在Dec操作之前的記憶體佈局,如下:
[string][null][non-null
data][object]
dec操作之後(在我測的時候,減少了兩次),記憶體佈局變成了:
[string][\xfe][non-null
data][object]
更多細節請查看immunityincs blog.
使用條件:
    這個技術通常需要多次寫入來洩漏需要的資訊,攻擊者需要非常精准的設計堆的佈局,保證length欄位被覆寫而不是記憶體中其他的物件。從IE 9開始,微軟使用了Nozzlehttp://research.microsoft.com/pubs/81085/usenixsec09b.pdf)來防止堆噴/風水,所以有時攻擊者需要使用VBArray技術來精准佈局堆。
修改陣列物件
    陣列物件長度修改和BSTR長度修改相似:他們都需要“好用”的漏洞。從攻擊者來看,一旦陣列長度被修改,攻擊者既可以任意讀寫記憶體或者控制程式流程,到達代碼執行的目的。
下面是使用該技術的0day利用。
CVE-2013-0634
   這個漏洞是Flash player在處理regex時的堆溢出,攻擊者覆寫了Vector.<Number>物件的length屬性,然後就可以讀取更多的內容,獲取flash.ocx的基址。
   這個漏洞利用流程如下:



Step1:通過申請下面所示的物件來設置連續的記憶體佈局:


Step2:如下所示釋放掉上面申請的物件中序號為1<Number>物件。

obj[1]
= null;
Step3:申請一個RegExp物件,這次申請會重新使用剛才釋放掉的位置。
boom = "(?i)()()(?-i)||||||||||||||||||||||||";
var trigger = new RegExp(boom, "");
    然後,當觸發漏洞後,會覆寫掉obj[2]裡的 Vector.<Number>物件的長度屬性,使其變大,攻擊者就可以通過obj[2]來讀寫一個大範圍的記憶體空間來定位flash.ocx的基址,然後覆寫掉虛表達到代碼執行的目的。
CVE-2013-3163
    這個漏洞是IE CBlockContainerBlock  物件UAF ,利用程式和CVE-2013-0634很像,但是更複雜一些。
    這個漏洞使用 OR 指令修改任意記憶體內容,大致如下:
or dword ptr [esi+8],20000h
利用流程如下:


首先,使用Vector.<uint>對象填充堆。
在填充之後,這些物件以對齊的方式存儲在一個固定的位址。

像是這樣:
第一個dword
0x03f0Vector.<uint>物件的長度,黃色標記是我們填充的值。如果攻擊者將esi+8指向0x03f0,or指令執行過後,變為0x0203f0,看到沒,大多了!!由於可控範圍變大,可將緊接著的對象長度改為0x3FFFFFF0



然後,攻擊者就可以控制整個IE進程的記憶體空間了,NB!位址隨機化也就沒用了,因為可以直接從記憶體中獲取到kernel32/NTDLL的基址。通過從程式碼片段動態尋找stack pivot
gadgets,從IAT定位到ZwProtectVirtualMemory,就可以構造rop鏈修改記憶體屬性繞過DEP.


通過精確的記憶體佈局,攻擊者又申請了一個包含flash.Media.Sound()對象的Vector.<object>,使用已經被修改過的Vector.<uint>物件去尋找sound物件,然後覆寫它的虛表指向rop鏈和shellcode.
CVE-2013-1690
   這是FireFoxDocumentViewerImpl物件的UAF漏洞,可以任意記憶體寫入一個word0×0001.
    上面的代碼中,所有以 m’開頭的變數都是從我們可以控制的物件中讀取的。如果可以設置物件,進入第二個條件判斷,強制跳進setImageAnimationMode()調用,觸發記憶體覆寫。setImageAnimationMode()內部代碼大概如下:



在這個利用中,攻擊者嘗試使用ArrayBuffer來精確佈局堆。下面的代碼中,每一個var2中的ArrayBuffer原始大小為0xff004

觸發漏洞後,ArrayBuffer長度增加為0x010ff004.也可通過在JS中比較byteLength來定位被修改了長度的ArrayBuffer ,然後攻擊者可通過這個ArrayBuffer來讀寫記憶體了。這次,攻擊者選擇從SharedUserData(0x7ffe0300)洩漏NTDLL的基址,然後手動硬編碼偏移來構造ROP.
CVE-2013-1493
   這個漏洞是JAVA CMM的整數溢出漏洞,可以覆寫陣列長度。在漏洞利用中,陣列長度可以到達0x7fffffff,攻擊者可以搜索securityManager物件然後設置它為null來繞過沙箱。
   這個方法相較於覆寫函數指標,處理位址隨機化和資料執行保護以到達代碼執行更加有效。
   陣列物件修改技術比其他的要好一些。因為Flash ActionScript vector技術,堆填充一點都沒受影響。只要你有記憶體覆寫漏洞,很輕鬆的就可以利用。
幾種技術細節對比對比:
繞過ASLR技術
優點
使用限制
CVE
備註
修改陣列物件
高級利用技巧
擴大陣列長度後可以任意記憶體讀寫
需要有記憶體覆寫漏洞
需要被攻擊者安裝flash

CVE-2013-1690
FireFox uaf 可以覆寫一個用戶控制的指標  修改ArrayBuffer長度到達任意記憶體讀寫
CVE-2013-3163
IE  UAF 。攻擊者可以修改Vector.<Uint>的長度,然後尋找構造rop的指令
CVE-2013-1493
JAVA整數溢出,覆寫陣列物件長度,到達任意記憶體讀寫
CVE-2013-0633
FLASH PLAYER 規則運算式緩衝區溢位,修改Vector.<Number>物件到達任意記憶體讀寫

修改BSTR null結束符

高級利用技巧
能洩漏部分記憶體繞過位址隨機化

記憶體覆寫漏洞
不同的Adobe Reader需要硬編碼不同的rop 偏移
CVE-2013-0640
Adobe Reader 未初始化記憶體使用   修改BSTR  null結束符洩露記憶體

使用未開啟位址隨機化的模組
容易利用
不太需要技巧

特定版本的軟體

CVE-2013-3893

IE UAF hxds.dll中構造rop 繞過位址隨機化和資料執行保護。
CVE-2012-4792
IE UAF JRE 1.6 OFFICE 2010 未開啟地址隨機化
總結
    繞過位址隨機化是現在漏洞利用最基本的需求,之前利用MS OFFICE未開啟ASLR dll來繞過,但是微軟在最新的作業系統和流覽器裡面做了限制。之前的技術將淘汰也更容易被檢測,攻擊者需要更先進的技術,對於可以覆寫記憶體的漏洞,結合Vector.<uint> Vector.<object>將更加可靠和靈活,從只能寫一個位元組到大範圍讀寫記憶體將非常容易,而且適用於各種作業系統,應用程式,語言版本。
    許多研究者公佈了對於繞過地址隨機化的研究,像Dion Blazakis JIT spray and tombkeeper LdrHotPatchRoutine技術。但是至今還未見使用,可能是因為這些技術是通用的對抗ASLR的方法,所以一經公佈,很快就被修補了。
    但是沒有一種通用的辦法修補特定的漏洞利用,希望將來有更多的0day使用相同的或者更加高級的技巧,我們可能需要在OSs裡面加入新的防護措施和安全產品來對抗0day攻擊。


沒有留言:

張貼留言