首页
社区
课程
招聘
[分享]hook抓包的风控解决方案
2023-8-13 19:43 11740

[分享]hook抓包的风控解决方案

2023-8-13 19:43
11740

0x01 前言

抓包应该是我们逆向的第一步,只有先抓到包,才能决定我们是否要进行脱壳、逆向。万一他没有加密、万一数据不是我们想要的那岂不是白忙活了。但是目前很APP都设置了门槛,比如新版的抖音、淘宝、天眼查等挂上代理就直接无数据或者就显示不出你想要的数据。还没有开始就直接结束了,让人懊恼不已。没办法只能上科技与狠活了。(感谢r0ysue肉师傅,以下很多素材都来源于他)

0x02 普通验证型

这个一般我们设置好IP和端口,导入证书不出意外是没问题。常见的抓包工具fiddler、charles、Burpsuite、httpcanary

0x03 双向验证型

针对双向证书绑定的APP,打印和保存证书,再导入到抓包工具中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
function hook_KeyStore_load() {
    Java.perform(function () {
        var ByteString = Java.use("com.android.okhttp.okio.ByteString");
        var myArray = new Array(1024);
        var i = 0
        for (i = 0; i < myArray.length; i++) {
            myArray[i] = 0x0;
        }
        var buffer = Java.array('byte', myArray);
        var StringClass = Java.use("java.lang.String");
        var KeyStore = Java.use("java.security.KeyStore");
        KeyStore.load.overload('java.security.KeyStore$LoadStoreParameter').implementation = function (arg0) {
            //可以在此打印调用栈观察信息
            console.log("KeyStore.load1:", arg0);
            this.load(arg0);
        };
        KeyStore.load.overload('java.io.InputStream', '[C').implementation = function (arg0, arg1) {
            //可以在此打印调用栈观察信息
            console.log("KeyStore.load2:", arg0, arg1 ? StringClass.$new(arg1) : null);
 
            if (arg0) {
                var file = Java.use("java.io.File").$new("/sdcard/Download/" + String(arg0) + ".p12");
                var out = Java.use("java.io.FileOutputStream").$new(file);
                var r;
                while ((r = arg0.read(buffer)) > 0) {
                    out.write(buffer, 0, r)
                }
                console.log("save success!")
                out.close()
            }
            this.load(arg0, arg1);
        };
        console.log("hook_KeyStore_load...");
 
    });
}

将证书导出后,charles进行证书配置。
图片描述

ssl pinning 证书在代码中的额外校验:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function hook_ssl() {
    Java.perform(function () {
        var ClassName = "com.android.org.conscrypt.Platform";
        var Platform = Java.use(ClassName);
        var targetMethod = "checkServerTrusted";
        var len = Platform[targetMethod].overloads.length;
        console.log(len);
        for (var i = 0; i < len; ++i) {
            Platform[targetMethod].overloads[i].implementation = function () {
                console.log("class:", ClassName, "target:", targetMethod, " i:", i, arguments);
            }
        }
    });
}

objection SSL

objection 中的 Bypass SSL pinning hook的证书种类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
sslContextEmptyTrustManager
    const x509TrustManager: X509TrustManager = Java.use("javax.net.ssl.X509TrustManager");
    const sSLContext: SSLContext = Java.use("javax.net.ssl.SSLContext");
 
okHttp3CertificatePinnerCheck
    const certificatePinner: CertificatePinner = Java.use("okhttp3.CertificatePinner");
 
okHttp3CertificatePinnerCheckOkHttp
    const certificatePinner: CertificatePinner = Java.use("okhttp3.CertificatePinner");
 
appceleratorTitaniumPinningTrustManager
   const pinningTrustManager: PinningTrustManager = Java.use("appcelerator.https.PinningTrustManager");
 
//Android 7+ TrustManagerImpl.verifyChain()
trustManagerImplVerifyChainCheck
    const trustManagerImpl: TrustManagerImpl = Java.use("com.android.org.conscrypt.TrustManagerImpl");
    const TrustManagerImplverifyChain = trustManagerImpl.verifyChain;
 
// Android 7+ TrustManagerImpl.checkTrustedRecursive()
trustManagerImplCheckTrustedRecursiveCheck
    const trustManagerImpl: TrustManagerImpl = Java.use("com.android.org.conscrypt.TrustManagerImpl");
    const TrustManagerImplcheckTrustedRecursive = trustManagerImpl.checkTrustedRecursive;
 
phoneGapSSLCertificateChecker
    const sslCertificateChecker: SSLCertificateChecker = Java.use("nl.xservices.plugins.SSLCertificateChecker");

DroidSSLUnpinning

DroidSSLUnpinning 这个工具是WooyunDota瘦蛟舞大佬总结的,github上有源码,以下我也贴出来了,他总结了一些常见的证书过检测的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
Java.perform(function() {
 
/*
hook list:
1.SSLcontext
2.okhttp
3.webview
4.XUtils
5.httpclientandroidlib
6.JSSE
7.network\_security\_config (android 7.0+)
8.Apache Http client (support partly)
9.OpenSSLSocketImpl
10.TrustKit
11.Cronet
*/
 
    // Attempts to bypass SSL pinning implementations in a number of
    // ways. These include implementing a new TrustManager that will
    // accept any SSL certificate, overriding OkHTTP v3 check()
    // method etc.
    var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
    var HostnameVerifier = Java.use('javax.net.ssl.HostnameVerifier');
    var SSLContext = Java.use('javax.net.ssl.SSLContext');
    var quiet_output = false;
 
    // Helper method to honor the quiet flag.
 
    function quiet_send(data) {
        if (quiet_output) {
            return;
        }
        send(data)
    }
 
    // Implement a new TrustManager
    // ref: https://gist.github.com/oleavr/3ca67a173ff7d207c6b8c3b0ca65a9d8
    // Java.registerClass() is only supported on ART for now(201803). 所以android 4.4以下不兼容,4.4要切换成ART使用.
    var X509Certificate = Java.use("java.security.cert.X509Certificate");
    var TrustManager;
    try {
        TrustManager = Java.registerClass({
            name: 'org.wooyun.TrustManager',
            implements: [X509TrustManager],
            methods: {
                checkClientTrusted: function(chain, authType) {},
                checkServerTrusted: function(chain, authType) {},
                getAcceptedIssuers: function() {
                    // var certs = [X509Certificate.$new()];
                    // return certs;
                    return [];
                }
            }
        });
    } catch (e) {
        quiet_send("registerClass from X509TrustManager >>>>>>>> " + e.message);
    }
 
    // Prepare the TrustManagers array to pass to SSLContext.init()
    var TrustManagers = [TrustManager.$new()];
 
    try {
        // Prepare a Empty SSLFactory
        var TLS_SSLContext = SSLContext.getInstance("TLS");
        TLS_SSLContext.init(null, TrustManagers, null);
        var EmptySSLFactory = TLS_SSLContext.getSocketFactory();
    } catch (e) {
        quiet_send(e.message);
    }
 
    send('Custom, Empty TrustManager ready');
 
    // Get a handle on the init() on the SSLContext class
    var SSLContext_init = SSLContext.init.overload(
        '[Ljavax.net.ssl.KeyManager;', '[Ljavax.net.ssl.TrustManager;', 'java.security.SecureRandom');
 
    // Override the init method, specifying our new TrustManager
    SSLContext_init.implementation = function(keyManager, trustManager, secureRandom) {
 
        quiet_send('Overriding SSLContext.init() with the custom TrustManager');
 
        SSLContext_init.call(this, null, TrustManagers, null);
    };
 
    /*** okhttp3.x unpinning ***/
 
 
    // Wrap the logic in a try/catch as not all applications will have
    // okhttp as part of the app.
    try {
 
        var CertificatePinner = Java.use('okhttp3.CertificatePinner');
 
        quiet_send('OkHTTP 3.x Found');
 
        CertificatePinner.check.overload('java.lang.String', 'java.util.List').implementation = function() {
 
            quiet_send('OkHTTP 3.x check() called. Not throwing an exception.');
        }
 
    } catch (err) {
 
        // If we dont have a ClassNotFoundException exception, raise the
        // problem encountered.
        if (err.message.indexOf('ClassNotFoundException') === 0) {
 
            throw new Error(err);
        }
    }
 
    // Appcelerator Titanium PinningTrustManager
 
    // Wrap the logic in a try/catch as not all applications will have
    // appcelerator as part of the app.
    try {
 
        var PinningTrustManager = Java.use('appcelerator.https.PinningTrustManager');
 
        send('Appcelerator Titanium Found');
 
        PinningTrustManager.checkServerTrusted.implementation = function() {
 
            quiet_send('Appcelerator checkServerTrusted() called. Not throwing an exception.');
        }
 
    } catch (err) {
 
        // If we dont have a ClassNotFoundException exception, raise the
        // problem encountered.
        if (err.message.indexOf('ClassNotFoundException') === 0) {
 
            throw new Error(err);
        }
    }
 
    /*** okhttp unpinning ***/
 
 
    try {
        var OkHttpClient = Java.use("com.squareup.okhttp.OkHttpClient");
        OkHttpClient.setCertificatePinner.implementation = function(certificatePinner) {
            // do nothing
            quiet_send("OkHttpClient.setCertificatePinner Called!");
            return this;
        };
 
        // Invalidate the certificate pinnet checks (if "setCertificatePinner" was called before the previous invalidation)
        var CertificatePinner = Java.use("com.squareup.okhttp.CertificatePinner");
        CertificatePinner.check.overload('java.lang.String', '[Ljava.security.cert.Certificate;').implementation = function(p0, p1) {
            // do nothing
            quiet_send("okhttp Called! [Certificate]");
            return;
        };
        CertificatePinner.check.overload('java.lang.String', 'java.util.List').implementation = function(p0, p1) {
            // do nothing
            quiet_send("okhttp Called! [List]");
            return;
        };
    } catch (e) {
        quiet_send("com.squareup.okhttp not found");
    }
 
    /*** WebView Hooks ***/
 
    /* frameworks/base/core/java/android/webkit/WebViewClient.java */
    /* public void onReceivedSslError(Webview, SslErrorHandler, SslError) */
    var WebViewClient = Java.use("android.webkit.WebViewClient");
 
    WebViewClient.onReceivedSslError.implementation = function(webView, sslErrorHandler, sslError) {
        quiet_send("WebViewClient onReceivedSslError invoke");
        //执行proceed方法
        sslErrorHandler.proceed();
        return;
    };
 
    WebViewClient.onReceivedError.overload('android.webkit.WebView', 'int', 'java.lang.String', 'java.lang.String').implementation = function(a, b, c, d) {
        quiet_send("WebViewClient onReceivedError invoked");
        return;
    };
 
    WebViewClient.onReceivedError.overload('android.webkit.WebView', 'android.webkit.WebResourceRequest', 'android.webkit.WebResourceError').implementation = function() {
        quiet_send("WebViewClient onReceivedError invoked");
        return;
    };
 
    /*** JSSE Hooks ***/
 
    /* libcore/luni/src/main/java/javax/net/ssl/TrustManagerFactory.java */
    /* public final TrustManager[] getTrustManager() */
    /* TrustManagerFactory.getTrustManagers maybe cause X509TrustManagerExtensions error  */
    // var TrustManagerFactory = Java.use("javax.net.ssl.TrustManagerFactory");
    // TrustManagerFactory.getTrustManagers.implementation = function(){
    //     quiet_send("TrustManagerFactory getTrustManagers invoked");
    //     return TrustManagers;
    // }
 
    var HttpsURLConnection = Java.use("javax.net.ssl.HttpsURLConnection");
    /* libcore/luni/src/main/java/javax/net/ssl/HttpsURLConnection.java */
    /* public void setDefaultHostnameVerifier(HostnameVerifier) */
    HttpsURLConnection.setDefaultHostnameVerifier.implementation = function(hostnameVerifier) {
        quiet_send("HttpsURLConnection.setDefaultHostnameVerifier invoked");
        return null;
    };
    /* libcore/luni/src/main/java/javax/net/ssl/HttpsURLConnection.java */
    /* public void setSSLSocketFactory(SSLSocketFactory) */
    HttpsURLConnection.setSSLSocketFactory.implementation = function(SSLSocketFactory) {
        quiet_send("HttpsURLConnection.setSSLSocketFactory invoked");
        return null;
    };
    /* libcore/luni/src/main/java/javax/net/ssl/HttpsURLConnection.java */
    /* public void setHostnameVerifier(HostnameVerifier) */
    HttpsURLConnection.setHostnameVerifier.implementation = function(hostnameVerifier) {
        quiet_send("HttpsURLConnection.setHostnameVerifier invoked");
        return null;
    };
 
    /*** Xutils3.x hooks ***/
    //Implement a new HostnameVerifier
    var TrustHostnameVerifier;
    try {
        TrustHostnameVerifier = Java.registerClass({
            name: 'org.wooyun.TrustHostnameVerifier',
            implements: [HostnameVerifier],
            method: {
                verify: function(hostname, session) {
                    return true;
                }
            }
        });
 
    } catch (e) {
        //java.lang.ClassNotFoundException: Didn't find class "org.wooyun.TrustHostnameVerifier"
        quiet_send("registerClass from hostnameVerifier >>>>>>>> " + e.message);
    }
 
    try {
        var RequestParams = Java.use('org.xutils.http.RequestParams');
        RequestParams.setSslSocketFactory.implementation = function(sslSocketFactory) {
            sslSocketFactory = EmptySSLFactory;
            return null;
        }
 
        RequestParams.setHostnameVerifier.implementation = function(hostnameVerifier) {
            hostnameVerifier = TrustHostnameVerifier.$new();
            return null;
        }
 
    } catch (e) {
        quiet_send("Xutils hooks not Found");
    }
 
    /*** httpclientandroidlib Hooks ***/
    try {
        var AbstractVerifier = Java.use("ch.boye.httpclientandroidlib.conn.ssl.AbstractVerifier");
        AbstractVerifier.verify.overload('java.lang.String', '[Ljava.lang.String', '[Ljava.lang.String', 'boolean').implementation = function() {
            quiet_send("httpclientandroidlib Hooks");
            return null;
        }
    } catch (e) {
        quiet_send("httpclientandroidlib Hooks not found");
    }
 
    /***
android 7.0+ network_security_config TrustManagerImpl hook
apache httpclient partly
***/
    var TrustManagerImpl = Java.use("com.android.org.conscrypt.TrustManagerImpl");
    // try {
    //     var Arrays = Java.use("java.util.Arrays");
    //     //apache http client pinning maybe baypass
    //     //https://github.com/google/conscrypt/blob/c88f9f55a523f128f0e4dace76a34724bfa1e88c/platform/src/main/java/org/conscrypt/TrustManagerImpl.java#471
    //     TrustManagerImpl.checkTrusted.implementation = function (chain, authType, session, parameters, authType) {
    //         quiet_send("TrustManagerImpl checkTrusted called");
    //         //Generics currently result in java.lang.Object
    //         return Arrays.asList(chain);
    //     }
    //
    // } catch (e) {
    //     quiet_send("TrustManagerImpl checkTrusted nout found");
    // }
 
    try {
        // Android 7+ TrustManagerImpl
        TrustManagerImpl.verifyChain.implementation = function(untrustedChain, trustAnchorChain, host, clientAuth, ocspData, tlsSctData) {
            quiet_send("TrustManagerImpl verifyChain called");
            // Skip all the logic and just return the chain again :P
            //https://www.nccgroup.trust/uk/about-us/newsroom-and-events/blogs/2017/november/bypassing-androids-network-security-configuration/
            // https://github.com/google/conscrypt/blob/c88f9f55a523f128f0e4dace76a34724bfa1e88c/platform/src/main/java/org/conscrypt/TrustManagerImpl.java#L650
            return untrustedChain;
        }
    } catch (e) {
        quiet_send("TrustManagerImpl verifyChain nout found below 7.0");
    }
    // OpenSSLSocketImpl
    try {
        var OpenSSLSocketImpl = Java.use('com.android.org.conscrypt.OpenSSLSocketImpl');
        OpenSSLSocketImpl.verifyCertificateChain.implementation = function(certRefs, authMethod) {
            quiet_send('OpenSSLSocketImpl.verifyCertificateChain');
        }
 
        quiet_send('OpenSSLSocketImpl pinning')
    } catch (err) {
        quiet_send('OpenSSLSocketImpl pinner not found');
    }
    // Trustkit
    try {
        var Activity = Java.use("com.datatheorem.android.trustkit.pinning.OkHostnameVerifier");
        Activity.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function(str) {
            quiet_send('Trustkit.verify1: ' + str);
            return true;
        };
        Activity.verify.overload('java.lang.String', 'java.security.cert.X509Certificate').implementation = function(str) {
            quiet_send('Trustkit.verify2: ' + str);
            return true;
        };
 
        quiet_send('Trustkit pinning')
    } catch (err) {
        quiet_send('Trustkit pinner not found')
    }
 
    try {
        //cronet pinner hook
        //weibo don't invoke
 
        var netBuilder = Java.use("org.chromium.net.CronetEngine$Builder");
 
        //https://developer.android.com/guide/topics/connectivity/cronet/reference/org/chromium/net/CronetEngine.Builder.html#enablePublicKeyPinningBypassForLocalTrustAnchors(boolean)
        netBuilder.enablePublicKeyPinningBypassForLocalTrustAnchors.implementation = function(arg) {
 
            //weibo not invoke
            console.log("Enables or disables public key pinning bypass for local trust anchors = " + arg);
 
            //true to enable the bypass, false to disable.
            var ret = netBuilder.enablePublicKeyPinningBypassForLocalTrustAnchors.call(this, true);
            return ret;
        };
 
        netBuilder.addPublicKeyPins.implementation = function(hostName, pinsSha256, includeSubdomains, expirationDate) {
            console.log("cronet addPublicKeyPins hostName = " + hostName);
 
            //var ret = netBuilder.addPublicKeyPins.call(this,hostName, pinsSha256,includeSubdomains, expirationDate);
            //this 是调用 addPublicKeyPins 前的对象吗? Yes,CronetEngine.Builder
            return this;
        };
 
    } catch (err) {
        console.log('[-] Cronet pinner not found')
    }
});

使用方法:
1 attach : frida -U com.example.mennomorsink.webviewtest2 --no-pause -l hooks.js
2 spawn : frida -U -f com.example.mennomorsink.webviewtest2 -l hooks.js --no-pause

混淆

如果APP出现了混淆,使用 objection、DroidSSLUnpinning都无法成功hook住,首先不要慌,我们的目标还是先搞清楚他用的是什么框架。可以hook java.io.File类,因为校验证书的过程中,必然要打开它,通过打印的调栈再结合源码可以分析出到底使用了什么框架。

1
android hooking watch class_method  java.io.File.$init --dump-args --dump-backtrace --dump-return

0x04 r0capture

r0capture安卓应用层抓包通杀脚本这个工具比较厉害,无视所有证书校验或绑定,不用考虑任何证书的事情。
Spawn 模式:
python3 r0capture.py -U -f com.coolapk.market -v

Attach 模式,抓包内容保存成pcap文件供后续分析:
python3 r0capture.py -U 酷安 -v -p iqiyi.pcap
图片描述


[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

最后于 2024-1-3 17:49 被西贝巴巴编辑 ,原因: 修改标题
收藏
免费 4
打赏
分享
最新回复 (11)
雪    币: 21012
活跃值: (30261)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
秋狝 2023-8-13 22:44
2
1
感谢分享
雪    币: 1058
活跃值: (760)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
TrumpWY 2023-8-14 10:55
3
0
直接lamda
雪    币: 47
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
乐在囧途 2023-8-30 09:32
4
0
dy怎么绕过啊
雪    币: 19
活跃值: (568)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hmlyn 2023-8-31 19:31
5
0
你好博主,我有一个APP也很苦恼,抓不到,有偿能帮我分析下吗?预算1000元
企鹅:876529930
样品下载地址:https://game.xiaomi.com
就是这个游戏中心APP。
雪    币: 3714
活跃值: (4984)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
西贝巴巴 2023-9-1 08:49
6
0
乐在囧途 dy怎么绕过啊
dy也是双向证书绑定,他在so文件里面做了校验,要修改后再重新打包,即可
雪    币: 835
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
hcf233 2023-9-19 14:00
7
0
hmlyn 你好博主,我有一个APP也很苦恼,抓不到,有偿能帮我分析下吗?预算1000元 企鹅:876529930 样品下载地址:https://game.xiaomi.com 就是这个游戏中心APP。[e ...
你要抓小米的干啥
雪    币: 2723
活跃值: (5130)
能力值: ( LV11,RANK:185 )
在线值:
发帖
回帖
粉丝
Thehepta 3 2023-9-19 17:09
8
0
双端证书校验,不是指的的是服务器两端都有各自指定的证书吗,你用chales做代理,请问,chales中间人代理服务器,发送给本地的证书,如何过app本地的服务端校验
雪    币: 3714
活跃值: (4984)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
西贝巴巴 2023-9-20 08:46
9
0
Thehepta 双端证书校验,不是指的的是服务器两端都有各自指定的证书吗,你用chales做代理,请问,chales中间人代理服务器,发送给本地的证书,如何过app本地的服务端校验
应用程序在进行SSL/TLS通信时启用了双端证书验证,将会拒绝与Charles之类的中间人进行通信,攻击者需要欺骗应用程序接受伪造证书,这通常需要在应用程序或操作系统中添加根证书或信任受信任的根证书颁发机构(CA),可以将APP本地的校验的证书,导入到Charles,只要行为一致,则可以进行通信。
雪    币: 4300
活跃值: (1460)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
pizazzboy 2023-9-20 09:27
10
0
感谢分离经验。
雪    币: 2723
活跃值: (5130)
能力值: ( LV11,RANK:185 )
在线值:
发帖
回帖
粉丝
Thehepta 3 2023-9-20 19:46
11
0
西贝巴巴 应用程序在进行SSL/TLS通信时启用了双端证书验证,将会拒绝与Charles之类的中间人进行通信,攻击者需要欺骗应用程序接受伪造证书,这通常需要在应用程序或操作系统中添加根证书或信任受信任的根证书颁 ...
你说的是,服务端对客户端的证书验证,你是通过将客户端的证书导入到chales, 客户端对服务端的证书验证,是通过注入客户端,修改他的认证部分代码是吗
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
逆向小白鼠 2024-2-5 15:09
12
0
大佬请问某宝的 水果滑块图片怎么抓啊
游客
登录 | 注册 方可回帖
返回