关于 performing-mobile-app-certificate-pinning-bypass
用于绕过移动应用证书固定、通过 Burp Suite 检查 HTTPS 流量的安全测试技能,涵盖 Android 和 iOS 的 Objection 与自定义 Frida 钩子流程,仅适用于获授权的应用测试。
主要功能
- 01识别 Android 和 iOS 固定方式
- 02使用 Objection 绕过常见固定
- 03编写自定义 Frida 钩子
- 04跟踪高级固定实现
- 05在 Burp Suite 验证流量拦截
适用场景
- 01在获授权的应用测试中检查 HTTPS 流量
- 02评估证书固定强度与绕过难度
- 03绕过后检查是否仍有连接未被捕获
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill performing-mobile-app-certificate-pinning-bypass安装后在 Claude Code 中输入/performing-mobile-app-certificate-pinning-bypass确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSEassets/template.mdreferences/api-reference.mdstandards.mdworkflows.mdscripts/agent.pyprocess.py详细介绍
执行移动应用证书固定绕过
何时使用
在以下情况下使用此技能:
- 移动应用由于证书固定而拒绝通过代理连接
- 执行需要 HTTPS 流量拦截的授权安全测试
- 评估固定实现的强度和绕过难度
- 评估移动应用网络安全的纵深防御
请勿使用于在没有明确测试授权的情况下绕过应用的固定。
前提条件
- 已配置 Burp Suite 作为代理,并在所有接口上设置监听器
- 已 root 的 Android 设备或已越狱的 iOS 设备
- 目标设备上运行 Frida 服务
- 已安装 Objection(
pip install objection) - 目标应用已安装并复现固定行为
工作流
步骤 1:识别固定实现
需要识别的 Android 固定方法:
1. Network Security Config (res/xml/network_security_config.xml)
<pin-set> with certificate hash pins
2. OkHttp CertificatePinner
CertificatePinner.Builder().add("api.target.com", "sha256/...")
3. Custom TrustManager
X509TrustManager overrides in code
4. Third-party libraries
- TrustKit
- Certificate Transparency checks
iOS 固定方法:
1. NSURLSession delegate (URLSession:didReceiveChallenge:)
2. ATS (App Transport Security) with custom trust evaluation
3. TrustKit framework
4. Alamofire ServerTrustPolicy
5. Custom SecTrust evaluation
步骤 2:使用 Objection 绕过(最快方法)
# Android
objection --gadget com.target.app explore
android sslpinning disable
# iOS
objection --gadget com.target.app explore
ios sslpinning disable
Objection 会 hook 常见的固定实现,包括 OkHttp CertificatePinner、TrustManagerImpl、NSURLSession delegate 方法和 SecTrust 评估。
步骤 3:使用自定义 Frida 脚本绕过
Android - 通用 SSL 固定绕过:
// android_ssl_bypass.js
Java.perform(function() {
// Bypass TrustManagerImpl
var TrustManagerImpl = Java.use("com.android.org.conscrypt.TrustManagerImpl");
TrustManagerImpl.verifyChain.implementation = function(untrustedChain, trustAnchorChain,
host, clientAuth, ocspData, tlsSctData) {
console.log("[+] Bypassing TrustManagerImpl for: " + host);
return untrustedChain;
};
// Bypass OkHttp3 CertificatePinner
try {
var CertificatePinner = Java.use("okhttp3.CertificatePinner");
CertificatePinner.check.overload("java.lang.String", "java.util.List").implementation =
function(hostname, peerCertificates) {
console.log("[+] Bypassing OkHttp3 pinning for: " + hostname);
return;
};
} catch(e) {}
// Bypass custom X509TrustManager
var X509TrustManager = Java.use("javax.net.ssl.X509TrustManager");
var TrustManager = Java.registerClass({
name: "com.bypass.TrustManager",
implements: [X509TrustManager],
methods: {
checkClientTrusted: function(chain, authType) {},
checkServerTrusted: function(chain, authType) {},
getAcceptedIssuers: function() { return []; }
}
});
// Bypass SSLContext
var SSLContext = Java.use("javax.net.ssl.SSLContext");
SSLContext.init.overload("[Ljavax.net.ssl.KeyManager;",
"[Ljavax.net.ssl.TrustManager;", "java.security.SecureRandom").implementation =
function(km, tm, sr) {
console.log("[+] Replacing TrustManagers in SSLContext.init");
this.init(km, [TrustManager.$new()], sr);
};
// Bypass NetworkSecurityConfig (Android 7+)
try {
var NetworkSecurityConfig = Java.use(
"android.security.net.config.NetworkSecurityConfig");
NetworkSecurityConfig.isCleartextTrafficPermitted.implementation = function() {
return true;
};
} catch(e) {}
console.log("[*] SSL pinning bypass loaded");
});
frida -U -f com.target.app -l android_ssl_bypass.js --no-pause
iOS - 通用 SSL 固定绕过:
// ios_ssl_bypass.js
if (ObjC.available) {
// Bypass NSURLSession delegate
var resolver = new ApiResolver("objc");
resolver.enumerateMatches(
"-[* URLSession:didReceiveChallenge:completionHandler:]", {
onMatch: function(match) {
Interceptor.attach(match.address, {
onEnter: function(args) {
var completionHandler = new ObjC.Block(args[4]);
var NSURLSessionAuthChallengeUseCredential = 0;
var trust = new ObjC.Object(args[3])
.protectionSpace().serverTrust();
var credential = ObjC.classes.NSURLCredential
.credentialForTrust_(trust);
completionHandler.invoke(NSURLSessionAuthChallengeUseCredential,
credential);
}
});
},
onComplete: function() {}
});
// Bypass SecTrustEvaluate
var SecTrustEvaluateWithError = Module.findExportByName(
"Security", "SecTrustEvaluateWithError");
if (SecTrustEvaluateWithError) {
Interceptor.replace(SecTrustEvaluateWithError, new NativeCallback(
function(trust, error) {
return 1; // Always return true
}, "bool", ["pointer", "pointer"]
));
}
console.log("[*] iOS SSL pinning bypass loaded");
}
步骤 4:处理高级固定
对于使用高级固定(TrustKit、自定义二进制检查)的应用:
# Identify the specific pinning library
frida-trace -U -n TargetApp -m "*[*Trust*]" -m "*[*Pin*]" -m "*[*SSL*]" -m "*[*Certificate*]"
# Hook the identified validation function
# Custom Frida script targeting the specific implementation
步骤 5:验证绕过成功
应用绕过之后:
- 将设备代理配置为 Burp Suite
- 打开目标应用并浏览经认证的流程
- 验证 HTTPS 流量出现在 Burp Suite HTTP History 中
- 检查是否有任何未被捕获的剩余固定连接
关键概念
| 术语 | 定义 |
|---|---|
| 证书固定 | 将接受的服务器证书限制为已知集合,防止通过恶意 CA 证书进行 MITM |
| 公钥固定 | 固定服务器的公钥哈希而非完整证书,可在证书轮换后继续有效 |
| 网络安全配置 | Android XML 配置,用于按域声明信任锚、固定和明文策略 |
| TrustKit | 实现证书固定并为 Android 和 iOS 提供报告的开源库 |
| HPKP 弃用 | HTTP Public Key Pinning 头已在浏览器中弃用,但该概念在移动应用中仍然存在 |
工具与系统
- Objection:针对常见库(OkHttp、NSURLSession、TrustKit)的预构建固定绕过
- Frida:针对特定固定实现的自定义 JavaScript hook
- apktool:用于在网络安全配置中识别固定的 APK 反编译
- SSLUnpinning (Xposed):用于 Android 上系统范围固定绕过的 Xposed 框架模块
- ssl-kill-switch2:用于在已越狱设备上系统范围禁用 SSL 固定的 iOS 调整
常见陷阱
- 证书透明度:一些应用除了固定之外还会检查 CT 日志。可能需要单独绕过 CT 验证。
- 多层固定:应用可能在多个层级实现固定(OkHttp + 自定义 TrustManager)。绕过所有层级。
- 二进制级固定:一些应用在原生 C/C++ 代码中验证证书,这需要在原生函数地址处使用 Interceptor.attach,而不是 Java/ObjC hook。
- 动态固定更新:使用 TrustKit 或类似工具的应用可能会从服务器获取更新的固定。在测试期间监控固定轮换。
评论
支持 Markdown