一、SSL Pinning 导致抓包失败
难题描述:多数金融、支付类APP会启用SSL Pinning(证书绑定),强制客户端只信任预置证书,导致Burp、Charles等工具无法抓取HTTPS流量,无法分析API通信内容。
原因分析:APP通过代码硬编码证书哈希或在原生层实现证书校验逻辑,常规的系统证书信任机制被绕过。
解决思路:
-
1. Frida动态Hook绕过:编写Frida脚本Hook证书校验函数,如Android的X509TrustManager.checkServerTrusted或iOS的NSURLSession相关方法。示例脚本:
Java.perform(function () { var TrustManager = Java.use('javax.net.ssl.X509TrustManager'); TrustManager.checkServerTrusted.implementation = function (chain, authType) { // 跳过证书校验 }; });执行命令:frida -U -f com.target.app -l bypass-ssl.js –no-pause
- 2. 修改APK重打包:使用Apktool反编译APP,删除res/raw目录下的证书文件,修改AndroidManifest.xml禁用证书校验,重新签名安装。
- 3. iOS砸壳后修改:对IPA文件砸壳(如使用Clutch),通过Hopper Disassembler定位证书校验逻辑并NOP掉,重签名后安装到测试设备。
实战案例:某银行APP采用双向证书校验,通过Frida Hook SSLContext.init方法替换自定义TrustManager,成功抓取到转账接口的加密参数,发现参数未做签名校验的漏洞。
注意事项:部分APP会在多个层级实现校验(如Java层+Native层),需同时Hook对应函数,避免漏判。
二、本地数据加密导致敏感信息难提取
难题描述:APP将用户Token、身份证号等敏感信息存储在SharedPreferences(Android)或UserDefaults(iOS)中,且采用AES、RSA等算法加密,直接读取无法获得明文。
原因分析:开发者为符合合规要求(如PCI DSS)对本地数据加密,但密钥管理可能存在漏洞(如硬编码在代码中)。
解决思路:
- 1. 静态分析找密钥:使用JADX反编译APK,搜索AES、SecretKey等关键词,定位密钥硬编码位置。例如某电商APP在CryptoUtil.java中以字符串形式存储密钥aes_key=1234567890abcdef。
-
2. 动态Hook解密函数:通过Frida监控Cipher.doFinal方法,捕获加密前后的数据。示例脚本:
Java.use('javax.crypto.Cipher').doFinal.implementation = function (data) { var result = this.doFinal(data); console.log('加密前: ' + hex.encode(data)); console.log('加密后: ' + hex.encode(result)); return result; };
-
3. 内存提取密钥:对使用动态生成密钥的APP,可通过GDB/LLDB附加进程,在密钥生成函数执行后读取内存中的密钥值。某支付APP在generateKey方法中通过设备指纹动态生成密钥,通过内存dump成功提取。
注意事项:iOS的Keychain数据加密强度较高,需结合越狱环境使用Keychain-Dumper工具提取。
三、反调试机制阻碍动态分析
难题描述:APP通过检测调试器(如GDB、LLDB)、模拟器环境或异常进程,触发退出、崩溃或伪造数据等防护逻辑,导致无法动态调试代码。
原因分析:常见手段包括检查TracerPid值(Android)、调用ptrace函数、检测模拟器特征(如ro.product.model为”sdk_gphone_x86″)。
解决思路:
-
1. 绕过调试器检测:使用Frida禁用ptrace调用:
Interceptor.attach(Module.findExportByName(null, 'ptrace'), { onEnter: function (args) { args[0] = ptr(0); // 将请求类型改为PT_NULL,无效化调试检测 } });
- 2. 伪装真机环境:在Genymotion模拟器中修改build.prop,将ro.build.tags改为”release-keys”,ro.product.manufacturer改为”Xiaomi”;iOS可使用Xcode配置自定义设备型号。
-
3. 修改反调试代码:对已砸壳的IPA,用Hopper定位反调试逻辑(如sysctl检测),将条件判断指令改为NOP(空操作)。某社交APP通过sysctl检测CTL_KERN下的KERN_PROC状态,修改后成功绕过。
注意事项:部分APP会采用多层反调试,需结合静态分析定位所有检测点。
四、加固壳导致代码逆向困难
难题描述:APP使用360加固、爱加密等商业加固方案,反编译后仅能看到壳代码,核心逻辑被加密保护,无法分析业务流程。
原因分析:加固壳通过动态解密、指令抽取、虚拟机保护等技术,阻止逆向工具直接获取原始代码。
解决思路:
-
1. 内存dump脱壳:在APP运行时(核心代码已解密加载到内存),使用frida-dump工具导出内存中的Dex文件:
frida -U -f com.target.app -l frida-dump.js --no-pause适用于Android的Dex加固,成功率约80%。
- 2. 动态调试脱壳:通过IDA附加进程,在dexFileParse函数处下断点,当壳解密完成后 dump 完整Dex。某金融APP使用爱加密V5加固,通过该方法成功获取原始代码。
-
3. 针对iOS加固的砸壳:使用Clutch或DumpDecrypted对IPA砸壳,配合class-dump提取头文件,分析OC类结构。对于Swift编写的APP,需结合Hopper分析Mach-O文件中的符号表。
注意事项:部分加固方案会检测调试环境,脱壳需在非调试状态下进行,可先通过Frida禁用检测。
五、第三方SDK漏洞难以识别
难题描述:APP集成的广告SDK、统计SDK(如友盟、TalkingData)可能存在漏洞(如明文传输、命令注入),但因代码混淆或未开源,难以发现。
原因分析:SDK通常以aar、framework形式嵌入,代码混淆度高,且功能逻辑独立于主APP,容易被测试人员忽略。
解决思路:
- 1. SDK组件识别:通过jadx-gui搜索常见SDK包名(如com.umeng.analytics),定位SDK目录;使用dexdump分析Dex中的类引用,识别第三方组件。
- 2. 针对性测试SDK接口:调用SDK暴露的方法,检测参数是否过滤。某电商APP集成的分享SDK存在shareText(String text)方法,未过滤javascript:协议,导致XSS漏洞。
-
3. 检测SDK通信安全:通过抓包分析SDK的独立API(如友盟的统计上报接口/log.gif),检查是否使用HTTPS、是否校验签名。某工具类APP的广告SDK以明文传输设备ID,导致信息泄露。
实战案例:某支付APP集成的某地图SDK存在证书校验漏洞,可被劫持发送虚假定位,通过替换SDK的证书文件成功复现。
六、本地权限滥用检测困难
难题描述:APP可能过度申请权限(如Android的READ_PHONE_STATE、iOS的NSLocationAlwaysUsageDescription),或在未告知用户的情况下滥用权限(如偷偷录音、读取通讯录),但手动测试难以全面覆盖。
原因分析:权限调用分散在多个功能模块,部分调用逻辑依赖特定触发条件(如后台定时任务)。
解决思路:
- 1. 静态分析权限清单:检查AndroidManifest.xml中的<uses-permission>标签,对比《网络安全法》要求,判断是否存在超范围申请(如手电筒APP申请READ_SMS)。
- 2. 动态监控权限调用:使用Android Studio的Profile工具,监控checkSelfPermission、requestPermissions等方法调用;iOS可通过Xcode的Instruments跟踪权限请求函数。
-
3. 自动化检测工具:使用MobSF(Mobile Security Framework)扫描APK/IPA,生成权限风险报告。某健身APP被检测出在启动时未用户交互就申请ACCESS_FINE_LOCATION,违反《个人信息保护法》。
注意事项:需结合业务场景判断权限必要性,如地图类APP申请定位权限为合理,而计算器APP申请则为异常。
七、动态加载代码(Dex/So)导致漏洞遗漏
难题描述:APP通过网络下载动态加载Dex(Android)或Framework(iOS),这部分代码在静态分析时不存在,易导致漏洞遗漏。
原因分析:开发者为减小安装包体积或实现热更新,将非核心功能放在远程服务器,运行时动态加载。
解决思路:
- 1. 捕获动态加载文件:在APP运行时,监控DexClassLoader(Android)或NSURLSession(iOS)的下载行为,保存加载的Dex/Framework文件。
-
2. Hook动态加载过程:使用Frida监控loadDex方法,获取加载路径后进行静态分析:
Java.use('dalvik.system.DexClassLoader').$init.implementation = function (dexPath) { console.log('动态加载Dex: ' + dexPath); this.$init(dexPath, ...arguments.slice(1)); };
- 3. 模拟服务器响应:通过修改Hosts文件将动态加载域名指向本地服务器,返回篡改后的测试文件,检测是否存在代码注入风险。某新闻APP因未校验动态加载的Dex签名,导致可注入恶意代码。
八、跨平台框架(Flutter/React Native)的特殊性难题
难题描述:使用Flutter、React Native开发的APP,代码同时包含原生层和JS/Dart层,传统针对原生APP的测试方法难以覆盖跨层交互漏洞。
原因分析:跨平台框架通过桥接机制(如React Native的Bridge)实现JS与原生通信,漏洞可能存在于参数传递、权限控制等环节。
解决思路:
- 1. 分层分析:对React Native APP,需同时分析index.android.bundle(JS代码)和原生Java代码,重点检查NativeModules暴露的方法是否有参数校验。
- 2. 针对Flutter的逆向:使用flutter_sdk/bin/flutter工具反编译AppBundle,获取Dart代码;监控MethodChannel的通信,检测参数是否被篡改。某电商Flutter APP因未校验MethodChannel传递的价格参数,导致支付金额可篡改。
-
3. 跨层交互测试:手动构造JS调用原生方法的参数(如NativeModules.Payment.pay(1)改为pay(-1)),检测是否存在逻辑漏洞。
注意事项:Flutter的Dart代码混淆后可读性低,需结合动态调试定位关键逻辑。
九、生物识别逻辑漏洞难以验证
难题描述:APP集成指纹、面容识别,但验证逻辑可能存在漏洞(如本地伪造通过),但测试时难以模拟生物信息。
原因分析:生物识别通常涉及硬件交互,测试环境难以直接获取真实生物特征数据。
解决思路:
-
1. 分析验证逻辑位置:若生物识别在本地完成(如仅校验指纹模板哈希),可Hook验证结果函数:
// Android指纹验证绕过 Java.use('android.hardware.fingerprint.FingerprintManager').authenticate.implementation = function (crypto, cancel, flags, callback) { callback.onAuthenticationSucceeded(null); // 直接返回验证成功 };
- 2. 检测服务器端验证:若生物识别结果需服务器校验(如上传指纹模板哈希),可拦截请求修改结果。某支付APP因服务器仅验证”success”字符串,修改后成功绕过。
-
3. 硬件模拟工具:使用Android的Emulator模拟指纹识别,在设置中添加虚拟指纹,测试验证流程。
注意事项:生物识别漏洞可能导致账户被盗,需在授权范围内测试,禁止泄露用户生物信息。
十、API接口签名机制导致参数篡改困难
难题描述:APP的API请求会对参数进行签名(如MD5(参数+密钥)),直接修改参数会因签名不匹配被服务器拒绝,无法测试越权、篡改等漏洞。
原因分析:开发者通过签名机制防止请求被篡改,签名算法和密钥通常在APP代码中实现。
解决思路:
- 1. 逆向签名算法:在代码中定位签名生成函数,如搜索sign、md5等关键词。某电商APP的generateSign函数为MD5(params排序+secretKey),还原后可生成合法签名。
-
2. Hook签名函数:直接获取生成的签名值,替换篡改后的参数签名:
// 拦截签名生成函数,获取合法签名 Java.use('com.target.app.utils.SignUtil').generateSign.implementation = function (params) { var sign = this.generateSign(params); console.log('参数: ' + JSON.stringify(params) + ' 签名: ' + sign); return sign; };
-
3. 寻找签名密钥:部分APP会将密钥存储在so文件(Android)或Mach-O文件(iOS)中,需使用IDA逆向分析。某金融APP的密钥隐藏在libsign.so的字符串常量中,提取后成功生成有效签名。
实战案例:某物流APP的订单查询接口通过签名防止越权,逆向算法后修改userId参数,成功查询其他用户订单信息。
实战总结与建议
移动应用渗透测试需兼顾静态分析与动态调试,针对不同平台(Android/iOS)和开发框架选择合适工具。核心原则是:先解决环境障碍(脱壳、绕过反调试),再分析业务逻辑(API、数据存储),最后验证漏洞影响。
建议搭建专用测试环境(如越狱iPhone、Root模拟器),积累常见加固方案的脱壳经验,同时关注最新的移动安全技术(如Android 13的隐私沙盒、iOS 16的App Tracking Transparency)对测试的影响。始终以“模拟真实攻击”为导向,确保发现的漏洞具有实际利用价值。
以上内容从实际测试场景出发,提供了具体的技术细节和操作方法,有助于读者应对移动应用渗透测试中的各类难题。若你对某类难题的解决思路有更细致的需求,或想补充其他场景,可随时告知。














暂无评论内容