Android系统由于其开源的属性,市场上针对开源代码定制的ROM参差不齐,在系统层面的安全防范和易损性都不一样,Android应用市场对app的审核相对iOS来说也比较宽泛,为很多漏洞提供了可乘之机。市场上一些主流的app虽然多少都做了一些安全防范,但由于大部分app不涉及资金安全,所以对安全的重视程度不够;而且由于安全是门系统学科,大部分app层的开发人员缺乏安全技术的积累,措施相对有限。
据了解:反编译 Android apk 现象的发生主要原因,在于开发商投入市场的Android apk包未经任何加固保护。
总之就是现在的移动APP安全测试的需求迅速扩大,相关测试技能对于大家的日常工作来说是必不可少的。
本人就最近研究APP,整理了APP安全测试做了部分总结。在针对APP进行渗透测试时,业务逻辑层和web端测试大同小异,所以着重介绍APP自身所特有的漏洞:反编译、二次打包、签名校验等;
APP面临的主要风险
客户端:
传统逆向分析类(反编译、调试、加密/签名破解…)
用户已经中招类(输入记录、导出组件、进程注入…)
服务端:
系统组件类(MS12-020、ShellShock、心血、ST2…)
业务应用类(注入跨站越权执行上传下载弱口令…)
本地客户端测试
本章我主要介绍的本地客户端的测试,所需要的环境、工具、APK文件结构、架构、测试点等。
以下目录结构如下,本篇所涉及到的在红框范围。
客户端测试工具-工具推荐(环境准备):
JDK:因为Android应用都包含J*A外壳,所以J*A环境是必要的。没有J*A,就没有apktool、Eclipse、jarsigner。
ADT:ADT中除了神器adb(Android Debug Bridge)和Monitor,还包含了Emulator虚拟机和Eclipse开发环境;另有较为新锐的替代品Android Studio。
GDB:作为大名鼎鼎的跨平台调试工具,GDB在实际测试中主要用于DUMP内存,从而发现敏感信息、解密数据、脱壳等等;
NDK:NDK可以在Windows上编译Android(arm)使用的Native层可执行文件(C/C++),各项Native层测试工具都可用NDK制作;
安卓设备:已root的真实手机/Emulator,不推荐x86虚拟机(VirtualBox/Genymotion)。x86虽然运行快,但是兼容性不佳,尤其客户APP涉及Native层时有时会出现莫名其妙的异常
***这里要特备注明的是对模拟器的选择***
创建模拟器的时候在选择android系统版本的时候会遇到的选项,选择x86的还是基于ARM架构的:
区别:
arm架构注重的是续航能力
x86架构注重的是性能
在目前大部分的移动设备(只能手机,平板等)和大部分的移动终端(超市消费时候刷卡的Pos机,ATM等)都是ARM的CPU。最主要原因因为续航能力。
而大部分的台式机和笔记本电脑,则是使用x86架构的CPU,因为这些设备更需要高性能的运转和高效的运算。
从目前来看,android手机目前还是arm架构占绝对主流,市场调研,目前90%的android手机都是arm架构的。
客户端测试工具-工具推荐(实用功能):
网络流量处理工具:
BurpSuite/Fiddler:针对HTTP进行各种操作的利器
Wireshark:偶尔遇到不走HTTP的APP时,定位代码用
APK文件处理工具:
ApkTool:功能众多,主要用来解包和打包Apk文件
SignApk:对Apk文件进行签名,否则无法安装运行
Dalvik反编译工具:
Dex2Jar:将Dex文件转换为Jar文件,便于反编译J*A
Smali2Java:直接从APK中反编译J*A
通用逆向分析工具:
JD-GUI/Luyten:可以反编译Class/Jar文件,在Dex2Jar之后使用
IDA:当APP存在Native层代码时,用于进行逆向分析
ApkTool:功能众多,主要用来解包和打包Apk文件,推荐一个图形化懒人工具:ApkIDE。
查壳工具
客户端测试 - 工具推荐(Xposed)
Xposed框架:
XposedBridge:JAR文件,Xposed开发所必需的接口库
XposedInstaller:APK文件,Xposed运行环境,注意5.0前后版本不同
JustTrustMe
Xposed模块,能够解除绝大多数常见SSL函数库的证书校验
注:通过修改本地客户端的方法实现的通信加密攻击不能记为风险
BlockSecureFlag:
Xposed模块,能够解除所有APP的FLAG_SECURE设置
注:适用于截屏时提示“内存不足XXXX”的场景
Surrogate:
Xposed模块,能够手动配置修改任意函数的返回值,多用于固定化随机密钥
注:灵活性不如XPOSED开发,但使用方便,适合开发基础不深的同学
客户端测试 – APK文件结构
Android应用(APK文件)通常是由以下四部分组成的:
1.清单文件(AndroidManifest.xml、/META-INF)
内含APK的包名、组件列表、启动组件、公共权限声明、各个组件的权限声明等一系列声明信息
2.Dalvik可执行文件(classes.dex、classes2.dex、…)
Java源代码->Smali中间代码->Dalvik机器码->Dalvik虚拟机->ARM/x86机器码
classes.dex中的便是Dalvik机器码
3.Native可执行文件(/lib)
其中包含很多.so链接库,多为C/C++编写而成的ARM/x86代码
可以通过JNI(Java-Native Interface)与J*A层相互调用
4.资源文件(/assets、/res、零散放置的其它种种)
除了图片等数据性质的文件之外,还有可能会有其它三种文件
客户端测试 - 反编译保护
把apk当成zip并解压,得classes.dex
执行:dex2jar.bat classes.dex文件路径
得classes.dex.jar
使用jd-gui或luyten打开jar文件,即可得J*A代码
jd-gui虽然搜索功能较好,但解析代码(尤其是混淆过的代码)时经常出BUG。luyten在这方面更加稳定,可以将两者结合使用。
有些APK会包含多个dex,全部转换成jar后合并压缩包即可
***这里特别说下代码混淆器:开源版还有商业版***
混淆器可以通过一些方法来保护你的代码不被反编译,他们不会阻止反编译器或者dex2jar对你的代码进行逆向过程,但是他们会使反编译出来的代码变得更难理解,最简单的方式,他们将APK中所有的变量和方法的名字和字符串转换成一到两个字符的字符串,这就从J*A源码中去掉了很多代码的含义,使其更难找到一些特定的信息,比如说找到一个API key 或者你存储用户登录信息的位置,好的混淆器会改变代码的流程,大多数情况下可以把业务逻辑隐藏起来,混淆器不会阻止一个一心想要破解你这个应用的黑客去理解你代码所做的事情,但他会让这个过程显得更难了。
跟很多java反编译器一样,也有很多的java混淆器,比如ProGuard,yGuard,RetroGuard,DashO,Allatori,Jshrink,Smokescreen,JODE,JaveGuard,Zelix Klassmaster,以及jCloak,这些还只是其中一小部分,甚至还有一款Android 的classes,dex混淆器,叫作Apkfuscator,你可以从http://github.com/strazzere/APKfusctor上 获取,或者你也可以试下http://shield4j.com上的Shield4j。
ProGuard是一个混淆代码的开源项目,它的主要作用是混淆代码,殊不知ProGuard还包括以下4个功能。
压缩(Shrink):检测并移除代码中无用的类、字段、方法和特性(Attribute)。
优化(Optimize):对字节码进行优化,移除无用的指令。
混淆(Obfuscate):使用a,b,c,d这样简短而无意义的名称,对类、字段和方法进行重命名。
预检(Preveirfy):在Java平台上对处理后的代码进行预检,确保加载的class文件是可执行的。
Progurad是免费的,而且已经集成到Android ADT中了,使用起来很方便。Proguard只能保护代码,却不能保护我们的apk文件。任何人都可以使用apktool工具,反编译我们开发的apk文件,进而更改其中各种资源,或者更改部分代码,甚至是注入代码,然后再打包回apk,二次发布后,达到自己的目的。或者是加入了广告,或者是增加了恶意木马病毒等。不需要multi-dex。Proguard会对输入的jar文件按照shrink - optimize - obfuscate - perverify的顺序依次进行处理,最后得到输出jar文件。Proguard使用library jars来辅助对input jars类之间的依赖关系进行解析, library jars自身不会被处理,也不会被包含到output jars中。
它能发现并删除无用类、字段(field)、方法和属性值(attribute)。它也能优化字节码 并删除无用的指令。最后,它使用简单无意义的名字来重命名你的类名、字段名和方法名。经过以上操作的jar文件会变得更小,并很难进行逆向工程。但是有耐心的攻击者仍能分析出代码结构
DexGuard 是GuardSquare公司推出的移动应用App安全软件,经过特别设计用于防止安卓系统上的应用APP与SDK遭受逆向工程与各类安全入侵的威胁
DexGuard是收费的,DexGuard是在Proguard基础上,加入了更多的保护措施。使用DexGuard混淆后,生成的apk文件,就无法正常使用apktool反编译了。尽管还是能够反编译出部分资源文件,但是由于反编译过程不完全,就无法再打包成apk了。这样就保护了我们的apk文件,不会被二次打包发布了。代码混淆力度更大 + 资源混淆 + so加壳等。自带multi-dex扫描
客户端测试 - 安装包签名
使用JDK中的jarsigner.exe检查安装包的签名:
jarsigner.exe -verify APK文件路径 -verbose -certs
***用一个有效的、直接客户所持有的证书来签名
通用签名风险
什么是通用签名?
搭建好Android开发环境后(使用Eclipse或Android Studio),对APK签名的默认密钥存在debug.keystore文件中。在linux和Mac上debug.keystore文件位置是在~/.android路径下,在windows目录下文件位置是C:\user\用户名.android路径下。
除了debug.keystore外,在AOSP发布的Android源码中,还有以下几个证书是公开的,任何人都可以获取,在源码的build/target/product/security目录中:
通用签名风险:
(1)如果攻击者的应用包名与目标应用相同,又使用了相同的密钥对应用进行签名,攻击者的应用就可以替换掉目标应用;
(2)另外目标应用的自定义权限android:protectionlevel为“signature”或者“signatureOrSystem”时,保护就形同虚设;
(3)如果设备使用的是第三方ROM,而第三方ROM的系统也是用AOSP默认的签名,那么使用如果使用系统级签名文件签名过的应用,权限就得到了提升。
以乌云公开的WooYun-2014-67027为例,有安全研究人员发现有一个数字证书签名被很多银行的手机客户端所使用。与此同时还发现了几款个人开发者类应用也使用了此证书签名。而这种数字签名被滥用的行为存在极大的安全隐患
解压应用安装包,可用keytool查看应用的签名证书信息: keytool -printcert -v -file META-INF/CERT.RSA
经挖掘和分析,研究人员发现目前共有23款不同银行手机银行客户端使用该签名:
在应用市场内,目前共发现6款个人开发的应用同时使用该数字证书签名:
事情发生的原因是银行的外包开发管理不严,不同银行的APP居然用同样的数字证书签名,并且开发者还将证书用于了个人APP的开发中。如果签名证书被恶意攻击者获取,可以编写安装是能直接替换掉这些银行客户端的恶意APP。
还可以使用AOSP通用签名提升应用权限:
直接编译AOSP源码得到的ROM,使用AOSP的默认证书,在设置->关于手机,版本号中可查看到:
对于普通的用默认debug.keystore证书签名的App,如果在AndroidManfiest.xml的manifest节点加入android:sharedUserId=”android.uid.system”这个属性,安装时会提示错误:
如果对app-debug.apk使用AOSP提供的platform.x509.pem和platform.pk8重新签名,则可以安装成功:
查看应用的进程属性,已是system用户组。
目前有不少的第三方ROM使用的AOSP提供的默认签名
个人开发者在往开源平台上传代码时,注意不要将签名证书的私钥上传。
客户端测试 - 完整性校验
ApkTool+SignApk:
解包后可修改并重新打包;
可查看AndroidManifest.xml;
可查看smali源码(适用于J*A反编译失败的情况);
解包:
java -jar apktool.jar d -f apk文件路径 -o 解包目标文件夹
打包:
java -jar apktool.jar b -f 待打包的文件夹 -o 输出apk路径
APK必须进行签名后,方可安装和运行:
java -jar signapk.jar testkey.x509.pem testkey.pk8 待签名apk文件路径 签名后输出apk路径
1.用ApkTool将目标APK文件解包;
2.随便找一个解包目录里的资源文件,修改之;
3.推荐找到启动logo图进行修改(因为容易确认结果);
4.用ApkTool,将解包目录重新打包成未签名的APK文件;
5.用SignApk,对未签名的APK文件进行签名;
6.将签了名的APK安装、运行、确认是否存在自校验;
签名绕过方式:
测试。使用ApkIDE重打包后 直接安装运行,在Loading过程中会弹出修改提示,如下图,说明软件检测到了被非法修改。
下面的操作是,将官方包的RSA拖出来,置换掉我们修改后的RSA文件,名字尽量与SF保持一致即CERT,然后安装 可完美运行。
Tags: .Native、Andorid、Android apk、AOSP、apktool、app、arm架构、dex2jar、IDA、java、Progurad、ROM、root、SYSTEM、x86架构、xposed框架、优化、加密、安全入侵、安全测试、查壳、测试、混淆、私钥、通用签名、预检、默认签名