安卓APP客户端渗透测试指南
安卓APP的渗透测试,主要分为两个方面
客户端:安卓四大组件的安全性检测,简单来说就是一个个的检查项,看看是否符合要求
服务端:APP和服务端交互的渗透测试,抓包检测,和Web渗透差不多
本篇我们主要介绍Android客户端的渗透测试,重点放在:要测哪些项目,怎么测上面。我会一条条的列出相应的测试项,并给出在我认知内最简便的方法(如果大佬们有更好的方法,欢迎邮件与我讨论),供自己及其他同行参考。
检测工具
- dex2jar
- APKTool
- jd-gui:Releases · java-decompiler/jd-gui
应用配置安全
开启AllowBackup属性
漏洞等级:高
风险分析:被测应用的AndroidManifest.xml文件中allowBackup属性值被设置为true,可通过adb backup对应用数据进行备份,在无root的情况下可以导出应用中存储的所有数据,造成用户数据泄露。
检查工具:APKTool
检查方法:
1、使用APKTool对apk进行反编译(后续不再详述此步骤)
把要反编译的apk复制到APKTool目录下,cmd切到APKTool的目录
输入指令:apktool.jar d test.apk
完成后,APKTool的目录下会多出一个和apk同名的文件夹
2、AndroidManifest.xml 文件中查看 allowBackup 属性,检查是否未设置或者被设置为true
AndroidManifest.xml 文件在刚刚反编译出来的文件夹里
整改意见:将参数android:allowBackup属性设置为false,防止数据泄漏
开启Debuggable属性
漏洞等级:中
风险分析:被测应用的AndroidManifest.xml文件中Debuggable属性值被设置为true时,可以设置断点来控制程序的执行流程,在应用程序运行时修改其行为,app存在被恶意程序调试的风险,可能导致泄漏敏感信息泄漏等问题。
检查工具:APKTool
检查方法:
1、使用APKTool对apk进行反编译
2、AndroidManifest.xml 文件中查看 Debuggable 属性,检查是否未设置或者被设置为true
整改意见:将参数android:allowBackup属性设置为false,防止数据泄漏
公共组件安全
WebView组件远程代码执行
漏洞等级:高
风险分析:Android API level 16以及之前的版本存在远程代码执行安全漏洞,该漏洞源于程序没有正确限制使用WebView.addJavascriptInterface 方法,远程攻击者可通过使用Java Reflection API利用该漏洞执行任意Java对象的方法,导致远程代码执行漏洞。
检查工具:dex2jar、jd-gui
检查方法:
1、解压缩apk文件(apk和zip包一样,可以直接被解压缩。改成zip后缀再解压缩也是一样的),得到其中的classes.dex
2、把classed.dex复制到 dex2jar 的目录下,cmd运行 dex2jar.bat classes.dex
,得到 classes_dex2jar.jar
3、使用 jd-gui 打开 classes_dex2jar.jar
4、全局搜索是否使用 addJavascriptInterface 方法
5、如果是 Android 4.2 之前版本,查看源代码中是否对addJavascriptInterface的输入参数进行过滤;如果是Android 4.2及之后版本,检查是否声明@JavascriptInterface来代替addjavascriptInterface
整改意见:
1、不使用 addJavascriptInterface 方法
2、若必须使用,则应对访问的url进行过滤限制或对html页面进行完整性校验,同时显示移除对指定的javascript接口的调用
1 | removeJavascriptInterface(searchBoxJavaBridge_); |
3、采用@JavascriptInterface 代替 addjavascriptInterface
Activity组件配置错误
漏洞等级:高
风险分析:Activity是安卓应用组件,提供与用户进行交互的界面,如果应用对权限控制不当,攻击者可以绕过认证阶段,直接调用后续activity组件。
检查工具:drozer
检查方法:
1、进入drozer(教程 https://jenchoi.top/2023/install-drozer-on-windows/ )
2、获取被测应用的包名(教程:获取APP包名的方法)
3、运行 run app.activity.info –a 包名
4、直接调用对应组件,看看是否能绕过app本身逻辑直接请求组件
1 | run app.activity.start --component 包名 组件名 |
组件名就是上面com.xxx.xxx.xxx.xxxActivity
整改意见:
1、如果组件不需要与其他app共享数据或交互,请将该组件的exported的属性为“false”。如果组件需要与其他app共享数据或交互, 请对组件进行权限控制和参数校验。app内使用的私有Activity不应配置intent-filter,如果配置了intent-filter需设置exported属性为false
2、谨慎处理接收的intent以及其携带的信息,当Activity返回数据时候需注意目标Activity是否有泄露信息的风险
Service组件暴漏
漏洞等级:高
风险分析:Service是Android中四大组件进行后台作业的主要组件,如果被测应用对权限控制不当,导致其他应用可以启动被测应用的Service。
检查工具:drozer
检查方法:
方法一:drozer 执行 run app.service.info -a <packageName>
方法二:直接检查AndroidManifest.xml 文件中的Services是否暴露
整改意见:
1、设置Service的android:exported 属性为 false
2、通过设置自定义权限来限制对Service的访问
本地拒绝服务漏洞
漏洞等级:高
风险分析:android系统提供了activity、service和broadcastreceiver等组件,并提供了intent机制来协助应用间的交互与通讯,intent负责对应用中一次操作的动作动作涉及数据、附加数据进行描述,android系统则根据此intent的描述,负责找到对应的组件,将intent传递给调用的组件,并完成组件的调用。android应用本地拒绝服务漏洞源于程序没有对intent.getxxxextra0获取的异常或者畸形数据处理时没有进行异常捕获,从而导致攻击者可通过向受害者应用发送此类空数据、异常或者畸形数据来达到使该应用crash的目的,简单的说就是攻击者通过intent发送空数据、异常或畸形数据给受害者应用导致其崩溃。
检查工具:
检查方法:
整改意见:
1、将不必要的组件设置为不导出,即在 AndroidMenifest.xml 中将相应组件的android:exported属性设为false
2、建议处理通过 intent.getxxxextra() 获取的数据时进行以下判断,以及用try catch方式进行捕获所有异常,以防止应用出现拒绝服务漏洞
1) 空指针异常
2) 类型转换异常
3) 数组越界访问异常
4) 类未定义异常
5) 其他异常
Broadcast组件拒绝服务
漏洞等级:高
风险分析:如果用户输入合并到可动态执行的代码中,那么攻击者可以提交构造的输入,破坏原有的数据,指定服务器执行构造的命令
检查工具:
检查方法:
整改意见:
1、AndroidManifest.xml 文件的各 Receiver 标签中,设置android:exported=”false”
2、Receiver 代码中增加消息异常处理机制。
ContentProvider组件信息泄露
漏洞等级:高
风险分析:攻击者可以利用开放的Content Provider 获取系统敏感资源
检查工具:drozer
检查方法:
整改意见:
1、AndroidManifest.xml文件的各Provider标签中,设置android;exported=”false”
2、内部app通过ContentProvider交换数据,设置 protectionLevel= “signature” 来验证签名
3、公开的 ContentProvider 确保不存储敏感数据
ContentProvider组件SQL注入
漏洞等级:高
风险分析:暴露的Provider组件,如果在 query() 中使用拼接字符串组成sql语句的形式去查询数据库,容易发生sql注入攻击。
检查工具:无
检查方法:
1、AndroidManifest.xml 中查找Provider是否对外暴露(exported属性为true)
2、是否使用 query() 方法
3、SQL语句赋值来源是否为拼接字符串
整改意见:
1、不必要导出的Provider组件,建议显示设置组件的 android:exported 属性为 false
2、使用selectionArgs进行参数化查询
content provider目录遍历检测
漏洞等级:高
风险分析:开发者为方便应用程序之间共享文件,会把实现了 openfile() 接口的content provider设置为导出状态,因此其他有相应调用该content provider权限的应用即可调用content provider的 openfile() 接口进行文件数据访问。但是如果没有进行content provider访问权限控制和对访问的目标文件的uri进行有效判断,攻击者利用文件目录遍历可访问任意可读文件,更有甚者可以往手机设备可写目录中写入任意数据。
检查工具:
检查方法:
整改意见:
1、如果组件不需要与其他app共享数据或交互,请将androidmanifest.xml 配置文件中设置该组件为exported的属性为 “false”
2、如果组件需要与其他app共享数据或交互, 请对组件进行权限控制和参数校验
3、如果需要导出的话,严格编写过滤
WebView域控制不严格漏洞
漏洞等级:高
风险分析:当B应用的activity是可被导出的,同时设置允许WebView使用File协议,则A应用可以在外部调起B的Activity,同时向B传递一个请求内部数据的文件则可以获取B的数据。
检查工具:
检查方法:
整改意见:
1、设置activity不可被导出
2、明确禁止WebView 使用 File 协议
代码安全
代码未混滑
漏洞等级:高
风险分析:客户端代码未做混淆,。
检查工具:dex2jar、jd-gui
检查方法:
1、dex2jar将classes.dex转成jar包
2、使用jd-gui打开jar包,查看代码是否混淆
代码混淆过后,在语意上难以通过直接查看代码理解
整改意见:对APP安装包进行加固,执行强混淆操作
代码未加固
漏洞等级:高
风险分析:客户端代码未做混淆和加固,使攻击者很轻易反编译出源代码,从而对应用程序逻辑进行分析。
检查工具:MT管理器
检查方法:
使用MT管理器查看被测apk文件加固状态
整改意见:对app加商业壳
二次编译打包
漏洞等级:高
风险分析:攻击者通过反编译后得到程序源代码,修改源码后,重新编译、签名并安装。在重新打包的过程中,攻击者可能注入恶意代码,或者修改软件逻辑绕过鉴权等。
检查工具:APKTool、jarsigner、zipalign(可选)
检查方法:
1、使用APKToole对apk进行反编译
2、修改代码后,再次使用APKTool对apk进行打包
apktool b 文件夹 -o 新apk名.apk
整改意见:内部代码实现apk二次打包鉴别机制,在程序运行时校验apk签名是否由官方私钥签名而来。
Janus安卓签名漏洞
漏洞等级:高
风险分析:攻击者可以绕过安卓系统的signature scheme V1签名机制,进而直接对app进行篡改
检查工具:
检查方法:
整改意见:app使用signature scheme V2及以上版本签名机制
Root环境检测
漏洞等级:高
风险分析:在mobile 应用启用certificate pinning 的情况下使用Rooted 手机+xposed+justtrustme 组件依然可以通过API hook进行中间人攻击。 监控客户端与后台的通信内容。
检查工具:
检查方法:
整改意见:
1、应用启动时检测手机环境,确保为非root环境
2、检测如xposed、 Cydia Substrate、frida等逆向工具是否运行时,弹窗提醒用户设备已root
模拟器环境检测
漏洞等级:高
风险分析:攻击者可以用模拟器运行、多开、调试、攻击程序
检查工具:
检查方法:
整改意见:在客户端代码中增加模拟器检测
证书绑定
漏洞等级:高
风险分析:攻击者通过替换证书解密客户端与服务端之间的数据
检查工具:
检查方法:
整改意见:客户端应对服务端证书进行强验证
代理环境检测
漏洞等级:高
风险分析:攻击者通过设置代理的方式,抓取客户端与服务器之间的数据包
检查工具:
检查方法:
整改意见:客户端存在代理时停止通络通信,并提醒用户关闭代理
敏感信息
敏感信息硬编码
漏洞等级:高
风险分析:如果类似密钥等敏感信息硬编码在源文件中,那么攻击者通过反编译程序代码,可以轻易获取这些敏感信
检查工具:
检查方法:
整改意见:避免类似密钥,激活码等敏感信息直接硬编码在客户端源文件中。
弱加密问题
漏洞等级:高
风险分析:使用弱加密算法会大大增加黑客攻击的概率,黑客可能会破解隐私数据、猜解密钥、中间人攻击等,造成隐私信息的泄漏,甚至造成财产损失
检查工具:
检查方法:
整改意见:
1、使用对称加密算法时避免使用DES算法,可以选择3DES
2、IvParameterSpec初始化时,不使用常量vector
3、使用 RSA 算法加密时,指定Padding模式,建议密钥长度>1024 bit
客户端敏感信息明文存储
漏洞等级:高
风险分析:敏感数据存储时应采取密文的形式,否则攻击者一旦获取数据,则直接获取明文的敏感信息。
检查工具:
检查方法:
整改意见:重要的敏感信息数据要通过加密方式存储,以避免被恶意截获
日志中记录了泄露敏感信息
漏洞等级:高
风险分析:客户端日志文件中或者动态的调试日志中输出了敏感的系统信息,攻击者可能会窃取到这些敏感信息。
检查工具:
检查方法:
整改意见:日志文件中或者动态的调试日志中不应包含敏感信息
本地数据库注入
漏洞等级:高
风险分析:客户端程序在查询本地的Content Provider时通过构造特殊的查询语句,进而查询额外的敏感信息。
检查工具:
检查方法:
整改意见:过滤引起SQLite查询语句歧义的特殊字符,例如单引号、双引号、圆括号、分号 等
WebView 密码明文存储漏洞
漏洞等级:高
风险分析:WebView 默认开启密码保存功能 mWebView.setSavePassword(true),如果该功能未关闭,在用户输入密码时会弹出提示框,询问用户是否保存密码,如果选择”是”,密码会被明文保存到 /data/data/com.package.name/databases/webview.db 中,这样就有被资取密码的危险。
检查工具:
检查方法:
整改意见:通过设置 WebSettings.setSavePassword(false) 关闭密码保存提醒功能
业务逻辑安全
客户端更新安全性
漏洞等级:高
风险分析:攻击者拦截替换客户端更新url,导致恶意程序被下载安装
检查工具:
检查方法:
整改意见:对返回数据进行加密