作者:0x7F@知道創宇404實驗室
時間:2019.02.27
英文版本:http://www.bjnorthway.com/948/
0x00 前言
ES 文件瀏覽器(ES File Explorer File Manager application)是一款安卓系統上的文件管理器,它支持在手機上瀏覽、管理文件。有超過 1 億次下載量,是目前安卓系統上使用得最廣的文件管理器。
2019年1月,由國外安全研究者公開一個關于 ES 文件瀏覽器的安全漏洞(CVE-2019-6447)。
2月下旬,筆者瀏覽到該漏洞的相關文章,想借此機會學習 APK 逆向,隨即對該漏洞進行了復現分析,結合已公開的分析文章,發現原理非常簡單,下面就來一探究竟吧。
0x01 漏洞概述
ES 文件瀏覽器在運行時會創建一個綁定在 59777 端口的 HTTP 服務,在該服務提供了 10+ 個命令,用于訪問用戶手機的數據以及執行應用程序;但該服務并沒有對請求進行校驗,從而導致出現安全漏洞。
影響范圍
<= ES 文件瀏覽器 v4.1.9.7.4
修復方式
前往應用商城下載最新版即可。修復該漏洞的版本為(v4.1.9.9)
0x02 漏洞復現
漏洞復現環境
- Windows 7
- OPPO R7
- ES 文件瀏覽器v4.1.9.4
- ADB (Android Debug Bridge)
復現過程
-
通過 USB 連接手機與電腦,并打開 USB 調試。

-
通過 ADB 檢查設備連接情況,并安裝 ES 文件瀏覽器v4.1.9.4 到設備上。

-
在手機上可以看到 ES 文件瀏覽器已經安裝成功,啟動該應用;通過 ADB 查看當前網絡端口情況,可以看到 59777 端口已經打開。

-
將手機和電腦配置到同一 WIFI 下,便于我們進行訪問測試。

-
構造 HTTP 數據報文,將命令封裝至 Json 數據中,請求 59777 端口;這里演示
getDeviceInfo命令,可以看到成功返回了設備的信息。
0x03 漏洞分析
反編譯dex文件
對 ES 文件瀏覽器v4.1.9.4 進行分析,首先將該 APK 進行解壓,可以看到其中包含了三個 *.dex 文件。使用 dex2jar 工具分別這三個文件進行反編譯,得到三個 *.jar 文件。

使用 jd-gui 工具加載這三個 jar 文件,使用關鍵詞搜索 59777、command、getDeviceInfo 以快速定位到漏洞邏輯部分,其位于 classes2-dex2jar.jar 下的 com.estrongs.android.f.a 路徑下。

ES HTTP支持的指令
上圖中,可以看到除了 getDeviceInfo 命令,該 HTTP 服務還支持不少的命令:
| command | description |
|---|---|
| listFiles | 列出所有的文件 |
| listPics | 列出所有的圖片 |
| listVideos | 列出所有的視頻 |
| listAudios | 列出所有的音頻 |
| listApps | 列出安裝的應用 |
| listAppsSystem | 列出系統自帶的應用 |
| listAppsPhone | 列出通信相關的應用 |
| listAppsSdcard | 列出安裝在sd卡上的應用 |
| listAppsAll | 列出所有的應用 |
| getAppThumbnail | 列出指定應用的圖標 |
| appLaunch | 啟動制定的應用 |
| appPull | 從設備上下載應用 |
| getDeviceInfo | 獲取系統信息 |
除了以上列出的命令,還可以直接訪問 url+系統文件路徑,直接訪問文件數據:
curl --header "Content-Type: application/json" http://192.168.0.105:59777/etc/wifi_mos.sh

命令執行示例(列出所有的文件):
curl --header "Content-Type: application/json" --request POST --data "{\"command\":\"listFiles\"}" http://192.168.0.105:59777

命令處理
其命令處理部分邏輯大致就是進行相應的邏輯處理,并將執行的結果封裝為 Json 數據格式,拼接為 HTTP 協議進行返回,下面是 getDeviceInfo 的處理邏輯:

通過以上的功能邏輯可以看到,HTTP 服務是 ES 文件瀏覽器的一個內置功能,可能是用于不同設備之間的共享,但由于沒有對請求進行校驗,導致安全問題的出現。
0x04 補丁分析
下載已補丁的版本 v4.1.9.9.3,同樣對 APK 進行解包,通過 dex2jar 反編譯為 *.jar 文件,對文件進行分析。
POST 請求校驗
v4.1.9.9.3 版本可能重新進行了代碼混淆,其反編譯后的機構和 v4.1.9.4 有很大的差別;我們仍然使用關鍵詞搜索來快速定位到之前的漏洞邏輯部分。位于 classes3-dex2jar.jar 下的 es.qg 路徑下。

從上圖可以看到,標注地方是新版本所添加的補丁,在處理請求時,首先進行檢查,檢查失敗的情況下返回 400 錯誤。
跟入 ap.d() 函數中,可以看到兩個關鍵檢查函數:
1.檢查函數1

該函數獲取了 UIModeManager 對象,當該對象的類型等于 4 時,返回 true,通過查閱官方文檔,在該處數值 4 對應的類型為 UI_MODE_TYPE_TELEVISION,也就是安卓TV的類型。說明官方將該功能限制在安卓TV的設備上了。
2.檢查函數2

檢查函數2依然是對安卓TV的判斷,在上一步函數獲取了屏幕的尺寸并轉換成了一個值,在該處判斷值要大于 20,才能返回 true。
Android TV會受到威脅?
根據以上補丁的情況來看,可以猜測到 Android TV 似乎受到該漏洞的威脅,但實際上并不會。因為 Android TV 處理流程和手機版的不同,本身也不受該漏洞的影響。
將有漏洞的版本(v4.1.9.4)安裝至 Android TV 上;經過測試可以發現,在 Android TV 下發起請求將直接返回 500 錯誤。

原因是程序在判斷設備是 TV 時,會首先提前做一次來源 IP 檢查(判斷是否由是本地發起的請求,檢查失敗也返回 500 錯誤),隨后再檢查可訪問的路徑,如下函數(classes3-dex2jar.jar/es.qj$a):

但經過測試,發現該數組的值為 NULL,直接返回 false

最終跳轉至該語句,返回 500 錯誤。所以 Android TV 也不會受到該漏洞的影響。
Get請求列目錄修復
在上文中還提到發送 GET 請求可以列文件,在新版本也進行了修復。

當以 GET 方式發起請求時,將進入 ai.bK() 的函數判斷,在該函數中檢查了 HTTP 的數據必須以 http://127.0.0.1: 開頭,才可以返回文件列表;HTTP 協議都是以 GET/POST/... 開頭,肯定不會以這個方式開頭,雖然不太理解這個檢查,但還算是解決了列目錄的問題。
0x05 總結
通過以上的分析,可以完整的了解到 ES 文件瀏覽器安全漏洞的觸發過程以及補丁情況;整體看來就是,開發者在設計共享訪問功能的時候忽略對請求的檢查,從而導致的安全漏洞。
References:
- Github: https://github.com/fs0c131y/ESFileExplorerOpenPortVuln
- Twitter: https://twitter.com/fs0c131y/status/1085460755313508352
- techcrunch: https://techcrunch.com/2019/01/16/android-app-es-file-explorer-expose-data/
- Freebuf: https://www.freebuf.com/vuls/195069.html
- smwenku: https://www.smwenku.com/a/5c45ee68bd9eee35b21ef1db/zh-cn
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/831/