欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

如何使用Frida繞過Android網(wǎng)絡(luò)安全配置

如何使用Frida繞過Android網(wǎng)絡(luò)安全配置,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對(duì)這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長期合作伙伴,公司提供的服務(wù)項(xiàng)目有:主機(jī)域名、虛擬主機(jī)、營銷軟件、網(wǎng)站建設(shè)、連城網(wǎng)站維護(hù)、網(wǎng)站推廣。

寫在前面的話

我們將演示如何利用Frida腳本來繞過Android的網(wǎng)絡(luò)安全配置,這是一種繞過網(wǎng)絡(luò)安全配置的新技術(shù)。除此之外,我們還將演示如何在其他場景來測試該腳本,并分析腳本的運(yùn)行機(jī)制。

在之前的一次Android應(yīng)用程序安全審計(jì)過程中,首先我們要做的就是準(zhǔn)備滲透測試的環(huán)境,并配置應(yīng)用程序來繞過網(wǎng)絡(luò)安全配置。由于我個(gè)人比較喜歡Frida,因此它也就成為了我的首選工具。

當(dāng)時(shí)我下載了兩到三個(gè)腳本,但是當(dāng)我在Android 7.1.0中運(yùn)行腳本時(shí),沒有一個(gè)可以成功的。這也就是為什么我想研究網(wǎng)絡(luò)安全配置的運(yùn)行機(jī)制,并且如何用Frida繞過它們。

我所做的第一件事就是生成不同的測試用例,我嘗試選擇了幾款比較常見的:

1、OKHttp

2、HttpsURLConnection

3、WebView

接下來,我用不同的網(wǎng)絡(luò)安全配置生成了三個(gè)應(yīng)用程序:

1、一個(gè)使用了默認(rèn)NSC配置的應(yīng)用程序-BypassNSC

2、一個(gè)帶有NSC文件(僅使用了系統(tǒng)證書)的應(yīng)用程序-BypassNSC2

3、一個(gè)帶有NSC文件的應(yīng)用程序(強(qiáng)制證書綁定)-BypassNSC3

代碼會(huì)解析并驗(yàn)證Android SDK中的網(wǎng)絡(luò)安全配置,我的測試版本為24、25和26。廣大用戶可以點(diǎn)擊【這里】獲取我所生成的應(yīng)用程序以及所使用的腳本。

腳本名如下:

network-security-config-bypass-1.js

network-security-config-bypass-2.js

network-security-config-bypass-3.js

network-security-config-bypass-cr.js

下圖為每一個(gè)腳本的分析測試結(jié)果:

如何使用Frida繞過Android網(wǎng)絡(luò)安全配置

network-security-config-bypass-1.js

原始引用:【鏈接】

該腳本會(huì)修改NetworkSecurityConfig.Builder類中的getEffectiveCertificatesEntryRefs方法,該方法可以返回有效證書列表。在標(biāo)準(zhǔn)的Android配置中,它所返回的有效證書列表就是安裝在目標(biāo)系統(tǒng)中的有效證書。毫無以為,這個(gè)腳本將直接返回用戶安裝的證書,因此理論上來說,它可以繞過前兩個(gè)應(yīng)用程序的網(wǎng)絡(luò)安全配置,但讓我驚訝的是,它竟然也適用于第三種情況,也就是證書綁定配置。我們可以使用下列方法來驗(yàn)證綁定的證書:

android.security.net.config.NetworkSecurityTrustManager.checkPins

下面的棧跟蹤記錄顯示了代碼到checkPins函數(shù)的執(zhí)行路徑:

    at android.security.net.config.NetworkSecurityTrustManager.checkPins(Native Method)    at android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted(NetworkSecurityTrustManager.java:95)    at android.security.net.config.RootTrustManager.checkServerTrusted(RootTrustManager.java:88)    at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:178)    at com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:596)    at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)    at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357)    ...

如果補(bǔ)丁沒有執(zhí)行,那么當(dāng)執(zhí)行路徑抵達(dá)該函數(shù)時(shí),則會(huì)拋出異常:

Caused by: java.security.cert.CertificateException: Pin verification failed        at android.security.net.config.NetworkSecurityTrustManager.checkPins(NetworkSecurityTrustManager.java:148)        at android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted(NetworkSecurityTrustManager.java:95)        at android.security.net.config.RootTrustManager.checkServerTrusted(RootTrustManager.java:88)        at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:178)        at com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:596)        at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)        at com.android.org.

我們看一下這個(gè)方法的實(shí)現(xiàn)代碼(API 25):

private void checkPins(List<X509Certificate> chain) throws CertificateException {        PinSet pinSet = mNetworkSecurityConfig.getPins();        if (pinSet.pins.isEmpty()                || System.currentTimeMillis() > pinSet.expirationTime                || !isPinningEnforced(chain)) {            return;        }        Set<String> pinAlgorithms = pinSet.getPinAlgorithms();        Map<String, MessageDigest> digestMap = new ArrayMap<String, MessageDigest>(                pinAlgorithms.size());        for (int i = chain.size() - 1; i >= 0 ; i--) {            X509Certificate cert = chain.get(i);            byte[] encodedSPKI = cert.getPublicKey().getEncoded();            for (String algorithm : pinAlgorithms) {                MessageDigest md = digestMap.get(algorithm);                if (md == null) {                    try {                        md = MessageDigest.getInstance(algorithm);                    } catch (GeneralSecurityException e) {                        throw new RuntimeException(e);                    }                    digestMap.put(algorithm, md);                }                if (pinSet.pins.contains(new Pin(algorithm, md.digest(encodedSPKI)))) {                    return;                }            }        }        // TODO: Throw a subclass of CertificateException which indicates a pinning failure.        throw new CertificateException("Pin verification failed");    }

這個(gè)方法可以接收網(wǎng)站通信所返回的證書列表,它做的第一件事情就是條件檢測:

1、pinset為空

2、驗(yàn)證時(shí)pinset已過期

3、證書綁定并非配置強(qiáng)制要求

如果上述條件沒有一個(gè)為真,綁定驗(yàn)證將會(huì)被忽略。如果必須實(shí)現(xiàn)驗(yàn)證,應(yīng)用程序?qū)z查站點(diǎn)提供的任何證書是否與網(wǎng)絡(luò)安全配置文件中定義的某個(gè)證書匹配,此時(shí)驗(yàn)證就是成功的。如果沒有發(fā)生這種情況,該方法將拋出前一個(gè)stacktrace中顯示的異常。

一開始,我以為這個(gè)問題存在于用來分析每一個(gè)證書的for循環(huán)中,所以我在Frida腳本中添加了下列l(wèi)og:

var Pin = Java.use("android.security.net.config.Pin");Pin.$init.implementation = function (digestAlg, digest) {var bt = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new());console.log("\nBacktrace:\n" + bt);console.log(digestAlg);return this.$init(digestAlg,digest);}

它可以輸出驗(yàn)證過程中的每一個(gè)pin,當(dāng)我運(yùn)行改動(dòng)過的應(yīng)用程序之后,我發(fā)現(xiàn)這并沒有什么用。于是我又在log中添加了針對(duì)pinSet.getPinAlgorithms()的調(diào)用,并在for循環(huán)之前執(zhí)行:

var PinSet = Java.use("android.security.net.config.PinSet");PinSet.getPinAlgorithms.implementation = function () {var bt = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new());console.log("\nBacktrace:\n" + bt);return this.getPinAlgorithms();}

這一次什么都沒打印出來,于是接下來我得看看函數(shù)的條件判斷是否為真,因此我在腳本中添加了下列代碼:

     NetworkSecurityTrustManager.checkPins.implementation = function (pins) {var bt = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new());console.log("\nBacktrace:\n" + bt);pinSet = this.mNetworkSecurityConfig.value.getPins();console.log("pinSet.pins.value.isEmpty: " +pinSet.pins.value.isEmpty());console.log("isPinningEnforced: " +this.isPinningEnforced(pins));console.log("pins.isEmpty: " +pins.isEmpty());console.log(System.currentTimeMillis())console.log(pinSet.expirationTime.value);console.log(System.currentTimeMillis() > pinSet.expirationTime.value);this.checkPins(pins);}

運(yùn)行應(yīng)用程序之后,我拿到了下列輸出:

pinSet.pins.value.isEmpty: falseisPinningEnforced: false <-- this condition is the problematic onepins.isEmpty: false15620312482749223372036854775807false

我們可以看到,isPinningEnforced為False,此時(shí)其他所有的表達(dá)式都將為True。該方法的實(shí)現(xiàn)代碼如下:

private boolean isPinningEnforced(List<X509Certificate> chain) throws CertificateException {if (chain.isEmpty()) {return false;}X509Certificate anchorCert = chain.get(chain.size() - 1);TrustAnchor chainAnchor =mNetworkSecurityConfig.findTrustAnchorBySubjectAndPublicKey(anchorCert);if (chainAnchor == null) {throw new CertificateException("Trusted chain does not end in a TrustAnchor");}return !chainAnchor.overridesPins;}

原來,問題出在findTrustAnchorBySubjectAndPublicKey的身上,它是NetworkSecurityConfig類中的一個(gè)方法,能夠返回一個(gè)chainAnchor:

public TrustAnchor findTrustAnchorBySubjectAndPublicKey(X509Certificate cert) {for (CertificatesEntryRef ref : mCertificatesEntryRefs) {TrustAnchor anchor = ref.findBySubjectAndPublicKey(cert);if (anchor != null) {return anchor;}}return null;}

它會(huì)在配置過程中對(duì)創(chuàng)建的CertificatesEntryRef進(jìn)行迭代,并返回第一個(gè)跟SubjectAndPublicKey匹配的對(duì)象。在這個(gè)場景中,它將返回的是其中一個(gè)代理。研究完源代碼后,我找到了CertificatesEntryRef類,并發(fā)現(xiàn)了唯一一個(gè)構(gòu)造器:

public CertificatesEntryRef(CertificateSource source, boolean overridesPins) {mSource = source;mOverridesPins = overridesPins;}

如果再回頭看一次Frida腳本,你將會(huì)發(fā)現(xiàn)CertificatesEntryRef是以下列方式創(chuàng)建的:

NetworkSecurityConfig_Builder.getEffectiveCertificatesEntryRefs.implementation = function(){origin = this.getEffectiveCertificatesEntryRefs()source = UserCertificateSource.getInstance()userCert = CertificatesEntryRef.$new(source,true) <-- sets overridesPins in trueorigin.add(userCert)return origin}

這也就是為什么這個(gè)腳本適用于所有場景。

network-security-config-bypass-2.js

原始引用:【鏈接】

在這個(gè)場景下,唯一適用的就是不包含網(wǎng)絡(luò)安全配置文件的應(yīng)用程序。

我分析了一下為什么補(bǔ)丁不起作用,原因在于parseNetworkSecurityConfig方法:

        XmlUtils.beginDocument(parser, "network-security-config");int outerDepth = parser.getDepth();while (XmlUtils.nextElementWithin(parser, outerDepth)) {//here it creates a NetworkSecurityconfig.Builder based on the xml structure....}...NetworkSecurityConfig.Builder platformDefaultBuilder =NetworkSecurityConfig.getDefaultBuilder(mTargetSdkVersion); <-- this is the method changed with the scriptaddDebugAnchorsIfNeeded(debugConfigBuilder, platformDefaultBuilder);//baseConfigBuilder is null only if the xml network-security-config is not defined in the AndroidManifest.xmlif (baseConfigBuilder != null) {baseConfigBuilder.setParent(platformDefaultBuilder);addDebugAnchorsIfNeeded(debugConfigBuilder, baseConfigBuilder);} else {baseConfigBuilder = platformDefaultBuilder;}...mDefaultConfig = baseConfigBuilder.build();mDomainMap = configs;}

構(gòu)建方法會(huì)生成NetworkSecurityConfig實(shí)體:

public NetworkSecurityConfig build() {boolean cleartextPermitted = getEffectiveCleartextTrafficPermitted();boolean hstsEnforced = getEffectiveHstsEnforced();PinSet pinSet = getEffectivePinSet();List<CertificatesEntryRef> entryRefs = getEffectiveCertificatesEntryRefs();return new NetworkSecurityConfig(cleartextPermitted, hstsEnforced, pinSet, entryRefs);}

有效證書源在entryRefs變量中定義,其構(gòu)造方法如下:

private List<CertificatesEntryRef> getEffectiveCertificatesEntryRefs() {if (mCertificatesEntryRefs != null) {return mCertificatesEntryRefs;}if (mParentBuilder != null) {return mParentBuilder.getEffectiveCertificatesEntryRefs();}return Collections.<CertificatesEntryRef>emptyList();}

此時(shí),mCertificatesEntryRefs不為空,并會(huì)返回標(biāo)準(zhǔn)的SystemCertificateSource。因此,mParentBuilder永遠(yuǎn)不會(huì)被調(diào)用。

接下來,當(dāng)服務(wù)器證書驗(yàn)證成功后,應(yīng)用程序?qū)?huì)調(diào)用NetworkSecurityConfig.findTrustAnchorBySubjectAndPublicKey方法,該方法將會(huì)對(duì)有效證書進(jìn)行過濾:

public TrustAnchor findTrustAnchorBySubjectAndPublicKey(X509Certificate cert) {for (CertificatesEntryRef ref : mCertificatesEntryRefs) {TrustAnchor anchor = ref.findBySubjectAndPublicKey(cert);if (anchor != null) {return anchor;}}return null;}

并導(dǎo)致棧跟蹤拋出異常:

com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:375)at com.android.org.conscrypt.TrustManagerImpl.getTrustedChainForServer(TrustManagerImpl.java:304)at android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted(NetworkSecurityTrustManager.java:94)at android.security.net.config.RootTrustManager.checkServerTrusted(RootTrustManager.java:88)...

network-security-config-bypass-3.js

原始引用:【鏈接】

該腳本適用于三個(gè)場景中的其中兩個(gè),因?yàn)檠a(bǔ)丁會(huì)在驗(yàn)證證書的方法中執(zhí)行。但是它不適用于第三種場景,因?yàn)樽C書綁定是在其他方法中執(zhí)行的,具體可以參考棧跟蹤記錄中的錯(cuò)誤信息:

at android.security.net.config.NetworkSecurityTrustManager.checkPins(NetworkSecurityTrustManager.java:148)at android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted(NetworkSecurityTrustManager.java:95)at android.security.net.config.RootTrustManager.checkServerTrusted(RootTrustManager.java:88)at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:203)at com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:592)at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:351)... 25 more

network-security-config-bypass-cr.js

在這個(gè)場景下,修補(bǔ)的方法為getConfigSource,當(dāng)代碼對(duì)network-security-config進(jìn)行解析時(shí)將會(huì)調(diào)用這個(gè)方法。我們可以看到,重寫的方法會(huì)創(chuàng)建一個(gè)DefaultConfigSource,并在Android 23中以參數(shù)形式進(jìn)行定義。

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)的支持。

網(wǎng)站欄目:如何使用Frida繞過Android網(wǎng)絡(luò)安全配置
文章起源:http://aaarwkj.com/article36/peggsg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化移動(dòng)網(wǎng)站建設(shè)、企業(yè)網(wǎng)站制作、微信公眾號(hào)網(wǎng)站內(nèi)鏈、定制開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

小程序開發(fā)
蜜桃精品人妻一区二区三区| 日日添夜夜添天天操| 亚洲一区二区三区精品在线| 色婷婷激一区二区三区| 伊人久久大香线蕉av网站| 成人精品播放视频在线观看| 亚洲区一区二区三区精品| 欧美精品国产亚洲另类| 色婷婷丝袜一区网站| 区一区二区三视频日韩| 丰满少妇一级淫片在线播放| 成人欧美精品一区二区不卡| 少妇一夜一次一区二区| 日韩欧美一区二区免费| 西西美女掰开阴让你看| 国产剧情av在线资源| 99中文字幕国产精品| 国产在线不卡中文字幕| 一区二区三区四区在线视频观看| 亚洲一区二区三区蜜桃av| 免费在线免费观看av| 色呦呦视频在线免费看| 美女后入式在线观看| 亚洲欧美中文字幕乱码| 91伊人手机在线观看| 日韩精品少妇一区二区| 久久精品国产亚洲熟女| 97免费观看在线观看| 亚洲黄色av网站在线| 黄片无毛欧美在线观看| 日韩欧美人妻中文字幕| 九九在线视频免费观看精品视频| 特级艳片在线观看免费| 亚洲a∨乱码一区二区三区蜜臀| 国产av一级二级三级最新精品| 欧美日韩视频一区二区| 亚洲男人的天堂社区av| 日本中文字幕免费一区| 日韩精品二区在线观看| 中文字幕久久av一区二区| 欧美精品国产亚洲另类|