你們在聚安全挑戰賽正式賽第三題中,遇到android app 遠程控制的題目。咱們今天帶你一探究竟,如何攻破這道題目。html
購物應用pwn (6分)android
環境:web
攻擊過程:chrome
目標:Chrome瀏覽器點擊連接,致使遠程觸發app的購買邏輯,app界面上顯示「購買成功」。shell
評分標準:經過瀏覽器訪問網頁即達到控制app遠程任意代碼執行得6分,其中:json
攻擊流程以下:瀏覽器
其中題目中要求「Chrome瀏覽器點擊連接」,Chrome的官方文檔規定了如何從連接發intent啓功app,官方文檔連接:https://developer.chrome.com/multidevice/android/intents 。反彙編ExamPwn.apk文件發現AndroidManifest.xml中果真有接受相關intent的內容。如圖:安全
類LoginActivity先接受這個intent解析出賬號密碼並匹配,賬號密碼直接以明文硬編碼在類LoginActivity中,反彙編直接能夠看見。匹配正確後將intent中的url丟給類MainActivity。也就是說攻擊者的網頁至少以下:app
反彙編類MainActivity發現,它會把url指向的文件看成特定格式的json解析。根據json內容,它會執行上傳文件和下載解析顯示圖片的任務。不難發現上傳文件的路徑是攻擊者提供的,app沒有檢查是否合法,形成任意文件上傳,信息泄漏的漏洞。此時構造以下json能夠泄漏app的內存地址ide
想要拿到Android app遠程代碼執行權限,漏洞基本只能存在於Dex動態加載邏輯、訪問遠程數據的native代碼中。用工具androguard掃描發現,沒有dex動態加載問題,漏洞只可能在native代碼中。App有native代碼libHt5g.so用於解析和播放gif圖片。漏洞極可能就在其中,反彙編libHt5g.so發現有不少函數都有FrameSequence關鍵詞。實際上就是Google本身的gif顯示庫,2016年12月和2017年1月都曝出過漏洞。
詳情見:
https://source.android.com/intl/us_ALL/security/bulletin/2016-12-01.html
https://source.android.com/intl/us_ALL/security/bulletin/2017-01-01.html
但光看源代碼基本不能利用。因此說出題者應該放了其餘漏洞在裏面。
反彙編看到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個字節是能夠做爲掩蓋目標。到此能夠任意代碼執行了。
因爲以前拿到/proc/self/maps,內存地址都泄露了,這裏說一下咱們的rop方法。
溢出後控制memcpy的dst參數,將準備好的數據拷貝到從/proc/self/maps裏找到的暫時不用的一塊內存。咱們在linker64裏找到兩個gadget
一、修改sp地址到新地址
二、把所在內存修改成可執行
三、跳轉到自定義的可執行內存