Janus 二元神漏洞测试

同步发表于:http://blog.hacktons.cn/2017/12/25/janus-demo/
背景
12月9号,Andorid对外曝光了一个名为Janus的重量级系统漏洞CVE-2017-13156), 由安全研究公司Guard Square发现。
Janus原意是神话中的二元身,用于描述这个漏洞还真是贴切。

整个漏洞其实建立在文件校验规则之上:
一个文件即是APK,又是DEX,在安装APK和执行阶段的校验规则差异,导致可以在APK头部附加一个恶意DEX来欺骗系统
下面我们从市场上随意下载一个apk来做测试。
测试APK
本文涉及的测试APK,只用于单击研究之用,请勿恶意散播或上传,由此引发的纠纷与作者无关
可以从豌豆荚,应用宝等市场下一个测试用的APK,为了方便,我们需要选用一些体积较小的apk,如果apk较大很有可能经过了分包,替换工作会麻烦点。

这里比较恶心的是,下载到的apk并不是我们选取的安装包,而是豌豆荚市场,既然豌豆荚这么强势要入镜,那么姑且直接分析豌豆荚市场吧。

MD5 (Wandoujia_224660_web_inner_referral_binded.apk) = d3c1d9b2a74a3f8fd9fce38d38423c58
签名检查
首先检查下豌豆荚的这个apk是不是v2签名的,因为我们要测试的Janus只能在v1下验证
检查签名信息可以通过*.SF来确认,根据公开信息,如果v2签名的话,会在SF文件内写入一个字段 X-Android-APK-Signed:2;
豌豆荚的SF文件名字是META-INF/DEAMON2.SF, 比较幸运啊,可以确认其使用的就是v1签名。
aven$ unzip -l Wandoujia_224660_web_inner_referral_binded.apk |grep META-INF
120009 12-15-17 14:38 META-INF/MANIFEST.MF
120130 12-15-17 14:38 META-INF/DEAMON2.SF
891 12-15-17 14:38 META-INF/DEAMON2.RSA
aven$ unzip -p Wandoujia_224660_web_inner_referral_binded.apk META-INF/DEAMON2.SF|less
Signature-Version: 1.0
SHA1-Digest-Manifest-Main-Attributes: jq/6qzaCk3O+H4OBJsDhMXm+FvE=
Created-By: 1.6.0_30 (Sun Microsystems Inc.)
SHA1-Digest-Manifest: Dts4zfEM9pZstNDahVfVh4e4jGA=
Name: res/drawable-xhdpi-v4/il.png
SHA1-Digest: QCves3Cr/wm3X2w4PR4ESXGMBOw=
Name: res/layout/dh.xml
SHA1-Digest: DCuKb0PRLuNV6jTEbSDGMTEW174=
包名确认
接下来我们需要构造一个新的dex,嫁接到豌豆荚的apk前面;这里需要确认豌豆荚使用的包名:com.wandoujia.phoenix2
package: name='com.wandoujia.phoenix2' versionCode='16861' versionName='5.68.21'
sdkVersion:'14'
targetSdkVersion:'16'
另外值得一提的是,豌豆荚的权限还是比较流氓的会要求大量敏感权限,因此在使用该市场的时候注意权限的问题,否则很有可能裸奔了:
比如读/写短信,读/写通讯录等等,还有一些第三方权限
uses-permission:'android.permission.READ_SMS'
uses-permission:'android.permission.RECEIVE_SMS'
uses-permission:'android.permission.MANAGE_ACCOUNTS'
uses-permission:'android.permission.AUTHENTICATE_ACCOUNTS'
uses-permission:'android.permission.USE_CREDENTIALS'
uses-permission:'android.permission.READ_SETTINGS'
uses-permission:'android.permission.READ_EXTERNAL_STORAGE'
uses-permission:'android.permission.SEND_SMS'
uses-permission:'android.permission.WRITE_EXTERNAL_STORAGE'
uses-permission:'android.permission.MOUNT_UNMOUNT_FILESYSTEMS'
uses-permission:'android.permission.INTERNET'
uses-permission:'android.permission.ACCESS_NETWORK_STATE'
uses-permission:'android.permission.ACCESS_WIFI_STATE'
uses-permission:'android.permission.CHANGE_WIFI_STATE'
uses-permission:'android.permission.CHANGE_WIFI_MULTICAST_STATE'
uses-permission:'android.permission.SET_WALLPAPER'
uses-permission:'android.permission.SET_WALLPAPER_HINTS'
uses-permission:'android.permission.WRITE_SETTINGS'
uses-permission:'android.permission.CAMERA'
uses-permission:'android.permission.FLASHLIGHT'
uses-permission:'com.android.launcher.permission.INSTALL_SHORTCUT'
uses-permission:'com.android.launcher.permission.UNINSTALL_SHORTCUT'
uses-permission:'android.permission.READ_PHONE_STATE'
uses-permission:'android.permission.MODIFY_AUDIO_SETTINGS'
uses-permission:'android.permission.SYSTEM_ALERT_WINDOW'
uses-permission:'android.permission.ACCESS_SUPPERUSER'
uses-permission:'android.permission.GET_PACKAGE_SIZE'
uses-permission:'android.permission.KILL_BACKGROUND_PROCESSES'
uses-permission:'android.permission.CLEAR_APP_CACHE'
uses-permission:'android.permission.DISABLE_KEYGUARD'
uses-permission:'com.android.launcher.permission.READ_SETTINGS'
uses-permission:'com.android.launcher.permission.WRITE_SETTINGS'
uses-permission:'com.android.launcher3.permission.READ_SETTINGS'
uses-permission:'com.android.launcher3.permission.WRITE_SETTINGS'
uses-permission:'com.meizu.flyme.launcher.permission.READ_SETTINGS'
uses-permission:'com.meizu.flyme.launcher.permission.WRITE_SETTINGS'
uses-permission:'org.adw.launcher.permission.READ_SETTINGS'
uses-permission:'org.adw.launcher.permission.WRITE_SETTINGS'
uses-permission:'com.qihoo360.launcher.permission.READ_SETTINGS'
uses-permission:'com.qihoo360.launcher.permission.WRITE_SETTINGS'
uses-permission:'com.lge.launcher.permission.READ_SETTINGS'
uses-permission:'com.lge.launcher.permission.WRITE_SETTINGS'
uses-permission:'net.qihoo.launcher.permission.READ_SETTINGS'
uses-permission:'net.qihoo.launcher.permission.WRITE_SETTINGS'
uses-permission:'org.adwfreak.launcher.permission.READ_SETTINGS'
uses-permission:'org.adwfreak.launcher.permission.WRITE_SETTINGS'
uses-permission:'com.huawei.launcher3.permission.READ_SETTINGS'
uses-permission:'com.huawei.launcher3.permission.WRITE_SETTINGS'
uses-permission:'com.fede.launcher.permission.READ_SETTINGS'
uses-permission:'com.fede.launcher.permission.WRITE_SETTINGS'
uses-permission:'com.sec.android.app.twlauncher.settings.READ_SETTINGS'
uses-permission:'com.sec.android.app.twlauncher.settings.WRITE_SETTINGS'
uses-permission:'com.anddoes.launcher.permission.READ_SETTINGS'
uses-permission:'com.anddoes.launcher.permission.WRITE_SETTINGS'
uses-permission:'com.lenovo.launcher.permission.READ_SETTINGS'
uses-permission:'com.lenovo.launcher.permission.WRITE_SETTINGS'
uses-permission:'com.google.android.launcher.permission.READ_SETTINGS'
uses-permission:'com.google.android.launcher.permission.WRITE_SETTINGS'
uses-permission:'com.oppo.launcher.permission.WRITE_SETTINGS'
uses-permission:'com.oppo.launcher.permission.READ_SETTINGS'
uses-permission:'com.yulong.android.launcher3.permission.WRITE_SETTINGS'
uses-permission:'com.yulong.android.launcher3.permission.READ_SETTINGS'
uses-permission:'com.huawei.android.launcher.permission.READ_SETTINGS'
uses-permission:'com.huawei.android.launcher.permission.WRITE_SETTINGS'
uses-permission:'com.htc.launcher.permission.READ_SETTINGS'
uses-permission:'com.htc.launcher.permission.WRITE_SETTINGS'
uses-permission:'com.bbk.launcher2.permission.READ_SETTINGS'
uses-permission:'com.bbk.launcher2.permission.WRITE_SETTINGS'
uses-permission:'android.permission.WAKE_LOCK'
uses-permission:'android.permission.BROADCAST_PACKAGE_ADDED'
uses-permission:'android.permission.BROADCAST_PACKAGE_CHANGED'
uses-permission:'android.permission.BROADCAST_PACKAGE_INSTALL'
uses-permission:'android.permission.BROADCAST_PACKAGE_REPLACED'
uses-permission:'android.permission.RESTART_PACKAGES'
uses-permission:'android.permission.GET_TASKS'
uses-permission:'android.permission.RECEIVE_BOOT_COMPLETED'
uses-permission:'android.permission.CHANGE_NETWORK_STATE'
uses-permission:'android.permission.GET_ACCOUNTS'
uses-permission:'android.permission.VIBRATE'
uses-permission:'android.permission.BIND_ACCESSIBILITY_SERVICE'
uses-permission:'android.permission.READ_CONTACTS'
uses-permission:'android.permission.WRITE_CONTACTS'
uses-permission:'android.permission.CALL_PHONE'
uses-permission:'android.permission.WRITE_SMS'
uses-permission:'android.permission.WRITE_CALL_LOG'
uses-permission:'android.permission.READ_CALL_LOG'
uses-permission:'android.permission.AUTHENTICATE_ACCOUNTS'
uses-permission:'android.permission.WRITE_SYNC_SETTINGS'
uses-permission:'android.permission.MANAGE_ACCOUNTS'
uses-permission:'android.permission.ACCESS_FINE_LOCATION'
uses-permission:'android.permission.ACCESS_COARSE_LOCATION'
uses-permission:'com.wandoujia.phoenix2.permission.MIPUSH_RECEIVE'
uses-permission:'android.permission.PACKAGE_USAGE_STATS'
uses-permission:'android.permission.PERSISTENT_ACTIVITY'
uses-permission:'android.permission.ACCESS_MTK_MMHW'
Hack
接下来开始编码工作,明确下我们的目标:
- 替换Application,并且在app进程启动时弹出一个toast;
- 替换启动页,显示一个特殊文案;
因此首先安确认下豌豆荚的自定义application:com.pp.assistant.PPApplication。
aven$ aapt dump xmltree Wandoujia_224660_web_inner_referral_binded.apk AndroidManifest.xml|less
E: application (line=155)
A: android:theme(0x01010000)=@0x7f0a0001
A: android:label(0x01010001)=@0x7f0c038a
A: android:icon(0x01010002)=@0x7f02009d
A: android:name(0x01010003)="com.pp.assistant.PPApplication" (Raw: "com.pp.assistant.PPApplication")
A: android:stateNotNeeded(0x01010016)=(type 0x12)0xffffffff
A: android:windowSoftInputMode(0x0101022b)=(type 0x11)0x3
A: android:allowBackup(0x01010280)=(type 0x12)0xffffffff
创建同名的PPApplication的,然后加上toast即可,接下来编译得到新的apk,并将其中的dex抽离出来备用。
插曲
在实际插入dex的时候,遇到了一些小插曲,比如插入完后,启动崩溃,所以如果是插入全新的dex的话,需要确认和原有dex的关系,如果完全摒弃原有逻辑,那么需要手动补全manifest中声明的ContentProvider和BroadcastReceiver,Activity根据需要替换,Service可选替换
另外合并apk和dex不是简单的字节叠加,需要修改最终apk的偏移量,确保zip的正确性。笔者使用的是一个Python脚本
https://github.com/V-E-O/PoC/tree/master/CVE-2017-13156
效果
搞定之后,可以直接安装apk,也可以覆盖升级安装,接下来启动app就可以看到完全不同的效果;
在这里我们出于实验性质,将豌豆荚市场的application和启动Activity做了整体替换,因此直接感受就是原有逻辑全部没有了,如果我们通过反编译后增量修改的方式来新增dex,纳闷可以实现和原app功能几乎一致的串改,这样可以恶意插入代码,同时不容易被用户发现。

修复
这个bug看起来挺严重的,不过实际上影响有限,如果用户通过正规市场下载程序基本没什么问题,同时Android官方已经做fix,相信后续很快就会在新版本中生效。
对于开发者来说比较被动,最好升级签名为V2,别的就没有屏蔽办法了,比较问题出在系统校验上面。
Janus 二元神漏洞测试的更多相关文章
- kali上部署dvwa漏洞测试平台
kali上部署dvwa漏洞测试平台 一.获取dvwa安装包并解压 二.赋予dvwa文件夹相应权限 三.配置Mysql数据库 四.启动apache2和mysql服务 五.在网页配置dvwa 六.登陆到D ...
- ThinkPHP5.0 漏洞测试
ThinkPHP5.0 漏洞测试 自从ThinkPHP发布漏洞补丁以来,服务器不知道多少次受到了批量扫描漏洞来抓取肉鸡的请求 虽然官方早已发布补丁,还是想试一下TP漏洞,测试两个漏洞 一.全版本执行漏 ...
- SPF邮件伪造漏洞测试脚本
测试脚本: # -*- coding: utf-8 -*- import socket,select,base64,os,re,time,datetime class mail: def __init ...
- Android单元测试之二:本地测试
Android单元测试之二:本地测试 本地测试 本地测试( Local tests):只在本地机器 JVM 上运行,以最小化执行时间,这种单元测试不依赖于 Android 框架,或者即使有依赖,也很方 ...
- CSRF 漏洞测试
CSRF简介: CSRF中文名:跨站请求伪造,英文译为:Cross-site request forgery,CSRF攻击就是attacker(攻击者)利用victim(受害者)尚未失效的身份认证信息 ...
- 小程序入口构造工具&二维码测试工具
小程序入口构造工具&二维码测试工具 本文将介绍我们小程序中隐藏的两个工具页面.原理虽不复杂,收益却实实在在,或许也能给诸君带来启发. 入口构造工具 痛点 PM&运营 投放链接 PM&a ...
- 使用Visual Studio Team Services进行压力和性能测试(二)——压力测试执行
使用Visual Studio Team Services进行压力和性能测试(二)--压力测试执行 1.点击Run test将会该压力测试进行排队,我们将看到等待测试代理屏幕.Visual Studi ...
- MS14-064 漏洞测试入侵——20145301
MS14-064 漏洞测试入侵 Microsoft Windows OLE远程代码执行漏洞,OLE(对象链接与嵌入)是一种允许应用程序共享数据和功能的技术 执行摘要 此安全更新可解决 Microsof ...
- MS08_067漏洞测试——20145301
MS08_067漏洞测试 实验步骤 search MS08_067查看相关信息 show payloads命令查找需要的攻击载荷 选择generic/shell_reverse_tcp来获取漏洞主机的 ...
随机推荐
- Asp.Net 为什么需要异步
之前看过别人提出为什么在本是多线程的Asp.Net下需要异步环境的时候,提出在Asp.Net环境下本身就是多线程,每个请求就是由一个专门IIS线程负责(咱不说Core下无IIS的情况).所以以此推论A ...
- 《Python数据分析常用手册》一、NumPy和Pandas篇
一.常用链接: 1.Python官网:https://www.python.org/ 2.各种库的whl离线安装包:http://www.lfd.uci.edu/~gohlke/pythonlibs/ ...
- linux如何查看端口被谁占用
1.查看端口是否被占用 [guosong@alice48 main]$ netstat -nlp|grep 6184 (Not all processes could be identified, n ...
- pattern
A compiled representation of a regular expression. A regular expression, specified as a string, must ...
- SpringBoot之彩色输出
spring.output.ansi.enabled NEVER:禁用ANSI-colored输出(默认项) DETECT:会检查终端是否支持ANSI,是的话就采用彩色输出(推荐项) ALWAYS:总 ...
- HTML5浏览器端图片预览&生成Base64
本文主要介绍如何通过拖拽方式在浏览器端实现图片预览,并生成图片的Base64编码. 工具链接:图片转Base64. 首先介绍一下FileReader, FileReader对象允许浏览器使用File或 ...
- C# 处理Word自动生成报告 二、数据源例子
还是以学生.语文.数学.分数为例吧, 感觉这个和helloworld都有一拼了. 造一张表如下, 整张报表就围绕这个表转圈了, 顺便说下就是名字如有雷同纯属巧合 新建个存储过程 ALTER PROCE ...
- ListView ,recycleView列表带进度条
实现上图功能有两种思路. 一:普通做法,更新item的数据,不停调用notifydatachange ; 二:各管自家刷新. 一个下载对应一个下载线程.线程持有对应item在Listview中的位置. ...
- OCPC(Optimized Cost per Click)机制
背景 在线广告中,广告按照CPM排序,排在前面的广告竞争有限广告位(截断).其中,CPM=bid*pctr.注GSP二价计费的,按照下一位bid计费.适当调整bid,可以提高竞价的排名,从而获得展现的 ...
- Mybatis分页插件PageHelper简单使用
一个好的讲解mybatis的博客地址http://www.jianshu.com/nb/5226994 引言 对于使用Mybatis时,最头痛的就是写分页,需要先写一个查询count的select语句 ...