科技

ES檔案瀏覽器CVE-2019-6447漏洞分析

漏洞名稱ES File Explorer Open Port Vulnerability - CVE-2019-6447

漏洞簡介ES檔案瀏覽器在啟動時建立了一個HTTP伺服器,在本地打開了59777埠。攻擊者通過構造指定的payload可以獲取使用者手機檔案,安裝apk等操作。

影響範圍4.1.9.7.4 and below(部分版本可能不支援,也可能和應用市場有關)

漏洞分析從fs0c131y所給出的資訊來說CVE-2019-6447影響的ES應用版本為4.1.9.7.4以下,但是在某些版本的應用該漏洞卻無法利用,例如從華為和google play商店下載的ES就無法順利復現該漏洞,向59777埠傳送payload一直會回覆500 ERROR報錯,下面將詳細對該漏洞進行分析。

4.1.9.4版本應用分析以下是選擇了4.1.9.4版本的ES檔案瀏覽器進行了分析,該版本ES能夠成功利用該漏洞。

首先對APK解包後發現存在三個DEX檔案。

先簡單看了下lib中的庫發現應用沒有加殼,用grep篩查以下59777確定相關程式碼可能在classes2.dex中。

把classses2.dex反編譯後,全域性搜尋command發現存在漏洞的類在com/estrongs/android/f/a之中,而觸發漏洞的函式為com/estrongs/android/f/a.a。

簡單看下來a.class,b.class,c.class可能都和該漏洞的服務相關,其中a.class繼承了c.class。

下面來看下整個漏洞的觸發過程,由於混淆程式碼不管是丟進jeb中還是smali閱讀起來都比較費力,為此我們可以先動態的將程式跑一邊後記錄trace,分析android trace檔案來檢視函式呼叫棧(利用TraceReader讀取)。

記錄trace的方法如下:

在DDMS上成功開啟Trace之後,我們就要去構造payload去觸發該漏洞,漏洞具體利用payload見github(https://github.com/fs0c131y/ESFileExplorerOpenPortVuln)。

curl --header "Content-Type: application/json" --request POST --data "" http://192.168.13 7.10:59777 -vvv把tracer檔案丟到TraceReader檢視呼叫棧,可以發現程式進入com/estrongs/android/f/c$a.runV來處理了我們的請求,注意這裡的類的例項化物件其實是a.class而不是c.class。:

首先接受socket然後讀到buffer中提取資料

然後判斷是不是post資料,如果是post請求則對content-type進行解析,當所有的前置解析完成後最後程式會來到label_189處

label189中,執行了v27 = this.a.aparseurlotherdata(v9, v10, v11, v6, v7);來進一步解析並執行相應的command。

這裡有一個問題,如果JEB直接雙擊來跟蹤函式會跳轉到自己類中的函式,而實際真正呼叫的是a.class(com/com/estrongs/android/f/a)中的函式aparseurlotherdata(這裡我對混淆函式名重新命名了實際上原本的函式名是a)。

下圖是JEB錯誤跳轉到函式的位置,實際上我們應該分析的是a.class中的aparseurlotherdata:

繼續追蹤下去來到就來到了我們一開始漏洞觸發的地方(com/estrongs/android/f/a.a):

關於這個地方的分析其實有很多文章以及做過了,這裡就不再過多提及了。

解析對應的command呼叫對應的功能函式後返回json:

最後進入com/estrongs/android/f/c$a.a(Ljava/lang/String;Ljava/lang/String;Ljava/util/Properties;Ljava/io/InputStream;)V將response寫回。

該函式將輸出的結果寫入到OutputStream中然後將其返回。該ES版本整個漏洞的觸發流程大致就如上所示。

這裡有一個需要注意的地方,如果是不存在漏洞的ES應用v2_7是為null的也就會進入this.a("500 Internal Server Error", "SERVER INTERNAL ERROR: Serve returned a null response.");中,這也是很多應用市場上的ES應用都會到報500錯誤的原因。

4.1.6.6.1版本應用分析以下將對4.1.6.6.1版本ES檔案管理器進行分析,該版本的ES檔案管理器沒有順利觸發漏洞。

直接curl個看看,500報錯了。

拆包靜態看一遍,程式碼基本上還是在f包中,但是多了很多其他的類,a.class依然是ESHttpServer實現的地方。

再curl一個包抓取一下呼叫棧。

curl --header "Content-Type: application/json" --request POST --data "" http://192.168.0\. 122:59777 -vvv

錯略比對發現在這個版本的ES中多了一些函式,可能是做了某一些的校驗邏輯。

靜態分析程式碼,發現前面的邏輯和之前app差不多,但是在執行完com.estrongs.android.f.h.a(Ljava/lang/String;Ljava/util/Properties;)V後又呼叫了bJ。

跟入bJ,bJ驗證了了url並且ap.a方法檢測當前環境是否處於WIFI環境下。

繼續往下跟蹤,我們來到問題點!bp.q || !f.e(v8)) && !f.a(v8, v25)這裡返回了true導致flagobject為null值所以伺服器返回了500。

bq.q為true或者f.e以及f.a為true才能進入邏輯

跟蹤進入bq.q,要滿足bp.p和cw.e都為true。

而FexApplication.a.getSystemService("uimode").getCurrentModeType == 4成立的時候bp.p才能為true,根據官方文件4的uimode為UIMODETYPE_TELEVISION。

在cw.e中需要滿足一定的介面長寬需求

boolean v0_1 = Math.sqrt(Math.pow((((double)v0.heightPixels)) * 1 / (((double)v0.densityDpi)), 2) + Math.pow((((double)v0.widthPixels)) * 1 / (((double)v0.densityDpi)), 2)) >= 20 ? true : false;

而另外的f.e(v8),f.a(v8, v2_5)函式則負責校驗了我們的ip。

此外存在另外一種情況是當我們的ip為127.0.0.1時候flag_object能不為null,但首先你要滿足v4=null這個先覺條件。

檢視v4 = as.bJ(v9),之前已經說過bJ函式負責校驗了url,我們再重新回到bJ發現return null好像不太可能,v9不管uri如何構造都會以'/'開始。

也就是說在應用市場上的ES版本不管是走if((!bp.q || !f.e(v8)) && !f.a(v8, v25))還是走if(v4 != null && as.I(v4) != 0)似乎都不能出發到flagobject = v8_1.a(v9, v10, v11, v6, v7)的邏輯,這樣該漏洞就沒法觸發,但說不定還有其他的繞過方法,希望大家能夠多多補充。

參考資料

Reference:科技日報

看更多!請加入我們的粉絲團

轉載請附文章網址

不可錯過的話題