阿里聚安全攻防挑戰賽第三題Android PwnMe解題思路

pengaiying 7年前發布 | 8K 次閱讀 阿里巴巴 Android開發 移動開發

大家在聚安全挑戰賽正式賽第三題中,遇到android app 遠程控制的題目。我們今天帶你一探究竟,如何攻破這道題目。

一、題目

購物應用pwn (6分)

環境:

- 要求在ARM 64位Android手機上攻擊成功,也可在模擬器(運行Google官方Android SDK提供的Google APIs ARM64 Android 7.0鏡像)中攻擊成功,其中鏡像會打包提供,參見題目下載鏈接。模擬器執行命令參考如下:(qemu-system-aarch64 -sysdir . -datadir . -kernel kernel-qemu -system system.img -ramdisk ramdisk.img -data userdata.img)

- 包含bug的apk一個

- 必須在非root環境

攻擊過程:

- 將apk裝入模擬器中。

- 打開chrome瀏覽器,訪問選手的惡意網頁的地址。(web服務由選手自己搭建)

- 通過選手的惡意網頁,即可獲取此app的shell。

- apk顯示“購買成功”

目標:Chrome瀏覽器點擊鏈接,導致遠程觸發app的購買邏輯,app界面上顯示“購買成功”。

評分標準: 通過瀏覽器訪問網頁即達到控制app遠程任意代碼執行得6分, 其中:

1. 反彈shell控制app ,5分。

2. 能夠進一步讓app界面顯示“購買成功”分數進一步得1分 。

3. 需提供遠程任意代碼執行的利用程序源代碼。

二、解題思路

攻擊流程如下:

1. Android Intents with Chrome 

其中題目中要求“Chrome瀏覽器點擊鏈接”,Chrome的官方文檔規定了如何從鏈接發intent啟功app,官方文檔鏈接: https://developer.chrome.com/multidevice/android/intents 。反匯編ExamPwn.apk文件發現AndroidManifest.xml中果然有接受相關intent的內容。如圖:

類LoginActivity先接受這個intent解析出帳號密碼并匹配,帳號密碼直接以明文硬編碼在類LoginActivity中,反匯編直接可以看見。匹配正確后將intent中的url丟給類MainActivity。也就是說攻擊者的網頁至少如下:

2.info leak

反匯編類MainActivity發現,它會把url指向的文件當作特定格式的json解析。根據json內容,它會執行上傳文件和下載解析顯示圖片的任務。不難發現上傳文件的路徑是攻擊者提供的,app沒有檢查是否合法,造成任意文件上傳,信息泄漏的漏洞。此時構造如下json可以泄漏app的內存地址

3. code exec

想要拿到Android app遠程代碼執行權限,漏洞基本只能存在于Dex動態加載邏輯、訪問遠程數據的native代碼中。用工具androguard掃描發現,沒有dex動態加載問題,漏洞只可能在native代碼中。App有native代碼libHt5g.so用于解析和播放gif圖片。漏洞很可能就在其中,反匯編libHt5g.so發現有很多函數都有FrameSequence關鍵詞。實際上就是Google自己的gif顯示庫,2016年12月和2017年1月都曝出過漏洞。

但光看源代碼基本不能利用。所以說出題者應該放了其他漏洞在里面。

反匯編看到private static native long nativeGetFrame(long j, int i, Bitmap bitmap, int i2);的時候可以發現,當gif一幀的大小小于等于1024字節的時候,buffer是分配在stack上然后再memcpy到原來的bitmap buffer中。不僅多此一舉而且跟源代碼不一致,基本確定出題者準備的是棧溢出。

到此為止如果還沒有發現有源代碼可以自己編譯然后binary diff的話,可以自己構造小于1024字節的gif,然后逐個字節替換為0xff,最快幾十字節改就會發現crash,分析后發現Gif格式中,一幀圖片的Left變量被當成負數處理了,無符號整數被當作有符號整數處理。而知道用binary diff的同學基本直接可以定位到出題者修改的所有地方,包括解析Left出錯的地方。

光看源代碼基本不能利用是因為bitmap是RGBA格式,RGB可以控制,而Alpha在源代碼里直接被0xff填充,意為不透明。這樣的話溢出的數據基本很難控制。所以作為出題者的我們按照gif格式添加了tag為0x77的ExtentionBlock,里面存放的數據作為Alpha值。這樣就能完全控制溢出的數據了。

由于Left變成了負數,造成了向低地址的任意數據的棧溢出。

受影響匯編代碼

可以看到此函數在棧上申請了0x480大小的字節。其中處于高地址的0x400(1024)個字節是將被溢出的buffer,處于低地址的0x80個字節是可以作為掩蓋目標。到此可以任意代碼執行了。

4.rop

由于之前拿到/proc/self/maps,內存地址都泄露了,這里說一下我們的rop方法。

溢出后控制memcpy的dst參數,將準備好的數據拷貝到從/proc/self/maps里找到的暫時不用的一塊內存。我們在linker64里找到兩個gadget

1、修改sp地址到新地址

2、把所在內存修改為可執行

3、跳轉到自定義的可執行內存

 

來自:http://jaq.alibaba.com/community/art/show?articleid=713

 

 本文由用戶 pengaiying 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!