Gadget構造:從JIT-ROP到對抗XnR
寫在前面
簡單地說,本文介紹了兩種
構造gadget的思路。(
在瀏覽器支持JIT的情況下)演進:關於JIT-ROP
我們知道,最初DEP的出現是為了對抗的棧溢出、堆溢出等這類劫持程序執行流的攻擊手法。在這之後,攻擊者為了繞過DEP,開始利用libc.so中的函數獲取shell,也就是我們所說的Ret2libc攻擊。更有效的防禦手段還有ASLR地址隨機化,使得libc.so載入的基址每次都會發生變化。當然,如果存在地址泄露等,ASLR仍可以被繞過。
於是乎,學術界前幾年開始研究細粒度的ASLR,即使基址被泄露,攻擊者也得不到準確的地址。
2013年s&p上發表了一篇文章提出
JIT-ROP
,這項工作極具創新性。其意義在於它提出了在運行時尋找gadget同時構造ROP鏈的概念。詳細的過程是這樣的:在存在一個內存泄露漏洞的情況下,得到一個運行時代碼指針,它泄露當前4k內存頁,因為當前頁可能會有分支指向其他頁,所以通過這個指針可以得到儘可能多的頁。將當前頁運行時反彙編後,獲得所需要的gadget並構造ROP鏈。也就是說,JIT-ROP是通過即時掃描有效內存,即時反彙編搜尋rop gadgets,即時拼接shellcode,從而繞過dep/aslr的,它在程序運行過程中動態執行,所依賴的資源在進程地址空間中獲取。所以它和傳統rop最大的不同在於:它可以使用任何代碼指針初始化攻擊環境,而傳統的rop需要泄露函數的具體地址。
這種攻擊手段可以繞過學術界過去提出的任意粒度的ASLR。
演進:關於XnR
為了針對JIT-ROP,14年ccs有一篇文章提出了XnR,利用軟體模擬的方式實現了頁的不可讀。
既然頁不可讀,那麼JIT-ROP所提出的運行時讀內存頁然後搜尋可用gadget這一思想就行不通了。
那麼如何對抗不可讀,提出使JIT-ROP攻擊不需要「可讀」這一條件,也可達成呢?這就是下面要討論的內容了。
相關:關於JIT
在進入正題之前,先簡單說說JIT引擎是什麼。
2008年,瀏覽器的JavaScript引擎引入JIT技術。JIT是一種即時編譯技術,是一種解決瀏覽器效率低下的方案。例如Javascript,它是典型的解釋型語言。程序員寫了一個for循環,解釋器是不知道這是一個循環的,所以它將會一句一句的去循環執行這個循環。這也是為什麼解釋型語言的效率特別低,因為它不會預先編譯。
JIT引擎的出現就是為了改善這一情況。它通過在運行時將部分語句編譯為機器碼,於是下次執行不需要再翻譯,從而省去了解釋開銷,使得瀏覽器性能大幅度改善。
JIT與攻擊
早期利用JIT新特性進行攻擊的方案是在2010年blackhat大會上提出的
Pointer Inference and JIT Spraying
,將 ActionScript代碼中進行大量的XOR操作。然後編譯成位元組碼,並且多次更新到Flash VM中,這樣它會建立很多帶有惡意Xor操作的內存塊。
但一方面這樣的方法比較舊,另一方面,學術界中早已提出防禦方法JITDefender。
準備工作
攻擊模型
(1)存在內存泄露漏洞
(2)不考慮CFI
(3)JavaScript環境
之所以如此,因為這篇文章的中心思想是,攻擊者可以通過自己注入gadget實現繞過其他限制手段如XnR。關注點並非實現真實過程的控制流轉移。
防禦環境
(1)DEP:NX,可寫不可執行
(2)ASLR: fine-grained,XnR應用於可執行文件,庫,JIT編譯而成的代碼
(3)Non-Readable Code: 所有代碼段不可讀
(4)Hidden Code Pointers: 除了JIT-compiled的指針均已匿名
(5)JIT Hardening: JIT上的防禦手段,比如randomized JIT pages, constant blinding,guard pages
攻擊方法
方法一:利用條件跳轉語句
原理:構造if/else,for/while,編譯成包含可預知的條件跳轉指令。
舉例說明一下,如果我們需要的gadget是
int 0x80;ret
,翻譯成機器碼也就是
0xcd80c3
。那麼,則往if中寫入0xc380cd位元組大小的JS代碼。
如上右圖,攻擊者是可以確定,編譯結果中肯定包含『je 0xc380cd』這一句的(x86/x64 架構採用小端存儲)。所以說,通過變化if中js代碼的大小,我們可以修改代碼長度,改變跳轉的距離。而每句JS代碼編譯後的大小是已知固定的。所以攻擊者可以精確的控制所生成的代碼長度。即,je後面的值,可以隨意控制。
舉個更具體的例子,在Chrome 33 (32-bit)/Chrome 51(64-bit)上,如果需要一個gadget:0xcd80c3。
S1: v=v1+v2, compiling to 0x10 bytes(64位 v=v)
S2: v=0x01010101, compiling to 0xd bytes.
使用S1 0c380c次(得到結果0xc380c0),
再使用S2 一次,求和即得到0xc380cd。
以上步驟可以注入自己想要的gadget,接下來就是要找到gadget所在的位置。
(1)首先通過內存泄露漏洞,得到JIT所編譯的JavaScript代碼的函數地址
(2)將這個函數的作為參數傳給另一個函數,這樣它就被push到stack中了(javascript的特性)。
(3)得到棧的信息,得到函數對象的指針,它包含了指向實際地址的指針。
方法二:利用直接調用語句
上一種方法對IE基本是無效的。IE部署了JIT-hardening策略,會隨機插入NOP,改變條件跳轉語句的值。這樣,編譯後的語句就不可控了。於是作者又提出使用直接調用指令實現攻擊。如:
call
0x1234560原理:任何兩個直接調用指令即時調用同一個函數,機器碼是不一樣的。其實和條件跳轉的原理差不多。之前控制的是je指令後邊的值,那它控制的是什麼呢。其實利用的是call後面的這個值是一個相對地址,第一次調用產生的機器碼是被調用者和下一次所調用的差。如下圖。
假設FUN函數在2000的位置。那麼在圖中,連續CALL FUN_1,所以這個常數代表FUN1和第二條CALL FUN1(即0x5)的距離。即
0x2000-0x5=0x1ffb
。(0x5是一條call指令的大小)。這個例子里,攻擊者得到的是0xe8fb1f0000。嗯,以上是大概思路。具體攻擊流程有三步:
(1)找到call指令後那個被調用函數的地址。
再列一遍這個式子,
0x2000-0x5=0x1ffb
。在這裡0x2000就是被調用函數的地址。總之,一般來說,在javascript環境下,可以利用當然是地址已知的helper函數或built-in函數(比如Math.random,String.substring)。
另外不得不說到IE,它的built-in函數在library中,而且採用了細粒度的ASLR。但是它們所產生的JS對象,未啟用隨機化,而且包含指向這個函數的指針。所以對於IE也是可行的。
(2)把call指令放到指定位置。
再列一遍這個式子,
0x2000-0x5=0x1ffb
。還是假設我們需要的gadget是int 0x80;ret (即0xcd80c3)。
0xcd80c3,包含三個位元組。也就是說,上面那個減法式子的結果必須保證位數滿足要求,要是你的距離才兩位是怎麼也構造不出三位的gadget的。於是為保證三位元組距離,需要創建一個由直接調用語句組成的JS函數,使它在編譯後覆蓋0x100 00 00位元組。即我們要求第一次和最後一次CALL之間的距離,至少為
0x1 00 00 00
位元組指令。(3)檢查機制
還是要說到IE,它在編譯時會隨機插入NOP,所以基本上不能知道函數會被編譯到哪個地址。而且,前提條件存在XnR,我們是不可以通過讀取代碼段來確定那個位置是否是所需要的gadget的。
那麼,只能通過取得足夠大小的代碼空間,全部填滿call指令,從而確保計算結果在距離範圍內。
Javascript中的check address函數會讀棧中數據,直到找到call指令放置的ret,可知是否放置正確。如果沒有,重新編譯,重複之前的步驟。
其他
這攻擊主要針對的是x86 (32- or 64-bit)架構。在RISC架構中,如ARM,MIPS,由於硬體層次的原因,利用上文所述的方法不能成功攻擊。除非在ARM架構下,攻擊者強制切換為16-bit THUMB模式。
另外,雖然論文中作者是以瀏覽器為例,但其實採用jit引擎的東西應該都適用(?)。比如pdf閱讀器是可以的。
總結
實際上本文的核心思想很簡單:
(1)攻擊者通過構造JS代碼產生一個jit-compile gadget
(2)由於所產生的gadget是攻擊者控制的,所以不需要搜索,不需要讀頁,即可被攻擊者用來構造ROP鏈
(3)以上過程發生在運行時
參考文獻
[1] What Cannot Be Read, Cannot Be Leveraged? Revisiting Assumptions of JIT-ROP Defenses. USENIX 2016
[2] Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization. IEEE S&P 2013
*
本文作者:cuteme,轉載請註明FreeBuf*

※NSA的第七種武器|雙脈衝星(DoublePulsar) 後門詳細分析
※一封偽造郵件引發的「探索」(涉及釣魚郵件、SPF和DKIM等)
※OOB(out of band)分析系列之DNS滲漏
※利用系統特性偽裝成一個免密登陸後門
TAG:FreeBuf |
※CYBERGadget將推出Switch用NGC手柄轉換器
※CYBERGadget推出Switch用鍵盤 左右可插入Joy-con
※CYBER GADGET推出能裝於Switch平板的握柄
※VR益智遊戲《Gadgeteer》將於4月23日登陸SteamVR
※看外媒Engadget是如何評價OPPO Reno 10倍變焦版
※OPPO R15國際舞台表現如何?GadgetMatch答案競是這般
※BotHub.AI徐文浩、ZAFUL謝宇嘉、Gigadgets鄭未健、易倉侯楚年:社交營銷不止是獲取流量的手段 更能提高LTV
※Carhartt WIP Gadgets 發布日常配件系列
※亞馬遜為開發者推出Alexa Gadgets Toolkit
※「出行裝備」新鮮人的 Gadget EDC
※一款通過尋找和串聯Gadget來構建ROP漏洞利用的工具
※北美知名科技自媒體GiGadgets獲數百萬美金A+輪融資
※Engadget團隊評測:2018智能手機拍照誰最牛?