一、前置知識(shí)
-
默認(rèn)你了解了HTTPS中間人攻擊的流程,再來回顧一下這個(gè)圖:
-
網(wǎng)絡(luò)在傳輸過程中一般不會(huì)被監(jiān)控解密,但是通過中間人進(jìn)行攻擊(也就是抓包)可以解密這個(gè)傳輸流程。
-
其實(shí)如果不進(jìn)行客戶端安裝證書,也是可以抓包的,但是沒有信任的證書相當(dāng)于就是在路由上走一次,并沒有加解密過程,實(shí)際上還是客戶端與服務(wù)器端進(jìn)行加解密通信
-
-
這個(gè)中間人自己生成的證書在中間進(jìn)行加解密與雙方進(jìn)行通信。
二、核心知識(shí)點(diǎn)
2.1 證書安裝
-
了解了中間人的攻擊流程,也就知道了關(guān)鍵是這個(gè)證書,證書被校驗(yàn)成功即可以進(jìn)行雙向的傳輸解密
-
安卓7以后安裝的證書是放在用戶目錄的,并不能被系統(tǒng)信任,所以無法加解密流量。
-
-
大多數(shù)抓不到包的原因就是證書安裝了,但是在用戶目錄
-
解決方法:
-
1
使用MT管理器
把用戶目錄的證書移動(dòng)到系統(tǒng)證書目錄(據(jù)說可以支持到安卓10)-
用戶證書文件目錄
/data/misc/user/0/cacerts-added/
-
系統(tǒng)證書目錄
/etc/security/cacerts/
-
-
2 由于 Android 10 采用了某些安全策略,將系統(tǒng)分區(qū)
/system掛載為只讀
,就算你 root 了也沒用,無法寫入系統(tǒng)分區(qū)也就無法導(dǎo)入系統(tǒng)證書-
解決:使用Move Certificates模塊
-
https://github.com/Magisk-Modules-Repo/movecert
-
-
3 修改源碼默認(rèn)信任用戶證書(提供幾個(gè)檢測(cè)的源碼定位代碼)
-
-
-
到此安裝完證書 使用抓包工具(charles、fidder、Burpsuit等)就可以進(jìn)行抓包了
-
但是我們使用的證書是中間人的證書 不是服務(wù)器直接下發(fā)的證書所以只能解決80%的HTTPS抓包問題。
三、SSLPinning環(huán)境下如何抓包
3.1 證書校驗(yàn)——SSL證書綁定
上文可以了解到從 HTTP 到 HTTPS 數(shù)據(jù)在傳輸過程中添加了一層 加密(SSL/TLS),讓我們數(shù)據(jù)流量處于加密狀態(tài),不再是明文可見。一旦 app 校驗(yàn)了證書的指紋信息。我們的證書不再受信任了。自然而然就無法建立連接,所以必須想辦法讓 app 信任,才能繼續(xù)抓包。當(dāng)然這個(gè)分為兩種情況:
3.1.1客戶端校驗(yàn)服務(wù)器端的證書
上篇文件提到了一個(gè)證書包含了很多信息,那么客戶端校驗(yàn)的原理就是:
在APP中預(yù)先設(shè)置好證書的信息,在證書校驗(yàn)階段時(shí)與服務(wù)器返回的證書信息進(jìn)行比較。
-
一般會(huì)有以下整數(shù)的信息會(huì)被校驗(yàn),每種校驗(yàn)的方式這里就不展開了,下一篇文件在詳細(xì)研究。
-
公鑰校驗(yàn)
-
證書校驗(yàn)
-
Host校驗(yàn)
-
-
如何繞過?(未混淆的情況)
-
因?yàn)楸举|(zhì)上校驗(yàn)是在客戶端中完成的,所以客戶端中肯定會(huì)有相關(guān)的校驗(yàn)代碼,我們找到校驗(yàn)的地方進(jìn)行HOOK,使得校驗(yàn)的地方直接PASS。這里方法列舉,暫時(shí)不展開,下一篇文件在詳細(xì)研究。加好友hackctf55進(jìn)交流群。
-
frida hook(見下面)
-
JustTrustMe(xposed的Hook腳本)
-
https://github.com/LSPosed/LSPosed/releases
-
https://github.com/Fuzion24/JustTrustMe/releases/tag/v.2
-
安裝后無圖標(biāo)
-
去手機(jī)的
/data/adb/lspd/
目錄下找apk包,然后再點(diǎn)擊安裝即可。
-
-
探索開發(fā)邏輯
1 公鑰校驗(yàn)
-
這里我把52pj的證書公鑰寫進(jìn)app進(jìn)行校驗(yàn)實(shí)驗(yàn)
private void doRequest(){
new Thread(){
@Override
public void run() {
final String CA_PUBLIC_KEY = "sha256/kO7OP94daK9P8+X52s00RvJLU0SiCXA9KAg9PelfwIw=";
final String CA_DOMAIN = "www.52pojie.cn";
//校驗(yàn)公鑰
CertificatePinner buildPinner = new CertificatePinner.Builder()
.add(CA_DOMAIN, CA_PUBLIC_KEY)
.build();
OkHttpClient client = new OkHttpClient.Builder().certificatePinner(buildPinner).build();
Request req = new Request.Builder().url("https://www.52pojie.cn/forum.php")
.build();
Call call = client.newCall(req);
try {
Response res = call.execute();
Log.e("請(qǐng)求成功", "狀態(tài)碼:" + res.code());
} catch (IOException e) {
e.printStackTrace();
Log.e("請(qǐng)求失敗", "異常" + e);
}
}
}.start();
}
-
安裝好charles的證書后發(fā)現(xiàn)抓包就不好使了
-
證書公鑰校驗(yàn)的代碼 一般來說是使用同的網(wǎng)絡(luò)請(qǐng)求框架,大多都是Okhttp3
CertificatePinner buildPinner = new CertificatePinner.Builder()
.add(CA_DOMAIN, CA_PUBLIC_KEY)
.build();
//將buildPinner 傳給OkHttpclient
OkHttpClient client = new OkHttpClient.Builder()
.certificatePinner(buildPinner)
.build();
-
查看
certificatePinner(buildPinner)
的代碼邏輯,使用frida hook把返回值空即可
public void check(String hostname, List peerCertificates)
throws SSLPeerUnverifiedException {
List pins = findMatchingPins(hostname);
if (pins.isEmpty()) return;
if (certificateChainCleaner != null) {
peerCertificates = certificateChainCleaner.clean(peerCertificates, hostname);
}
for (int c = 0, certsSize = peerCertificates.size(); c < certsSize; c++) {
X509Certificate x509Certificate = (X509Certificate) peerCertificates.get(c);
// Lazily compute the hashes for each certificate.
ByteString sha1 = null;
ByteString sha256 = null;
for (int p = 0, pinsSize = pins.size(); p < pinsSize; p++) {
Pin pin = pins.get(p);
if (pin.hashAlgorithm.equals("sha256/")) {
if (sha256 == null) sha256 = sha256(x509Certificate);
if (pin.hash.equals(sha256)) return; // Success!
} else if (pin.hashAlgorithm.equals("sha1/")) {
if (sha1 == null) sha1 = sha1(x509Certificate);
if (pin.hash.equals(sha1)) return; // Success!
} else {
throw new AssertionError("unsupported hashAlgorithm: " + pin.hashAlgorithm);
}
}
}
-
frida 腳本片段
// Bypass OkHTTPv3 {1}
var okhttp3_Activity_1 = Java.use('okhttp3.CertificatePinner');
okhttp3_Activity_1.check.overload('java.lang.String', 'java.util.List').implementation = function(a, b) {
console.log('[+] Bypassing OkHTTPv3 {1}: ' + a);
return;
2 證書校驗(yàn)
private void doRequest2(){
X509TrustManager trustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
//服務(wù)器返回的證書
X509Certificate cf = chain[0];
//轉(zhuǎn)換為RSA的公鑰
RSAPublicKey rsaPublicKey = (RSAPublicKey) cf.getPublicKey();
//Base64 encode
String ServerPubkey = Base64.encodeToString(rsaPublicKey.getEncoded(), 0);
Log.e("服務(wù)器端返回的證書",ServerPubkey);
//讀取客戶端資源目錄中的證書
InputStream client_input = getResources().openRawResource(R.raw.pojie);
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
X509Certificate realCertificate = (X509Certificate) certificateFactory.generateCertificate(client_input);
String realPubkey = Base64.encodeToString(realCertificate.getPublicKey().getEncoded(), 0);
Log.e("客戶端資源目錄中的證書",realPubkey);
cf.checkValidity();
final boolean expected = realPubkey.equalsIgnoreCase(ServerPubkey);
Log.e("eq = ",String.valueOf(expected));
if (!expected){
throw new CertificateException("證書不一致");
}
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
};
SSLSocketFactory factory = null;
try {
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null,new TrustManager[]{trustManager},new SecureRandom());
factory = sslContext.getSocketFactory();
} catch (Exception e) {
e.printStackTrace();
}
SSLSocketFactory finalFactory = factory;
new Thread(){
@Override
public void run() {
try {
OkHttpClient client = new OkHttpClient.Builder().sslSocketFactory(finalFactory, trustManager).build();
Request req = new Request.Builder().url("https://www.52pojie.cn/forum.php").build();
Call call = client.newCall(req);
Response res = call.execute();
Log.e("請(qǐng)求發(fā)送成功","狀態(tài)碼:" + res.code());
} catch (IOException e) {
Log.e("請(qǐng)求發(fā)送失敗","網(wǎng)絡(luò)異常" + e);
}
}
}.start();
}
X509TrustManager trustManager = new X509TrustManager() {
...
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {
...
}
....
}
var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
var SSLContext = Java.use('javax.net.ssl.SSLContext');
// TrustManager (Android < 7) //
////////////////////////////////
var TrustManager = Java.registerClass({
// Implement a custom TrustManager
name: 'dev.asd.test.TrustManager',
implements: [X509TrustManager],
methods: {
checkClientTrusted: function(chain, authType) {},
checkServerTrusted: function(chain, authType) {},
getAcceptedIssuers: function() {return []; }
}
});
// Prepare the TrustManager array to pass to SSLContext.init()
var TrustManagers = [TrustManager.$new()];
// 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');
try {
// Override the init method, specifying the custom TrustManager
SSLContext_init.implementation = function(keyManager, trustManager, secureRandom) {
console.log('[+] Bypassing Trustmanager (Android < 7) pinner');
SSLContext_init.call(this, keyManager, TrustManagers, secureRandom);
};
} catch (err) {
console.log('[-] TrustManager (Android < 7) pinner not found');
//console.log(err);
}
-
-
-
不用的請(qǐng)求框架 代碼不一樣需要看情況編寫
-
-
內(nèi)置證書到資源文件目錄
-
抓包測(cè)試
-
校驗(yàn)的核心邏輯:自定義的
trustManager
類實(shí)現(xiàn)的checkServerTrusted接口
-
繞過:
-
這個(gè)一般是自定義的類然后實(shí)現(xiàn)了這個(gè)trustManager的接口 ,所以不確定這個(gè)類在哪,不容易hook
-
但是定義好trustManager會(huì)傳入以下倆地方
-
思路是這樣:實(shí)例化一個(gè)trustManager類,然后里面什么都不寫,當(dāng)上面兩處調(diào)用到這個(gè)類時(shí)hook這兩個(gè)地方,把自己定義的空trustManager類放進(jìn)去,這樣就可以繞過,參考下面的frida腳本
-
3host(域名)校驗(yàn)
-
背景:一個(gè)證書可能對(duì)應(yīng)有很多域名都可以使用,但是開發(fā)者只想讓當(dāng)前的應(yīng)用證書校驗(yàn)通過后只能往指定的域名發(fā)送請(qǐng)求,而不想證書校驗(yàn)通過后往其他可以校驗(yàn)證書通過的域名發(fā)送請(qǐng)求。(證書允許往很多域名發(fā)送請(qǐng)求,但是app限制只能往特定域名發(fā)送請(qǐng)求)
private void doRequest3(){
HostnameVerifier verifier = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
if ("www.52pojie.cn".equalsIgnoreCase(hostname)){
return true;
}
return false;
}
};
new Thread() {
@Override
public void run() {
try {
OkHttpClient client = new OkHttpClient.Builder().hostnameVerifier(verifier).build();
Request req = new Request.Builder().url("https://www.52pojie.cn/forum.php").build();
Call call = client.newCall(req);
Response res = call.execute();
Log.e("請(qǐng)求發(fā)送成功", "狀態(tài)碼:" + res.code());
} catch (IOException ex) {
Log.e("Main", "網(wǎng)絡(luò)請(qǐng)求異常" + ex);
}
}
}.start();
}
-
-
繞過方式和證書校驗(yàn)思路一樣 自己創(chuàng)建一個(gè)HostnameVerifier類實(shí)現(xiàn)的接口直接返回true,哪里調(diào)用傳給哪里即可。加好友hackctf55進(jìn)交流群。
-
3.1.2 服務(wù)器端證書校驗(yàn)
在客戶端放入證書(p12/bks),客戶端向服務(wù)端發(fā)送請(qǐng)求時(shí),攜帶證書信息,在服務(wù)端會(huì)校驗(yàn)客戶端攜帶過來的證書合法性
private void doRequest4(){
X509TrustManager trustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
};
HostnameVerifier verify = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
new Thread(){
@Override
public void run() {
try {
InputStream client_input = getResources().openRawResource(R.raw.client);
Log.e("x",client_input.getClass().toString());
SSLContext sslContext = SSLContext.getInstance("TLS");
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(client_input, "demoli666".toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, "demoli666".toCharArray());
sslContext.init(keyManagerFactory.getKeyManagers(), new TrustManager[]{trustManager}, new SecureRandom());
SSLSocketFactory factory = sslContext.getSocketFactory();
OkHttpClient client = new OkHttpClient.Builder().sslSocketFactory(factory, trustManager).hostnameVerifier(verify).build();
Request req = new Request.Builder().url("https://xxx.xxx.xxx.xxx:443/index").build();
Call call = client.newCall(req);
Response res = call.execute();
Log.e("請(qǐng)求發(fā)送成功","狀態(tài)碼:" + res.code());
} catch (Exception e) {
Log.e("請(qǐng)求發(fā)送失敗","網(wǎng)絡(luò)異常" + e);
}
}
}.start();
}
-
開發(fā)邏輯
-
在APK打包時(shí),將證書放入assets或raw目錄
-
在開發(fā)代碼時(shí),發(fā)送請(qǐng)求讀取證書文件內(nèi)容+證書密碼 攜帶發(fā)送到服務(wù)器端
-
-
標(biāo)志
-
找到證書文件(bsk/p12)
-
通過hook獲取證書相關(guān)密碼
Java.perform(function () {
function uuid(len, radix) {
var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
var uuid = [], i;
radix = radix || chars.length;
if (len) {
// Compact form
for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
} else {
// rfc4122, version 4 form
var r;
// rfc4122 requires these characters
uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
uuid[14] = '4';
// Fill in random data. At i==19 set the high bits of clock sequence as
// per rfc4122, sec. 4.1.5
for (i = 0; i < 36; i++) {
if (!uuid[i]) {
r = 0 | Math.random() * 16;
uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
}
}
}
return uuid.join('');
}
function storeP12(pri, p7, p12Path, p12Password) {
var X509Certificate = Java.use("java.security.cert.X509Certificate")
var p7X509 = Java.cast(p7, X509Certificate);
var chain = Java.array("java.security.cert.X509Certificate", [p7X509])
var ks = Java.use("java.security.KeyStore").getInstance("PKCS12", "BC");
ks.load(null, null);
ks.setKeyEntry("client", pri, Java.use('java.lang.String').$new(p12Password).toCharArray(), chain);
try {
var out = Java.use("java.io.FileOutputStream").$new(p12Path);
ks.store(out, Java.use('java.lang.String').$new(p12Password).toCharArray())
} catch (exp) {
console.log(exp)
}
}
//在服務(wù)器校驗(yàn)客戶端的情形下,幫助dump客戶端證書,并保存為p12的格式,證書密碼為r0ysue
Java.use("java.security.KeyStore$PrivateKeyEntry").getPrivateKey.implementation = function () {
var result = this.getPrivateKey()
var packageName = Java.use("android.app.ActivityThread").currentApplication().getApplicationContext().getPackageName();
storeP12(this.getPrivateKey(), this.getCertificate(), '/sdcard/Download/' + packageName + uuid(10, 16) + '.p12', 'r0ysue');
return result;
}
Java.use("java.security.KeyStore$PrivateKeyEntry").getCertificateChain.implementation = function () {
var result = this.getCertificateChain()
var packageName = Java.use("android.app.ActivityThread").currentApplication().getApplicationContext().getPackageName();
storeP12(this.getPrivateKey(), this.getCertificate(), '/sdcard/Download/' + packageName + uuid(10, 16) + '.p12', 'r0ysue');
return result;
}
});
-
-
將證書導(dǎo)入charles即可正常抓包
-
charles只支持p12證書,若是在app中獲取了bks證書 需要 轉(zhuǎn)換p12
-
可以使用https://keystore-explorer.org/downloads.html來做證書的轉(zhuǎn)換。
-
在使用py構(gòu)造請(qǐng)求時(shí)也需要攜帶這個(gè)證書和密碼
-
四、混淆代碼
1 關(guān)于混淆
-
只需要了解到安卓開發(fā)中,系統(tǒng)包是無法混淆的,例如
java.security.KeyStore
不會(huì)被混淆,但是第三方的包都會(huì)被混淆為a.b.c.v
類似的形式 -
所以在這樣的情況下之前的hook第三方包的腳本都是不通用的
-
客戶端證書校驗(yàn)的frida腳本【不通用】
Java.use('okhttp3.CertificatePinner');
Java.use('com.square.okhttp.internal.tls.OkHostnamaVerifier');
-
服務(wù)端證書校驗(yàn)的frida腳本【通用】
Java.use("java.security.KeyStore");
-
遇到混淆的情況下,這些hook代碼或多或少會(huì)失效一些,所以我們要尋找一個(gè)像服務(wù)端證書校驗(yàn)的系統(tǒng)函數(shù)來繞過客戶端證書校驗(yàn)。
2 解決方法
-
服務(wù)端的證書校驗(yàn)對(duì)于我們來說已經(jīng)不是問題,混淆對(duì)于
java.security.KeyStore
沒有作用。 -
客戶端的證書校驗(yàn),我們先來捋一下開發(fā)時(shí)的邏輯
-
1 調(diào)用證書校驗(yàn)
X509TrustManager trustManager = new X509TrustManager() { public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {} }
-
2 主機(jī)校驗(yàn)
HostnameVerifier verify = new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } };
-
3 pinner 公鑰校驗(yàn)這個(gè)校驗(yàn)主要是調(diào)用了CertificatePinner類中check方法
CertificatePinner buildPinner = new CertificatePinner.Builder() .add(CA_DOMAIN, CA_PUBLIC_KEY) .build(); OkHttpClient client = new OkHttpClient.Builder().certificatePinner(buildPinner).build();
-
-
可以打調(diào)用?;蛘遠(yuǎn)ook查看這三個(gè)方法走的調(diào)用邏輯,結(jié)論就是都走了:
okhttp3.internal.connection.RealConnection
類中的connectTls
方法:
Java.perform(function () {
var NativeSsl = Java.use('com.android.org.conscrypt.NativeSsl');
NativeSsl.doHandshake.overload('java.io.FileDescriptor', 'int').implementation = function (a, b) {
console.log("參數(shù):", a, b);
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
return this.doHandshake(a, b);
};
});
// frida -UF -l 1.hook_check.js
-
找到第三方調(diào)用棧 注意客戶端的證書校驗(yàn)順序
-
1 證書校驗(yàn)
Java.perform(function () { var Platform = Java.use('com.android.org.conscrypt.Platform'); Platform.checkServerTrusted.overload('javax.net.ssl.X509TrustManager', '[Ljava.security.cert.X509Certificate;', 'java.lang.String', 'com.android.org.conscrypt.AbstractConscryptSocket').implementation = function (x509tm, chain, authType, socket) { console.log(' [+] checkServer ',x509tm,JSON.stringify(x509tm) ); // 這里會(huì)去調(diào)用客戶端證書校驗(yàn)的方法,不執(zhí)行,就是不去校驗(yàn)(直接通過)。 //return this.checkServerTrusted(x509tm, chain, authType, socket); }; });
-
2 hostname校驗(yàn)
很少遇到 不寫了 Java.perform(function () { function getFieldValue(obj, fieldName) { var cls = obj.getClass(); var field = cls.getDeclaredField(fieldName); field.setAccessible(true); var name = field.getName(); var value = field.get(obj); return value; } function getMethodValue(obj, methodName) { var res; var cls = obj.getClass(); var methods = cls.getDeclaredMethods(); methods.forEach(function (method) { var method_name = method.getName(); console.log(method_name, method); if (method_name === methodName) { method.setAccessible(true); res = method; return; } }) return res; } var RealConnection = Java.use('uk.c'); RealConnection.f.implementation = function (a, b, c, d) { try { console.log("==============="); var route = getFieldValue(this, "c"); console.log('route=', route); var address = getFieldValue(route, 'a'); console.log('address=', address); var hostnameVerifier = getFieldValue(address, 'hostnameVerifier'); console.log('hostnameVerifier=', hostnameVerifier); console.log(' [+] hostnameVerifier', hostnameVerifier); } catch (e) { console.log(e); } return this.f(a, b, c, d); }; });
-
3 公鑰pinner校驗(yàn)
connectTls中就能找到他的類和方法被混淆后的名稱,可以直接Hook
-
五、禁用代理的場(chǎng)景
-
現(xiàn)在的很多的app都是用禁止網(wǎng)絡(luò)代理來防止抓包。在請(qǐng)求的時(shí)候都使用了Proxy.NO_PROXY
-
解決方法:
-
傳輸層的vpn進(jìn)行流量轉(zhuǎn)發(fā)
-
使用charles + Postern
-
postern是在傳輸層久把流量轉(zhuǎn)發(fā)指定的中間人(代理/抓包軟件)
-
不理解傳輸層什么意思?稍后來填坑
-
六、特殊框架 flutter 環(huán)境下如何抓包
-
框架特點(diǎn):自實(shí)現(xiàn)SSL庫(kù) + 單向證書綁定 + 禁用代理
-
https://bbs.kanxue.com/thread-261941.htm
-
注意自己的系統(tǒng)是32位還是64位
-
拖到IDA中 ---> shift + f12 搜索ssl_server
-
找到這個(gè)地方后 往上找函數(shù)開始的地方
-
然后你需要這樣操作才能把字節(jié)顯示出來
-
菜單欄->Options->General->Disassembly->Display disassambly line parts->number ofo opcode bytes(non-graph)->填入每行顯示的字節(jié)數(shù)即可
-
-
也可以直接找該函數(shù)的函數(shù)地址
function hook_ssl_verify_result(address) { Interceptor.attach(address, { onEnter: function(args) { console.log("Disabling SSL validation") }, onLeave: function(retval) { console.log("Retval: " + retval) retval.replace(0x1); } }); } function disablePinning(){ // Change the offset on the line below with the binwalk result // If you are on 32 bit, add 1 to the offset to indicate it is a THUMB function: .add(0x1) // Otherwise, you will get 'Error: unable to intercept function at ......; please file a bug' // 0x393DA4 換成你找到的函數(shù)地址 var address = Module.findBaseAddress('libflutter.so').add(0x393DA4) hook_ssl_verify_result(address); } setTimeout(disablePinning, 1000)
七、非root環(huán)境如何抓包
-
場(chǎng)景:應(yīng)用對(duì)root環(huán)境進(jìn)行校驗(yàn)
-
暫時(shí)不展開
八、自實(shí)現(xiàn)SSL/TLS框架
九、其他抓包技巧
-
https://www.52pojie.cn/thread-1405917-1-1.html
-
hook得到 sslkey,可以解釋原理
-
https://bbs.kanxue.com/thread-277996.htm
-
服務(wù)器
+關(guān)注
關(guān)注
13文章
9717瀏覽量
87364 -
APP
+關(guān)注
關(guān)注
33文章
1585瀏覽量
73858 -
SSL
+關(guān)注
關(guān)注
0文章
130瀏覽量
26102
原文標(biāo)題:APP抓不到包?
文章出處:【微信號(hào):哆啦安全,微信公眾號(hào):哆啦安全】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
CC2530 packet sniffer 為什么抓包抓不到,?
終端節(jié)點(diǎn)為什么無法抓包?
CC2640 使用BTool抓包怎么用?
Zigbee網(wǎng)路協(xié)調(diào)器發(fā)送的超長(zhǎng)數(shù)據(jù)幀在網(wǎng)絡(luò)中抓不到包?
CC2541和手機(jī)連接后抓不到包?
WIZnet芯片通訊時(shí)怎么抓包?
cc2640的simpleblebroadcaster例程抓不到包
wireshark抓包數(shù)據(jù)分析問題
MCU_Wireshark USB 抓包過濾(抓特定端口地址)

為什么抓不到baidu的數(shù)據(jù)包?
安卓端免代理抓包

如何抓取app數(shù)據(jù)包 網(wǎng)絡(luò)抓包原理及實(shí)現(xiàn)

評(píng)論