国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

解決APP抓包問題【網(wǎng)絡(luò)安全】

這篇具有很好參考價值的文章主要介紹了解決APP抓包問題【網(wǎng)絡(luò)安全】。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1.前言

在日常滲透過程中我們經(jīng)常會遇到瓶頸無處下手,這個時候如果攻擊者從APP進(jìn)行突破,往往會有很多驚喜。但是目前市場上的APP都會為防止別人惡意盜取和惡意篡改進(jìn)行一些保護(hù)措施,比如模擬器檢測、root檢測、APK加固、代碼混淆、代碼反調(diào)試、反脫殼、簽名校驗等等對抗機(jī)制。

而測試人員對APP進(jìn)行滲透的首步操作通常就是上burp或者Charles這類抓包工具進(jìn)行抓包,查看請求記錄里的域名及鏈接地址是否可以進(jìn)一步利用,但是如果遇到一些APP出現(xiàn)證書報錯或者抓不到包的情況該怎么辦,讀過本篇文章之后,相信你會擁有一些新的解決方案和思考。

2.數(shù)字證書

我們都知道http協(xié)議傳輸?shù)氖敲魑男畔ⅲ强梢灾苯硬东@的,從而造成了數(shù)據(jù)泄露。為了防止中間人的攔截,出現(xiàn)了HTTPS加密機(jī)制。在HTTPS中,使用了證書+數(shù)字簽名解決了這個問題。

此篇的重點在于如何應(yīng)對APP的抓包對抗。

總結(jié)的HTTPS加密機(jī)制如下:

  • 數(shù)字簽名是發(fā)送方的明文經(jīng)歷了兩次加密得到的兩個東西組成,一個是hash ,一個是經(jīng)過私鑰加密。
  • 數(shù)字證書就是明文+數(shù)字簽名。但是數(shù)字證書中的內(nèi)容遠(yuǎn)不止這倆,還包括了權(quán)威機(jī)構(gòu)的信息,服務(wù)器的域名,最重要的是有簽名的計算方法,不然用公鑰進(jìn)行解密之后的hash,如何與加密明文進(jìn)行對比呢,還有證書中還包括公鑰,公鑰用于發(fā)放給請求證書的客戶端。
  • HTTPS就是使用SSL/TLS協(xié)議進(jìn)行加密傳輸,讓客戶端拿到服務(wù)器的公鑰,然后客戶端隨機(jī)生成一個對稱加密的秘鑰,使用公鑰加密,傳輸給服務(wù)端,后續(xù)的所有信息都通過該對稱秘鑰進(jìn)行加密解密,完成整個HTTPS的流程。

3.https抓包

【一一幫助安全學(xué)習(xí)一一】
①網(wǎng)絡(luò)安全學(xué)習(xí)路線
②20份滲透測試電子書
③安全攻防357頁筆記
④50份安全攻防面試指南
⑤安全紅隊滲透工具包
⑥網(wǎng)絡(luò)安全必備書籍
⑦100個漏洞實戰(zhàn)案例
⑧安全大廠內(nèi)部教程

導(dǎo)入用戶證書

在第一次使用burp時,都會有這么一步,將burp的證書導(dǎo)出,添加進(jìn)瀏覽器 【受信任的根證書頒發(fā)機(jī)構(gòu)】中去,這樣就會信任burp發(fā)來的請求包,也就可以請求數(shù)據(jù)進(jìn)行修改。我們對APP抓包,也同樣要將burp證書安裝到系統(tǒng)證書中去,一般從【SD卡安裝】的證書會存放在用戶信任的憑據(jù)下
解決APP抓包問題【網(wǎng)絡(luò)安全】

解決APP抓包問題【網(wǎng)絡(luò)安全】

但是,在Android 7.0以前,應(yīng)用默認(rèn)會信任系統(tǒng)證書和用戶證書,Android 7.0開始,默認(rèn)只信任系統(tǒng)證書。

所以如果你的手機(jī)是處于Android7.0以上版本的話,并且在沒有綁定SSL證書的情況下,也會抓不到包,從安卓開發(fā)的角度可以很清楚的看到這一點。

下圖是我將burp證書安裝到Android7.1.2的用戶證書下,使用okhttp對https://ttt.com進(jìn)行請求的結(jié)果。由于ttt.com的SSL證書是自簽名證書,而自簽名證書是不被系統(tǒng)默認(rèn)信任的,所以需要先將ttt.com的自簽名證書添加到系統(tǒng)證書中才可以訪問。
解決APP抓包問題【網(wǎng)絡(luò)安全】

自簽名證書的生成如下圖所示:
解決APP抓包問題【網(wǎng)絡(luò)安全】

  • 系統(tǒng)證書路徑:/system/etc/security/cacerts/
  • 用戶證書路徑:/data/misc/user/0/cacerts-added/

移動到系統(tǒng)根證書路徑的方法:

1、導(dǎo)出burp.der

2、使用openssl更改證書格式,先將burp證書的der格式轉(zhuǎn)成pem,再獲取證書的hash

openssl x509 -inform DER -in burp.der -out burp.pem
openssl x509 -inform PEM -subject_hash_old -in burp.pem 

解決APP抓包問題【網(wǎng)絡(luò)安全】

3.移動到系統(tǒng)根證書目錄路徑下

Android根證書目錄都是以pem證書的hash值+.0格式,所以要將剛才生成的pem改名為xxxx.0

mv burp.pem a5ba575.0

由于系統(tǒng)讀寫權(quán)限問題,不一定能直接上傳到system目錄

adb push 9a5ba575.0 /sdcard

adb shell 
mount -o remount,rw /system
cp /sdcard/9a5ba575.0 /system/etc/security/cacerts/
chmod 644 /system/etc/security/cacerts/9a5ba575.0

移動完成之后,再打開【設(shè)置】-【安全】-【信任的憑據(jù)】驗證一下
解決APP抓包問題【網(wǎng)絡(luò)安全】

這時可以在Android7.0以上版本正常訪問https://ttt.com了,其他抓包工具同理即可。

證書有效期過長

還有一種情況是,導(dǎo)入到系統(tǒng)證書仍抓不到包,并且瀏覽器會報NET::ERR_CERT_VALIDITY_TOO_LONG錯誤。

原因是chrome從2018年開始只信任有效期少于825天(27個月)的證書,而burp證書有效期過長。

解決方案是自己做一個低于27個月的root證書導(dǎo)入burp,再通過burp重新導(dǎo)出證書并放入到系統(tǒng)證書路徑下。

openssl genrsa -out key.pem 3072 -nodes
openssl req -new -x509 -key key.pem -sha256 -config openssl.cnf -out cert.pem -days 730 -subj "/C=JP/ST=/L=/O=m4bln/CN=MY CA"
openssl pkcs12 -export -inkey key.pem -in cert.pem -out cert_and_key.pfx
把cert_and_key.pfx導(dǎo)入burp

目前還沒遇到過這種情況,但是如果遇到了這種問題要知道怎么解決。

以上兩種方法都是僅依靠了系統(tǒng)校驗證書的方式進(jìn)行抓包,APP在整個請求HTTPS的請求過程時還并未進(jìn)行證書校驗,和在普通的瀏覽器中訪問并無區(qū)別,只是要將想要被信任的證書放入系統(tǒng)證書路徑內(nèi)。

4.SSLPinning

對于像ttt.com這種自簽名的免費證書,不需要CA權(quán)威認(rèn)證的證書,大多數(shù)APP開發(fā)商都會使用。那么如果在安卓開發(fā)的過程中,將證書的驗證邏輯放在APP內(nèi)部,與系統(tǒng)和瀏覽器毫無相關(guān),這時再想將burp證書導(dǎo)入系統(tǒng)受信任路徑下也于事無補(bǔ)了。

APP自己校驗證書,分為兩種,一種是將驗證邏輯也在代碼中,一種是寫在安卓7.0之后才有的network-security-config中。

驗證是方式也有兩種,一種是驗證證書公鑰的hash值,一種是直接驗證證書的公鑰文件。

這種通過APP自身的驗證方式就叫做證書綁定(也叫Certificate PinningSSL Pinning)。

那么如何去判斷一個APP是否使用了證書綁定呢?首先拿到apk文件,用apktool工具進(jìn)行反編譯,查看敏感文件

apktool d -s <file.apk> -o <outdir>

開發(fā)人員經(jīng)常會將網(wǎng)絡(luò)配置的相關(guān)文件保存到指定位置,如下圖就指定在了xml目錄下。
解決APP抓包問題【網(wǎng)絡(luò)安全】

所以在反編譯后的res/xml目錄下會有一個network_security_config.xml文件,打開看到標(biāo)簽,說明使用了證書綁定機(jī)制。

解決APP抓包問題【網(wǎng)絡(luò)安全】

在配置文件中檢驗的兩種方法

<network-security-config xmlns:tools="http://schemas.android.com/tools">
    <!--允許http訪問-->
    <base-config cleartextTrafficPermitted="true"
        tools:ignore="InsecureBaseConfiguration" />

    <!--證書校驗-->
    <domain-config>
        <domain includeSubdomains="true">www.ttt.com</domain>
        <trust-anchors>
            <certificates src="@raw/ttt"/>
        </trust-anchors>
    </domain-config>

    <!--公鑰校驗-->
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">ttt.com</domain>
        <!--利用xml校驗證書公鑰的hash值-->
        <pin-set expiration="2099-01-01"
            tools:ignore="MissingBackupPin">
            <pin digest="SHA-256">7VMdvZE3PGbxb0Pgf1PlCp+MI8KZ2ZC5psM8TIylNDA=</pin>
        </pin-set>
        <!--利用xml校驗證書的公鑰文件-->
        <trust-anchors>
            <certificates src="@raw/ttt"/>
        </trust-anchors>
    </domain-config>

</network-security-config>

這兩種校驗機(jī)制出現(xiàn)一種即可,從代碼中可以看出,ttt.com就是安卓自己要校驗綁定的域名。

如果只是在這個文件進(jìn)行校驗,有兩種解決方案:一是直接將文件中校驗的部分或注釋掉,再重新打包和簽名即可,但是這過程又有些麻煩,并不是上上策,如果遇到了不能重打包的apk就尷尬了。。。二是最常用的也是最好用的frida來hook關(guān)鍵函數(shù)進(jìn)行繞過,后面會講解。當(dāng)然有些人會直接在真機(jī)或者模擬器上安裝xposed模塊,但是我個人覺得每次使用都要軟重啟,可能還會造成卡機(jī),所以感覺還是使用frida最方便。

在代碼中檢驗的兩種方法

1.利用代碼校驗證書的公鑰hash

String hostname = "www.ttt.com";
CertificatePinner certificatePinner = new CertificatePinner.Builder()
    .add(hostname, "sha256/7VMdvZE3PGbxb0Pgf1PlCp+MI8KZ2ZC5psM8TIylNDA=")
    .build();
OkHttpClient client = new OkHttpClient.Builder()
    .certificatePinner(certificatePinner)
    .hostnameVerifier(new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }).build();

2.利用代碼校驗證書的公鑰證書文件

// 獲取證書輸入流
InputStream openRawResource = getApplicationContext().getResources().openRawResource(R.raw.ttt); 
Certificate ca = CertificateFactory.getInstance("X.509").generateCertificate(openRawResource);
// 創(chuàng)建 Keystore 包含我們的證書
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// 創(chuàng)建一個 TrustManager 僅把 Keystore 中的證書 作為信任的錨點
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); // 建議不要使用自己實現(xiàn)的X509TrustManager,而是使用默認(rèn)的X509TrustManager
trustManagerFactory.init(keyStore);
// 用 TrustManager 初始化一個 SSLContext
sslContext = SSLContext.getInstance("TLS");  //定義:public static SSLContext sslContext = null;
sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());

OkHttpClient client = new OkHttpClient.Builder()
    .sslSocketFactory(sslContext.getSocketFactory(),
                      (X509TrustManager) trustManagerFactory.getTrustManagers()[0] )
    .hostnameVerifier(new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }).build();

通過frida進(jìn)行hook,這種繞過的腳本也很多,比較熟悉的有JustTrustMe和DroidSSLUnpinning,他們的底層原理都是一樣的,通過hook關(guān)鍵的驗證函數(shù),進(jìn)行邏輯繞過。

frida的安裝過程就不詳細(xì)講解了,網(wǎng)上很多教程。這里我使用的是frida 12.8.0 + frida-tools=5.3.0

這里我使用的hook.js的腳本如下:

/*  Android ssl certificate pinning bypass script for various methods
by Maurizio Siddu modify by Ch3nYe

Run with:
frida -U -f [APP_ID] -l frida_multiple_unpinning.js --no-pause
*/
setTimeout(function() {
Java.perform(function () {
console.log('');
console.log('======');
console.log('[#] Android Bypass for various Certificate Pinning methods [#]');
console.log('======');

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) request');
SSLContext_init.call(this, keyManager, TrustManagers, secureRandom);
};
} catch (err) {
console.log('[-] TrustManager (Android < 7) pinner not found');
//console.log(err);
}

// OkHTTPv3 (quadruple bypass) //
/
try {
// 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 true;
};
} catch (err) {
console.log('[-] OkHTTPv3 {1} pinner not found');
//console.log(err);
}
try {
// Bypass OkHTTPv3 {2}
// This method of CertificatePinner.check could be found in some old Android app
var okhttp3_Activity_2 = Java.use('okhttp3.CertificatePinner');
okhttp3_Activity_2.check.overload('java.lang.String', 'java.security.cert.Certificate').implementation = function (a, b) {
console.log('[+] Bypassing OkHTTPv3 {2}: ' + a);
return true;
};
} catch (err) {
console.log('[-] OkHTTPv3 {2} pinner not found');
//console.log(err);
}
try {
// Bypass OkHTTPv3 {3}
var okhttp3_Activity_3 = Java.use('okhttp3.CertificatePinner');
okhttp3_Activity_3.check.overload('java.lang.String', '[Ljava.security.cert.Certificate;').implementation = function (a, b) {
console.log('[+] Bypassing OkHTTPv3 {3}: ' + a);
return true;
};
} catch(err) {
console.log('[-] OkHTTPv3 {3} pinner not found');
//console.log(err);
}
try {
// Bypass OkHTTPv3 {4}
var okhttp3_Activity_4 = Java.use('okhttp3.CertificatePinner');
okhttp3_Activity_4[''].implementation = function (a, b) {
console.log('[+] Bypassing OkHTTPv3 {4}: ' + a);
};
} catch(err) {
console.log('[-] OkHTTPv3 {4} pinner not found');
//console.log(err);
}

// Trustkit (triple bypass) //
//
try {
// Bypass Trustkit {1}
var trustkit_Activity_1 = Java.use('com.datatheorem.android.trustkit.pinning.OkHostnameVerifier');
trustkit_Activity_1.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function (a, b) {
console.log('[+] Bypassing Trustkit {1}: ' + a);
return true;
};
} catch (err) {
console.log('[-] Trustkit {1} pinner not found');
//console.log(err);
}
try {
// Bypass Trustkit {2}
var trustkit_Activity_2 = Java.use('com.datatheorem.android.trustkit.pinning.OkHostnameVerifier');
trustkit_Activity_2.verify.overload('java.lang.String', 'java.security.cert.X509Certificate').implementation = function (a, b) {
console.log('[+] Bypassing Trustkit {2}: ' + a);
return true;
};
} catch (err) {
console.log('[-] Trustkit {2} pinner not found');
//console.log(err);
}
try {
// Bypass Trustkit {3}
var trustkit_PinningTrustManager = Java.use('com.datatheorem.android.trustkit.pinning.PinningTrustManager');
trustkit_PinningTrustManager.checkServerTrusted.implementation = function () {
console.log('[+] Bypassing Trustkit {3}');
};
} catch (err) {
console.log('[-] Trustkit {3} pinner not found');
//console.log(err);
}

// TrustManagerImpl (Android > 7) //

try {
var TrustManagerImpl = Java.use('com.android.org.conscrypt.TrustManagerImpl');
TrustManagerImpl.verifyChain.implementation = function (untrustedChain, trustAnchorChain, host, clientAuth, ocspData, tlsSctData) {
console.log('[+] Bypassing TrustManagerImpl (Android > 7): ' + host);
return untrustedChain;
};
} catch (err) {
console.log('[-] TrustManagerImpl (Android > 7) pinner not found');
//console.log(err);
}

// Appcelerator Titanium //
///
try {
var appcelerator_PinningTrustManager = Java.use('appcelerator.https.PinningTrustManager');
appcelerator_PinningTrustManager.checkServerTrusted.implementation = function () {
console.log('[+] Bypassing Appcelerator PinningTrustManager');
};
} catch (err) {
console.log('[-] Appcelerator PinningTrustManager pinner not found');
//console.log(err);
}

// OpenSSLSocketImpl Conscrypt //
/
try {
var OpenSSLSocketImpl = Java.use('com.android.org.conscrypt.OpenSSLSocketImpl');
OpenSSLSocketImpl.verifyCertificateChain.implementation = function (certRefs, JavaObject, authMethod) {
console.log('[+] Bypassing OpenSSLSocketImpl Conscrypt');
};
} catch (err) {
console.log('[-] OpenSSLSocketImpl Conscrypt pinner not found');
//console.log(err);
}

// OpenSSLEngineSocketImpl Conscrypt //
///
try {
var OpenSSLEngineSocketImpl_Activity = Java.use('com.android.org.conscrypt.OpenSSLEngineSocketImpl');
OpenSSLSocketImpl_Activity.verifyCertificateChain.overload('[Ljava.lang.Long;', 'java.lang.String').implementation = function (a, b) {
console.log('[+] Bypassing OpenSSLEngineSocketImpl Conscrypt: ' + b);
};
} catch (err) {
console.log('[-] OpenSSLEngineSocketImpl Conscrypt pinner not found');
//console.log(err);
}

// OpenSSLSocketImpl Apache Harmony //
//
try {
var OpenSSLSocketImpl_Harmony = Java.use('org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl');
OpenSSLSocketImpl_Harmony.verifyCertificateChain.implementation = function (asn1DerEncodedCertificateChain, authMethod) {
console.log('[+] Bypassing OpenSSLSocketImpl Apache Harmony');
};
} catch (err) {
console.log('[-] OpenSSLSocketImpl Apache Harmony pinner not found');
//console.log(err);
}

// PhoneGap sslCertificateChecker (https://github.com/EddyVerbruggen/SSLCertificateChecker-PhoneGap-Plugin) //
//
try {
var phonegap_Activity = Java.use('nl.xservices.plugins.sslCertificateChecker');
phonegap_Activity.execute.overload('java.lang.String', 'org.json.JSONArray', 'org.apache.cordova.CallbackContext').implementation = function (a, b, c) {
console.log('[+] Bypassing PhoneGap sslCertificateChecker: ' + a);
return true;
};
} catch (err) {
console.log('[-] PhoneGap sslCertificateChecker pinner not found');
//console.log(err);
}

// IBM MobileFirst pinTrustedCertificatePublicKey (double bypass) //

try {
// Bypass IBM MobileFirst {1}
var WLClient_Activity_1 = Java.use('com.worklight.wlclient.api.WLClient');
WLClient_Activity_1.getInstance().pinTrustedCertificatePublicKey.overload('java.lang.String').implementation = function (cert) {
console.log('[+] Bypassing IBM MobileFirst pinTrustedCertificatePublicKey {1}: ' + cert);
return;
};
} catch (err) {
console.log('[-] IBM MobileFirst pinTrustedCertificatePublicKey {1} pinner not found');
//console.log(err);
}
try {
// Bypass IBM MobileFirst {2}
var WLClient_Activity_2 = Java.use('com.worklight.wlclient.api.WLClient');
WLClient_Activity_2.getInstance().pinTrustedCertificatePublicKey.overload('[Ljava.lang.String;').implementation = function (cert) {
console.log('[+] Bypassing IBM MobileFirst pinTrustedCertificatePublicKey {2}: ' + cert);
return;
};
} catch (err) {
console.log('[-] IBM MobileFirst pinTrustedCertificatePublicKey {2} pinner not found');
//console.log(err);
}

// IBM WorkLight (ancestor of MobileFirst) HostNameVerifierWithCertificatePinning (quadruple bypass) //
///
try {
// Bypass IBM WorkLight {1}
var worklight_Activity_1 = Java.use('com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning');
worklight_Activity_1.verify.overload('java.lang.String', 'javax.net.ssl.SSLSocket').implementation = function (a, b) {
console.log('[+] Bypassing IBM WorkLight HostNameVerifierWithCertificatePinning {1}: ' + a);
return;
};
} catch (err) {
console.log('[-] IBM WorkLight HostNameVerifierWithCertificatePinning {1} pinner not found');
//console.log(err);
}
try {
// Bypass IBM WorkLight {2}
var worklight_Activity_2 = Java.use('com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning');
worklight_Activity_2.verify.overload('java.lang.String', 'java.security.cert.X509Certificate').implementation = function (a, b) {
console.log('[+] Bypassing IBM WorkLight HostNameVerifierWithCertificatePinning {2}: ' + a);
return;
};
} catch (err) {
console.log('[-] IBM WorkLight HostNameVerifierWithCertificatePinning {2} pinner not found');
//console.log(err);
}
try {
// Bypass IBM WorkLight {3}
var worklight_Activity_3 = Java.use('com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning');
worklight_Activity_3.verify.overload('java.lang.String', '[Ljava.lang.String;', '[Ljava.lang.String;').implementation = function (a, b) {
console.log('[+] Bypassing IBM WorkLight HostNameVerifierWithCertificatePinning {3}: ' + a);
return;
};
} catch (err) {
console.log('[-] IBM WorkLight HostNameVerifierWithCertificatePinning {3} pinner not found');
//console.log(err);
}
try {
// Bypass IBM WorkLight {4}
var worklight_Activity_4 = Java.use('com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning');
worklight_Activity_4.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function (a, b) {
console.log('[+] Bypassing IBM WorkLight HostNameVerifierWithCertificatePinning {4}: ' + a);
return true;
};
} catch (err) {
console.log('[-] IBM WorkLight HostNameVerifierWithCertificatePinning {4} pinner not found');
//console.log(err);
}

// Conscrypt CertPinManager //
//
try {
var conscrypt_CertPinManager_Activity = Java.use('com.android.org.conscrypt.CertPinManager');
conscrypt_CertPinManager_Activity.isChainValid.overload('java.lang.String', 'java.util.List').implementation = function (a, b) {
console.log('[+] Bypassing Conscrypt CertPinManager: ' + a);
return true;
};
} catch (err) {
console.log('[-] Conscrypt CertPinManager pinner not found');
//console.log(err);
}

// CWAC-Netsecurity (unofficial back-port pinner for Android<4.2) CertPinManager //
///
try {
var cwac_CertPinManager_Activity = Java.use('com.commonsware.cwac.netsecurity.conscrypt.CertPinManager');
cwac_CertPinManager_Activity.isChainValid.overload('java.lang.String', 'java.util.List').implementation = function (a, b) {
console.log('[+] Bypassing CWAC-Netsecurity CertPinManager: ' + a);
return true;
};
} catch (err) {
console.log('[-] CWAC-Netsecurity CertPinManager pinner not found');
//console.log(err);
}

// Worklight Androidgap WLCertificatePinningPlugin //
/
try {
var androidgap_WLCertificatePinningPlugin_Activity = Java.use('com.worklight.androidgap.plugin.WLCertificatePinningPlugin');
androidgap_WLCertificatePinningPlugin_Activity.execute.overload('java.lang.String', 'org.json.JSONArray', 'org.apache.cordova.CallbackContext').implementation = function (a, b, c) {
console.log('[+] Bypassing Worklight Androidgap WLCertificatePinningPlugin: ' + a);
return true;
};
} catch (err) {
console.log('[-] Worklight Androidgap WLCertificatePinningPlugin pinner not found');
//console.log(err);
}

// Netty FingerprintTrustManagerFactory //
//
try {
var netty_FingerprintTrustManagerFactory = Java.use('io.netty.handler.ssl.util.FingerprintTrustManagerFactory');
//NOTE: sometimes this below implementation could be useful
//var netty_FingerprintTrustManagerFactory = Java.use('org.jboss.netty.handler.ssl.util.FingerprintTrustManagerFactory');
netty_FingerprintTrustManagerFactory.checkTrusted.implementation = function (type, chain) {
console.log('[+] Bypassing Netty FingerprintTrustManagerFactory');
};
} catch (err) {
console.log('[-] Netty FingerprintTrustManagerFactory pinner not found');
//console.log(err);
}

// Squareup CertificatePinner [OkHTTP<v3] (double bypass) //

try {
// Bypass Squareup CertificatePinner  {1}
var Squareup_CertificatePinner_Activity_1 = Java.use('com.squareup.okhttp.CertificatePinner');
Squareup_CertificatePinner_Activity_1.check.overload('java.lang.String', 'java.security.cert.Certificate').implementation = function (a, b) {
console.log('[+] Bypassing Squareup CertificatePinner {1}: ' + a);
return;
};
} catch (err) {
console.log('[-] Squareup CertificatePinner {1} pinner not found');
//console.log(err);
}
try {
// Bypass Squareup CertificatePinner {2}
var Squareup_CertificatePinner_Activity_2 = Java.use('com.squareup.okhttp.CertificatePinner');
Squareup_CertificatePinner_Activity_2.check.overload('java.lang.String', 'java.util.List').implementation = function (a, b) {
console.log('[+] Bypassing Squareup CertificatePinner {2}: ' + a);
return;
};
} catch (err) {
console.log('[-] Squareup CertificatePinner {2} pinner not found');
//console.log(err);
}

// Squareup OkHostnameVerifier [OkHTTP v3] (double bypass) //
/
try {
// Bypass Squareup OkHostnameVerifier {1}
var Squareup_OkHostnameVerifier_Activity_1 = Java.use('com.squareup.okhttp.internal.tls.OkHostnameVerifier');
Squareup_OkHostnameVerifier_Activity_1.verify.overload('java.lang.String', 'java.security.cert.X509Certificate').implementation = function (a, b) {
console.log('[+] Bypassing Squareup OkHostnameVerifier {1}: ' + a);
return true;
};
} catch (err) {
console.log('[-] Squareup OkHostnameVerifier pinner not found');
//console.log(err);
}
try {
// Bypass Squareup OkHostnameVerifier {2}
var Squareup_OkHostnameVerifier_Activity_2 = Java.use('com.squareup.okhttp.internal.tls.OkHostnameVerifier');
Squareup_OkHostnameVerifier_Activity_2.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function (a, b) {
console.log('[+] Bypassing Squareup OkHostnameVerifier {2}: ' + a);
return true;
};
} catch (err) {
console.log('[-] Squareup OkHostnameVerifier pinner not found');
//console.log(err);
}

// Android WebViewClient (double bypass) //
///
try {
// Bypass WebViewClient {1} (deprecated from Android 6)
var AndroidWebViewClient_Activity_1 = Java.use('android.webkit.WebViewClient');
AndroidWebViewClient_Activity_1.onReceivedSslError.overload('android.webkit.WebView', 'android.webkit.SslErrorHandler', 'android.net.http.SslError').implementation = function (obj1, obj2, obj3) {
console.log('[+] Bypassing Android WebViewClient {1}');
};
} catch (err) {
console.log('[-] Android WebViewClient {1} pinner not found');
//console.log(err)
}
try {
// Bypass WebViewClient {2}
var AndroidWebViewClient_Activity_2 = Java.use('android.webkit.WebViewClient');
AndroidWebViewClient_Activity_2.onReceivedSslError.overload('android.webkit.WebView', 'android.webkit.WebResourceRequest', 'android.webkit.WebResourceError').implementation = function (obj1, obj2, obj3) {
console.log('[+] Bypassing Android WebViewClient {2}');
};
} catch (err) {
console.log('[-] Android WebViewClient {2} pinner not found');
//console.log(err)
}

// Apache Cordova WebViewClient //
//
try {
var CordovaWebViewClient_Activity = Java.use('org.apache.cordova.CordovaWebViewClient');
CordovaWebViewClient_Activity.onReceivedSslError.overload('android.webkit.WebView', 'android.webkit.SslErrorHandler', 'android.net.http.SslError').implementation = function (obj1, obj2, obj3) {
console.log('[+] Bypassing Apache Cordova WebViewClient');
obj3.proceed();
};
} catch (err) {
console.log('[-] Apache Cordova WebViewClient pinner not found');
//console.log(err);
}

// Boye AbstractVerifier //
///
try {
var boye_AbstractVerifier = Java.use('ch.boye.httpclientandroidlib.conn.ssl.AbstractVerifier');
boye_AbstractVerifier.verify.implementation = function (host, ssl) {
console.log('[+] Bypassing Boye AbstractVerifier: ' + host);
};
} catch (err) {
console.log('[-] Boye AbstractVerifier pinner not found');
//console.log(err);
}

});

}, 0);

啟動frida進(jìn)行hook指定APP的包名

frida -U -f com.example.safehttps -l hook.js --no-pause

解決APP抓包問題【網(wǎng)絡(luò)安全】

可以看到開啟burp抓包成功。

5.開啟雙向校驗

雙向校驗顧名思義也就是服務(wù)器也要對客戶端進(jìn)行證書校驗,在剛才客戶端校驗服務(wù)端的基礎(chǔ)上添加一直被校驗的邏輯在里面。

首先ttt.com所在的nginx服務(wù)器要開啟雙向認(rèn)證
解決APP抓包問題【網(wǎng)絡(luò)安全】

開啟客戶端的校驗后,在瀏覽器進(jìn)行訪問,會發(fā)現(xiàn)返回400,沒有被請求的SSL證書發(fā)送,是因為瀏覽器正常請求不會攜帶證書信息去請求ttt.com
解決APP抓包問題【網(wǎng)絡(luò)安全】

那么如何攜帶客戶端的證書,就要利用burp來操作,將ttt.com的證書添加到TLS客戶證書
解決APP抓包問題【網(wǎng)絡(luò)安全】

這時再訪問
解決APP抓包問題【網(wǎng)絡(luò)安全】

在APP中進(jìn)行綁定客戶端的證書文件,一般是p12格式文件,會放在assets目錄下或者raw目錄下,client.p12會有一個密鑰內(nèi)置在代碼中,需要找到才能添加進(jìn)burp中。
解決APP抓包問題【網(wǎng)絡(luò)安全】

這個在反編譯后的目錄下也能找到,通常在assets或者res/raw目錄下查找,但是再導(dǎo)入burp這一步是需要證書密碼的,比如上圖能明顯看到密碼是123456,但是找不到證書密碼怎么辦,可以看一下目錄下是否存在lib文件夾,如果存在的話極大可能是將密碼寫進(jìn)so層了,這就需要你會IDA反匯編獲取證書密鑰了,這部分在此不詳細(xì)闡述,感興趣的朋友可以先去研究一下。
解決APP抓包問題【網(wǎng)絡(luò)安全】

APP雙向校驗驗證

服務(wù)器校驗客戶端的證書ClientSSLSocketFactory,服務(wù)端將客戶端的證書進(jìn)行綁定。

TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
    throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
}
trustManager = (X509TrustManager) trustManagers[0];

OkHttpClient client = new OkHttpClient.Builder()
        .sslSocketFactory(Objects.requireNonNull(ClientSSLSocketFactory.getSocketFactory(getApplicationContext())), Objects.requireNonNull(trustManager))
        .hostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                //強(qiáng)行返回true 即驗證成功
                return true;
            }
}).build();

public class ClientSSLSocketFactory  {
    private static final String KEY_STORE_PASSWORD = "123456"; // 證書密碼
    private static InputStream client_input;

    public static SSLSocketFactory getSocketFactory(Context context) {
        try {
            //客戶端證書
            client_input = context.getResources().getAssets().open("client.p12");
            SSLContext sslContext = SSLContext.getInstance("TLS");
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            keyStore.load(client_input, KEY_STORE_PASSWORD.toCharArray());
            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            keyManagerFactory.init(keyStore, KEY_STORE_PASSWORD.toCharArray());
            sslContext.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom());
            return sslContext.getSocketFactory();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                client_input.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

雙向校驗時,要將SSLPinning與服務(wù)器校驗客戶端證書的模塊同時開啟。

對其就行繞過,需要先啟動Frida進(jìn)行hook,然后勾選上客戶端證書,才可以請求成功。如下圖所示:
解決APP抓包問題【網(wǎng)絡(luò)安全】

沒勾選就會請求失敗,出現(xiàn)400 Bad Request,和瀏覽器無代理時請求的結(jié)果一樣,如下圖:
解決APP抓包問題【網(wǎng)絡(luò)安全】

此時burp代理日志顯示如下,SSL請求失敗
解決APP抓包問題【網(wǎng)絡(luò)安全】

WebView證書校驗

webview也是一種請求方式,相當(dāng)于頁面的跳轉(zhuǎn)或嵌入,請求的結(jié)果會顯示在主屏幕上。

對于webview證書校驗,有些可以找到的腳本不一定有繞過,所以在使用的過程中要查看是否含有webview的關(guān)鍵信息

這里我使用的是DroidSSLUnpinning

使用效果如下:
解決APP抓包問題【網(wǎng)絡(luò)安全】

解決APP抓包問題【網(wǎng)絡(luò)安全】

此時的APP綁定場景為:OKhttp請求為雙向校驗,webview為SSLPinning校驗。所以在圖中的上面一行是okhttp的請求結(jié)果,下面的是webview的請求結(jié)果,此腳本雙向校驗仍然可以繞過。

如果說webview再添加了客戶端校驗,那么在反編譯apk后,需要找到webview訪問域名的證書密鑰,再安裝進(jìn)burp中即可。

6.ssl_logger通殺

至此,我們可以繞過證書綁定,抓APP發(fā)出的https包了,然而上述的證書解綁hook工具僅僅是通過hook了幾種綁定證書的API,不適用于新出現(xiàn)或者非主流的證書綁定技術(shù)。這時,就需要神器ssl_logger

ssl_logger是用來解密SSL流量的工具,也是一款基于frida的hook工具,通過hook libssl庫中的SSL_read、SSL_write等函數(shù)來實現(xiàn)流量解密,由于底層的實現(xiàn)會調(diào)用這幾個函數(shù)來封裝,所以可以直接解出流量數(shù)據(jù)。
解決APP抓包問題【網(wǎng)絡(luò)安全】

r0capture是r0ysue大佬在其基礎(chǔ)上進(jìn)行改進(jìn)的一款工具。
解決APP抓包問題【網(wǎng)絡(luò)安全】

由于ssl_logger是適用于MAC和linux操作系統(tǒng),所以我選擇在kali上進(jìn)行hook實現(xiàn)雙向校驗的app
解決APP抓包問題【網(wǎng)絡(luò)安全】

打開抓到的1.pcap包
解決APP抓包問題【網(wǎng)絡(luò)安全】
解決APP抓包問題【網(wǎng)絡(luò)安全】

從圖中可以看出成功的獲取到了信息,是不是感覺這個工具特別神,但是看pcap的包總歸不如看burp的一目了然,這個工具就這一點不太友好。所以用哪個看你心情

7.eBPF hook 免CA證書

ecapture:eBPF HOOK uprobe實現(xiàn)的各種用戶態(tài)進(jìn)程的數(shù)據(jù)捕獲,無需改動原程序。這個工具也是通過hook了libssl庫中SSL_write、SSL_read這兩個關(guān)鍵的SSL加密函數(shù)的返回值,拿到明文信息,通過ebpf map傳遞給用戶進(jìn)程。在APP中,如果遇到場景是burp抓包時出現(xiàn)證書報錯,我覺得可以嘗試一下用這個工具直接curl訪問進(jìn)行抓包。eBPF hook也是最近才發(fā)現(xiàn)的hook方法,值得我們?nèi)ド钊胩剿鳌?/p>

我這里用的是作者v0.1.3版本發(fā)布的工具,使用效果如下:
解決APP抓包問題【網(wǎng)絡(luò)安全】

8.總結(jié)

在依靠系統(tǒng)或默認(rèn)瀏覽器校驗證書的情況下,導(dǎo)入burp證書為用戶證書是可以抓https包的

當(dāng)app支持的最小API為24(Android 7.0)或以上時,默認(rèn)情況下app只信任系統(tǒng)級別的證書,需要把burp變?yōu)橄到y(tǒng)證書

自簽名證書作為系統(tǒng)證書時,有效期最長不超過825天,用戶證書則沒有限制

開啟證書校驗的APP在使用burp抓包時會報certtificate_unknown等錯誤

使用frida hook繞過雙向證書校驗時,必須要將客戶端的p12文件導(dǎo)入burp中

一些腳本仍繞不過可以使用ssl_logger或者逆向代碼進(jìn)行分析驗證邏輯,再有針對性的繞過

p12文件的密鑰如果在so層,需要會用IDA進(jìn)行靜態(tài)分析lib下的so文件獲取關(guān)鍵密鑰

看完本篇文章之后,相信你再面對抓不到包的APP或者是https請求也不會手足無措了。文章來源地址http://www.zghlxwxcb.cn/news/detail-419900.html

到了這里,關(guān)于解決APP抓包問題【網(wǎng)絡(luò)安全】的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 網(wǎng)絡(luò)安全工具——Wireshark抓包工具

    網(wǎng)絡(luò)安全工具——Wireshark抓包工具

    Wireshark是一個網(wǎng)絡(luò)封包分析軟件。網(wǎng)絡(luò)封包分析軟件的功能是擷取網(wǎng)絡(luò)封包,并盡可能顯示出最為詳細(xì)的網(wǎng)絡(luò)封包資料。Wireshark使用WinPCAP作為接口,直接與網(wǎng)卡進(jìn)行數(shù)據(jù)報文交換。 網(wǎng)絡(luò)管理員使用Wireshark 來檢測網(wǎng)絡(luò)問題, 網(wǎng)絡(luò)安全工程師使用Wireshark來檢查資訊安全相關(guān)問題

    2024年02月13日
    瀏覽(20)
  • 云原生環(huán)境該怎樣解決網(wǎng)絡(luò)安全問題

    云原生環(huán)境該怎樣解決網(wǎng)絡(luò)安全問題

    隨著云計算逐漸邁向成熟階段,云原生技術(shù)以其“生在云上、長在云上”的核心理念,被普遍認(rèn)為是云計算未來十年發(fā)展的關(guān)鍵方向。該技術(shù)不僅能夠有效破解傳統(tǒng)云實踐中所面臨的應(yīng)用升級緩慢、架構(gòu)臃腫、迭代效率低下等難題,更為業(yè)務(wù)創(chuàng)新注入了強(qiáng)大的動力。 云原生技

    2024年04月27日
    瀏覽(22)
  • 網(wǎng)絡(luò)信息通信的安全問題以及解決方法

    網(wǎng)絡(luò)信息通信的安全問題以及解決方法

    網(wǎng)絡(luò)通信筆記 竊聽指A,B兩者通信時被第三方竊聽。例如:美國如何竊聽海底光纜這類事件 這種情況也很好解決, 信息加密 就行 假冒是指第三方,冒充A(發(fā)送者)或B(接受者),與另外一方進(jìn)行消息通信。類似盜號的操作 這種情況一般用,數(shù)據(jù)簽名,和消息認(rèn)證的方式解決 篡改

    2024年02月16日
    瀏覽(25)
  • 自學(xué)網(wǎng)絡(luò)安全遇到問題怎么解決?路線是什么

    自學(xué)網(wǎng)絡(luò)安全遇到問題怎么解決?路線是什么

    自學(xué)網(wǎng)絡(luò)安全很容易學(xué)著學(xué)著就迷茫了,找到源頭問題,解決它就可以了,所以首先咱們聊聊,學(xué)習(xí)網(wǎng)絡(luò)安全方向通常會有哪些問題,看到后面有驚喜哦 1、打基礎(chǔ)時間太長 學(xué)基礎(chǔ)花費很長時間,光語言都有幾門,有些人會倒在學(xué)習(xí) linux 系統(tǒng)及命令的路上,更多的人會倒在學(xué)

    2024年02月06日
    瀏覽(21)
  • 網(wǎng)絡(luò)安全:WireShark 抓包及常用協(xié)議分析

    網(wǎng)絡(luò)安全:WireShark 抓包及常用協(xié)議分析

    打開kali終端進(jìn)入wireshark 進(jìn)入到wireshark點擊選項 勾選選項混雜模式開始抓包 進(jìn)入終端打開火狐,打開百度進(jìn)行抓包 這時我們抓到了很多類型的數(shù)據(jù)包 上方的過濾器可以指定類型數(shù)據(jù)寶或者指定源地址目標(biāo)地址等等,例如現(xiàn)在抓取arp協(xié)議的數(shù)據(jù)包 我們ping一個地址 我們可以用

    2023年04月08日
    瀏覽(23)
  • 網(wǎng)絡(luò)安全工具——Burp Suite抓包工具

    網(wǎng)絡(luò)安全工具——Burp Suite抓包工具

    我這里安裝的是Burp2021的破解版 請支持正版 首先安裝java環(huán)境,本人使用的是 jdk-15 1、解壓之后jdk-15的文件夾內(nèi)容 2、將我們的java環(huán)境添加進(jìn)我們的環(huán)境變量 Java變量路徑是:C:developmentjdk-15bin #這里是我的路徑,不要復(fù)制粘貼,大家將自己jdk-15bin的路徑添加進(jìn)環(huán)境變量就行

    2024年02月12日
    瀏覽(23)
  • 【網(wǎng)絡(luò)安全】理解報文加密、數(shù)字簽名能解決的實際問題

    【網(wǎng)絡(luò)安全】理解報文加密、數(shù)字簽名能解決的實際問題

    工作中重新接觸了 【公鑰、私鑰、簽名】的概念。抽空重新看了《計算機(jī)網(wǎng)絡(luò)》和國外的小黑書,把這塊基礎(chǔ)知識再收斂一下?;谛『跁臄⑹陆Y(jié)構(gòu),把網(wǎng)絡(luò)安全解決的實際問題拆解成: 防止報文泄露 防止報文被篡改 實體鑒別 端點鑒別 防止重放攻擊 1. 防止報文泄露 —

    2024年02月11日
    瀏覽(23)
  • 安卓5.0模擬器下安裝Xposed和JustTrustMe詳細(xì)教程解決app某音抓包無網(wǎng)絡(luò)問題附安裝包下載地址

    安卓5.0模擬器下安裝Xposed和JustTrustMe詳細(xì)教程解決app某音抓包無網(wǎng)絡(luò)問題附安裝包下載地址

    本篇文章主要介紹如何在安卓5.0模擬器下安裝Xposed以及JustTrustMe模塊,從而來實現(xiàn)抖音app抓包無網(wǎng)絡(luò)問題,當(dāng)然也包括抓包后HTTPS解密問題。 環(huán)境 : Android5.0 X86 架構(gòu),模擬器使用夜深/雷電均可,也可以使用AS中的VM manager新建安卓模擬器,你也可以使用真機(jī)測試但不推薦,畢竟需

    2024年02月02日
    瀏覽(40)
  • Kali Linux --《網(wǎng)絡(luò)安全》-- 使用 WireShark 對常用協(xié)議抓包并分析原理

    Kali Linux --《網(wǎng)絡(luò)安全》-- 使用 WireShark 對常用協(xié)議抓包并分析原理

    作為一款高效免費的抓包工具,wireshark可以捕獲并描述網(wǎng)絡(luò)數(shù)據(jù)包,其最大的優(yōu)勢就是免費、開源以及多平臺支持,在GNU通用公共許可證的保障范圍下,用戶可以免費獲取軟件和代碼,并擁有對其源碼修改和定制的權(quán)利,如今其已是全球最廣泛的網(wǎng)絡(luò)數(shù)據(jù)包分析軟件之一。接

    2023年04月08日
    瀏覽(21)
  • 網(wǎng)絡(luò)安全攻防之破解小程序積分制度(Fiddler抓包教程實戰(zhàn))【文末含彩蛋】

    網(wǎng)絡(luò)安全攻防之破解小程序積分制度(Fiddler抓包教程實戰(zhàn))【文末含彩蛋】

    今天碰到一個微信公眾號的的某個積分制功能:簡單介紹就是你閱讀文章可以刷積分,然后也可以使用積分,正好前段時間接觸到了Fiddler(抓包神奇),想利用一下,把請求給修改了,從而增加自己的累計積分。 這就是那個程序的界面,點擊【我要閱讀】,閱讀文章后就可

    2023年04月08日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包