performing-mobile-app-certificate-pinning-bypass について
モバイルアプリの証明書ピンニングを回避し、Burp SuiteでHTTPS通信を検査するセキュリティテストスキルです。ObjectionとカスタムFridaフックを使うAndroid・iOSの手順を扱い、許可を得たアプリテストを対象とします。
主な機能
- 01Android・iOSのピンニング方式の特定
- 02Objectionによる一般的な回避
- 03カスタムFridaフックの作成
- 04高度なピンニング実装の追跡
- 05Burp 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 をプロキシとして設定していること
- ルート化された 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 は、OkHttp CertificatePinner、TrustManagerImpl、NSURLSession のデリゲートメソッド、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 フックです
- apktool:Network Security Config 内のピンニングを特定するための APK 逆コンパイルツールです
- SSLUnpinning (Xposed):Android でシステム全体のピンニングをバイパスするための Xposed フレームワークモジュールです
- ssl-kill-switch2:ジェイルブレイクされたデバイスでシステム全体の SSL ピンニングを無効にする iOS 用調整ツールです
よくある落とし穴
- 証明書の透明性:ピンニングに加えて CT ログをチェックするアプリもあります。CT 検証も別途バイパスする必要がある場合があります。
- 多層ピンニング:アプリは複数の層(OkHttp + カスタム TrustManager)でピンニングを実装していることがあります。すべての層をバイパスしてください。
- バイナリレベルのピンニング:証明書をネイティブの C/C++ コードで検証するアプリもあります。この場合、Java/ObjC のフックではなく、ネイティブ関数アドレスに対する Interceptor.attach が必要です。
- 動的なピンニング更新:TrustKit などを使うアプリは、更新されたピンをサーバーから取得する場合があります。テスト中はピンのローテーションを監視してください。
コメント
Markdown 対応