“水滴”來襲:詳解Binder核心通殺漏洞

360安全衛士發表於2019-03-06


作者:韓洪立 (@hexb1n) – 360 C0RE Team


Binder基於OpenBinder來實現,是Android系統的重要組成部分。Binder構建於Linux核心中的Binder驅動之上,系統中涉及到Binder通訊的部分,都需要透過與”/dev/binder”的裝置驅動互動來實現資料傳遞。由於Binder驅動在整個Android系統中發揮的重要作用,所以一直以來也是Android安全研究的重點之一。


在二進位制的世界裡,物件的生成和銷燬都有一定的流程和時間點,有一些是在編譯器層面來實現,有一些卻需要程式設計者來維護。一旦這個流程設計的不夠完美,使得攻擊者能夠透過非法操作擾亂其正常的生命週期便有可能造成一系列的安全問題。去年8月份我在對Binder驅動程式碼進行安全審計的時候,發現了一枚如同《三體》中“水滴”一般的核心通殺漏洞,擁有了驚人的破壞力,僅用一個漏洞便可以實現任意地址讀、任意地址寫、寫任意內容、資訊洩露。同時,Binder驅動也是目前為數不多的幾個可被沙箱中的程式訪問的驅動之一,該漏洞可能被用於沙箱逃逸。在如此重要的核心驅動中會潛伏這樣一枚通殺漏洞堪稱神奇。


基於這個漏洞,我們實現了對Pixel全系手機的ROOT,其中的Pixel 3也代表了谷歌安卓核心目前最高的安全防禦水平,這也是Pixel 3自問世以來,全球範圍內首次公開的ROOT攻擊。這裡要感謝@周明建@王曉東@姚俊@邵大成等團隊小夥伴的支援,讓漏洞利用能夠及早的完成,文末也附了我們的提權影片連結[1]。


這個漏洞在2019年3月的Android SecurityBulletin中已經公開,對應的漏洞編號為CVE-2019-2025。下文我將會介紹該漏洞危害、影響範圍、漏洞原理以及利用思路。


  • 漏洞危害及影響範圍


漏洞危害

1)  通殺。目前國內外主流的Android機型基本都會受到影響;

2)  攻擊能力極強。該漏洞可實現較穩定的任意地址讀寫、寫任意內容、資訊洩露,並且每觸發一次漏洞便可以任意寫一次、讀一次,Google現有的核心安全緩解措施對於這類能夠任意地址讀寫的漏洞暫無有效的防禦策略;

3)  沙箱逃逸。可能用於沙箱逃逸,並直接提權到ROOT;

同時,Binder驅動已早在2015年初被合入Linux主線,使用了Binder模組的平臺均有可能受到影響。


影響範圍

該漏洞屬於use-after-free問題,觸發時需要不同執行緒間同步競爭呼叫”binder_ioctl()”,而在早期的設計中,”binder_ioctl()”由一個效率較低的全域性互斥鎖保護,見圖1。


“水滴”來襲:詳解Binder核心通殺漏洞

圖1


而此問題後續被最佳化,從”drivers/android/binder.c”的commit日誌可以看到,2016年11月14日的一個補丁將這個全域性互斥鎖去掉,並最佳化為更加細粒度的互斥鎖來保護,見圖2。完整的補丁可參見連結[2]。


“水滴”來襲:詳解Binder核心通殺漏洞

圖2


打上這個補丁的核心原始碼便可能受到該漏洞的影響。由於該漏洞具備通殺能力,目前市面上主流在用的2016年11月之後的核心版本多數都會受到影響,在修補該問題之前將會有大量的裝置處於安全風險之中。成功ROOT後攻擊者可以獲得系統的最高許可權,同時該漏洞可能被用於遠端攻擊鏈,若是被黑產利用將可直接對使用者的個人隱私、財產安全甚至人身安全造成嚴重的危害。目前Linux主線上已提供了針對該漏洞的補丁,Android廠商可參考附註連結[3]及時修補。


  • 漏洞的成因


基礎知識

關於Binder機制這裡就不做過多介紹了,接觸過Android的同學應該對它或多或少都有一定的瞭解。理解該漏洞需熟悉透過Binder通訊的雙方的基本互動流程,以及中間用到一些結構體物件,網路上關於Binder的資料非常豐富,可自行補充。


漏洞原理

當使用者程式透過呼叫”IPCThreadState::transact()”向server程式請求資料時,server程式會呼叫”IPCThreadState::sendReply()”向使用者程式回傳資料以作為響應。在這個過程中,server程式會陷入核心,並呼叫“binder_alloc_new_buf()”從使用者程式(“target_proc->alloc”)對應的”alloc->free_buffers.rb_node”紅黑樹中申請一個”struct binder_buffer”型別的物件,被申請得到的物件會從”alloc->free_buffers.rb_node”紅黑樹中移除,並鏈入到 ”alloc->allocated_buffers.rb_node” 紅黑樹中進行維護,此後將”t->buffer->allow_user_free”賦值為0,以避免”t->buffer”在使用過程中被釋放,見圖3。


“水滴”來襲:詳解Binder核心通殺漏洞

圖3


使用者程式擁有對該”t->buffer”的釋放權,不過要在使用者程式收到了server程式發來的訊息,結束本次互動並銷燬所用的Parcel物件時。然而,我們可以試圖透過主動向核心傳送”BC_FREE_BUFFER”請求來提前釋放該”t->buffer”物件,不過這需要滿足核心對各項引數的校驗,如圖4所示。


“水滴”來襲:詳解Binder核心通殺漏洞
圖4

上文中提到的“t->buffer”可以透過向核心傳入對應的“data_ptr”值,再透過呼叫“binder_alloc_prepare_to_free()”函式來找到,其返回值會賦值給”buffer”,緊接著核心會檢查“buffer->allow_user_free”以及”buffer->transaction”的合法性,由於缺少互斥鎖的保護,這裡存在一個條件競爭問題,如果使用者程式能在圖3中”t->buffer->allow_user_free”被賦值為0之前觸發到“binder_alloc_free_buf()->binder_free_buf_locked()->rb_erase()”, 便有可能將其從”alloc->buffers”中移除,見圖5。


“水滴”來襲:詳解Binder核心通殺漏洞

圖5


之後便可再選擇合適時機觸發”kfree()”將其釋放,而此時當server程式繼續使用”t->buffer”時便觸發了use-after-free問題。這樣我們就可以藉助堆噴技術來實現任意地址讀寫以及資訊洩露。


  • 漏洞利用


核心中每年公開的漏洞數量都多達數百個,但真正能夠成功提權的寥寥無幾。而近年來隨著系統防護的不斷完善,此前一些可以用來ROOT的漏洞,如果處在現有的防護機制下也變的無能為力。在Android的通用模組出現這類具備了任意地址讀寫、資訊洩露能力,同時還可能用於沙箱逃逸的漏洞十分少見。即便隨著Android系統後續一些新的防護機制引入,這類漏洞仍有可能具備很強的攻擊潛力。由於漏洞的特點,攻擊手法也是仁者見仁智者見智,我們也做出來幾種不同的利用方案,這裡會介紹漏洞利用的基本思路,具體的細節這裡不會放出。


任意地址寫

呼叫合適的堆噴函式去佔位該”t->buffer”物件,堆噴成功後,圖3中3178行所示的”t->buffer->data”可由攻擊者完全控制,而”tr->data.ptr.buffer”是server程式發給使用者程式的reply資料,可由攻擊者間接控制。當“copy_from_user()”函式被執行時,便觸發了任意地址寫問題。


任意地址讀

server程式此後又會呼叫“binder_enqueue_thread_work_ilocked()”函式向使用者程式傳送訊息,如圖6中3377行所示。


“水滴”來襲:詳解Binder核心通殺漏洞

圖6


與此同時,使用者端程式在迴圈呼叫“IPCThreadState::talkWithDriver()”等待server程式的響應。當有訊息到達時,核心會透過呼叫圖7中4100,4107行所示函式,將server程式傳送過來的“struct binder_transaction”型別的物件取出,並儲存在變數”t”中,其中“t->buffer”是被我們控制的惡意物件,而”target_node”是”struct binder_buffer”結構體的一個成員變數,若將其設定為非空值,將會被當成”struct binder_node”型別的指標,並從該指標加0x58、0x5c位置取值賦值給”tr.target.ptr”及”tr.cookie”。此後核心再呼叫4319行所示的”copy_to_user()”將資料傳遞給使用者程式。透過這一機制我們便可以實現任意地址讀。


“水滴”來襲:詳解Binder核心通殺漏洞

圖7


資訊洩露

透過尋找一些帶有敏感資訊的結構體對”t->buffer”進行堆噴,“t->buffer->target_node”,“t->buffer->data_size”, “t->buffer->data”都將作為資訊洩漏點,將堆噴結構體中的敏感資料洩露給使用者程式。


  • 時間節點


2018.08 發現並確認漏洞危害及影響範圍;
2018.09.28 將漏洞發現上報給Google;
2018.10.06 Google回覆郵件,進一步確認漏洞細節;
2018.10.23 Google確認該問題;
2018.11.02 提交漏洞利用給Google;
2018.11.06 Linux Kernal 主線上修復該問題;
2018.12.18 告知漏洞公開時間,並多次在郵件中致謝;
2019.03.05 安全公告,漏洞編號為CVE-2019-2025;

我們是全球首個發現該漏洞並提交至Google的安全團隊,同時由於漏洞本身的嚴重性,並且我們成功利用這一漏洞繞過了代表谷歌安卓目前最高水平的核心防護機制,完成了針對Google旗下三款Pixel系列機型的完美ROOT,也收到了Google誠摯的致謝。


“水滴”來襲:詳解Binder核心通殺漏洞
 

  • 總結


漏洞在原理上擁有極強的攻擊能力,但在實際利用過程中還是有一定的門檻,需要非常熟悉漏洞利用技巧及核心的相關知識才能將其穩定的利用,我們在Pixel系列裝置上能夠實現近100%的漏洞觸發成功率。在Android系統安全防護日臻健全的時代,這類通殺漏洞更是具備了稀缺性,也是黑產從業者夢寐以求的,安全研究人員如果不能趕在他們之前發現並修補該漏洞,一旦被黑產從業者掌握並大規模利用,造成的損失將難以估計。各家Android廠商也需儘快修復該問題,避免使用者暴露在安全風險之中。 

  • 參考


[1]https://weibo.com/tv/v/HaeCNbLmz?fid=1034:4324393006868015

[2]https://lore.kernel.org/patchwork/patch/805040/

[3]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7bada55ab50697861eee6bb7d60b41e68a961a9c


相關文章