安卓APP的渗透测试,主要分为两个方面

  • 客户端:安卓四大组件的安全性检测,简单来说就是一个个的检查项,看看是否符合要求

  • 服务端:APP和服务端交互的渗透测试,抓包检测,和Web渗透差不多

本篇我们主要介绍Android客户端的渗透测试,重点放在:要测哪些项目,怎么测上面。我会一条条的列出相应的测试项,并给出在我认知内最简便的方法(如果大佬们有更好的方法,欢迎邮件与我讨论),供自己及其他同行参考。

检测工具

应用配置安全

开启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 文件在刚刚反编译出来的文件夹里

image-20230701135230263

整改意见:将参数android:allowBackup属性设置为false,防止数据泄漏

开启Debuggable属性

漏洞等级:中

风险分析:被测应用的AndroidManifest.xml文件中Debuggable属性值被设置为true时,可以设置断点来控制程序的执行流程,在应用程序运行时修改其行为,app存在被恶意程序调试的风险,可能导致泄漏敏感信息泄漏等问题。

检查工具:APKTool

检查方法:

1、使用APKTool对apk进行反编译

2、AndroidManifest.xml 文件中查看 Debuggable 属性,检查是否未设置或者被设置为true

image-20230701135254393

整改意见:将参数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
2
3
removeJavascriptInterface(searchBoxJavaBridge_);
removeJavascriptInterface(accessibility);
removeJavascriptInterface(accessibilityTraversal);

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 包名

image-20230701150922596

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文件加固状态

image-20230701164937608

整改意见:对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,导致恶意程序被下载安装

检查工具:

检查方法:

整改意见:对返回数据进行加密