作者: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)

復現過程

  1. 通過 USB 連接手機與電腦,并打開 USB 調試。

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

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

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

  5. 構造 HTTP 數據報文,將命令封裝至 Json 數據中,請求 59777 端口;這里演示 getDeviceInfo 命令,可以看到成功返回了設備的信息。

0x03 漏洞分析

反編譯dex文件
對 ES 文件瀏覽器v4.1.9.4 進行分析,首先將該 APK 進行解壓,可以看到其中包含了三個 *.dex 文件。使用 dex2jar 工具分別這三個文件進行反編譯,得到三個 *.jar 文件。

使用 jd-gui 工具加載這三個 jar 文件,使用關鍵詞搜索 59777commandgetDeviceInfo 以快速定位到漏洞邏輯部分,其位于 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:


Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/831/