<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          一篇文章教你學(xué)會(huì)在 Android 中 https 抓包原理和操作

          共 8143字,需瀏覽 17分鐘

           ·

          2022-11-10 12:02

          159bae960158eec3fb68c95b4ae00c97.webp


          點(diǎn)擊上方“ Python學(xué)習(xí)開發(fā) ”,選擇“ 加為星標(biāo)

          第一時(shí)間關(guān)注技術(shù)干貨!


          ?非常棒的一篇安卓系統(tǒng)抓包的文章,涉及到原理分析,推薦給大家

          原文地址:

          https://juejin.im/post/5cc313755188252d6f11b463

          / ?前言 ?/

          HTTP協(xié)議發(fā)展至今已經(jīng)有二十多年的歷史,整個(gè)發(fā)展的趨勢主要是兩個(gè)方向:效率和安全。效率方面,從HTTP1.0的一次請(qǐng)求一個(gè)連接,到HTTP1.1的連接復(fù)用,到SPDY/HTTP2的多路復(fù)用,到QUIC/HTTP3的基于UDP傳輸,在效率方面越來越高效。安全方面,從HTTP的明文,到HTTP2強(qiáng)制使用TLSv1.2,到QUIC/HTTP3強(qiáng)制使用TLSv1.3,越來越注重?cái)?shù)據(jù)傳輸?shù)陌踩???偠灾?,HTTP協(xié)議的發(fā)展對(duì)用戶是友好的,但是對(duì)開發(fā)者而言卻不那么友善。

          抓包是每個(gè)程序員的必修技能之一,尤其是在接口調(diào)試和程序逆向方面具有廣闊的用途。但是,隨著越來越多的通信協(xié)議使用加密的HTTPS,而且系統(tǒng)層面也開始強(qiáng)制規(guī)定使用HTTPS,抓包似乎是顯得越來越難了。

          本篇博客,主要詳解Android平臺(tái)下,HTTPS抓包的常見問題以及解決辦法。工欲善其事必先利其器,博客中以HttpCanary作為抓包工具進(jìn)行講解。更多HttpCanary的資料,請(qǐng)見:

          GitHub地址:

          https://github.com/MegatronKing/HttpCanary

          / ?抓包原理 ?/

          幾乎所有網(wǎng)絡(luò)數(shù)據(jù)的抓包都是采用中間人的方式(MITM),包括大家常用的Fiddler、Charles等知名抓包工具,HttpCanary同樣是使用中間人的方式進(jìn)行抓包。

          從上面這個(gè)原理圖,可以看出抓包的核心問題主要是兩個(gè):

          • MITM Server如何偽裝成真正的Server

          • MITM Client如何偽裝成真正的Client

          第一個(gè)問題,MITM Server要成為真正的Server,必須能夠給指定域名簽發(fā)公鑰證書,且公鑰證書能夠通過系統(tǒng)的安全校驗(yàn)。比如Client發(fā)送了一條https://www.baidu.com/的網(wǎng)絡(luò)請(qǐng)求,MITM Server要偽裝成百度的Server,必須持有www.baidu.com域名的公鑰證書并發(fā)給Client,同時(shí)還要有與公鑰相匹配的私鑰。

          MITM Server的處理方式是從第一個(gè)SSL/TLS握手包Client Hello中提取出域名www.baidu.com,利用應(yīng)用內(nèi)置的CA證書創(chuàng)建www.baidu.com域名的公鑰證書和私鑰。創(chuàng)建的公鑰證書在SSL/TLS握手的過程中發(fā)給Client,Client收到公鑰證書后會(huì)由系統(tǒng)會(huì)對(duì)此證書進(jìn)行校驗(yàn),判斷是否是百度公司持有的證書,但很明顯這個(gè)證書是抓包工具偽造的。為了能夠讓系統(tǒng)校驗(yàn)公鑰證書時(shí)認(rèn)為證書是真實(shí)有效的,我們需要將抓包應(yīng)用內(nèi)置的CA證書手動(dòng)安裝到系統(tǒng)中,作為真正的證書發(fā)行商(CA),即洗白。這就是為什么,HTTPS抓包一定要先安裝CA證書。

          第二個(gè)問題,MITM Client偽裝成Client。由于服務(wù)器并不會(huì)校驗(yàn)Client(絕大部分情況),所以這個(gè)問題一般不會(huì)存在。比如Server一般不會(huì)關(guān)心Client到底是Chrome瀏覽器還是IE瀏覽器,是Android App還是iOS App。當(dāng)然,Server也是可以校驗(yàn)Client的,這個(gè)后面分析。

          / ?安裝CA證書 ?/

          抓包應(yīng)用內(nèi)置的CA證書要洗白,必須安裝到系統(tǒng)中。而Android系統(tǒng)將CA證書又分為兩種:用戶CA證書和系統(tǒng)CA證書。顧明思議,用戶CA證書是由用戶自行安裝的,系統(tǒng)CA證書是由系統(tǒng)內(nèi)置的,很明顯后者更加真實(shí)有效。

          系統(tǒng)CA證書存放在/etc/security/cacerts/目錄下,名稱是CA證書subjectDN的Md5值前四位移位取或,后綴名是.0,比如00673b5b.0??紤]到安全原因,系統(tǒng)CA證書需要有Root權(quán)限才能進(jìn)行添加和刪除。

          對(duì)于非Root的Android設(shè)備,用戶只能安裝用戶CA證書。

          無論是系統(tǒng)CA證書還是用戶CA證書,都可以在設(shè)置->系統(tǒng)安全->加密與憑據(jù)->信任的憑據(jù)中查看:

          4190b269a6f60c43e91da6a2bf366103.webp圖片

          / ?Android7.0的用戶CA限制 ?/

          Android從7.0開始系統(tǒng)不再信任用戶CA證書(應(yīng)用targetSdkVersion >= 24時(shí)生效,如果targetSdkVersion < 24即使系統(tǒng)是7.0+依然會(huì)信任)。也就是說即使安裝了用戶CA證書,在Android 7.0+的機(jī)器上,targetSdkVersion >= 24的應(yīng)用的HTTPS包就抓不到了。

          比如上面的例子,抓包工具用內(nèi)置的CA證書,創(chuàng)建了www.baidu.com域名的公鑰證書發(fā)給Client,系統(tǒng)校驗(yàn)此證書時(shí)發(fā)現(xiàn)是用戶CA證書簽發(fā)的,sorry。。。那么,我們?nèi)绻@過這種限制呢?已知有以下四種方式(低于7.0的系統(tǒng)請(qǐng)忽略)。

          配置networkSecurityConfig

          如果我們想抓自己的App,只需要在AndroidManifest中配置networkSecurityConfig即可:

                <?xml?version="1.0"?encoding="utf-8"?>
          <manifest?...?>
          ????<application?android:networkSecurityConfig="@xml/network_security_config"
          ???????...?>

          ????????...
          ????</application>
          </manifest>
                <?xml?version="1.0"?encoding="utf-8"?>
          <network-security-config>
          ????<base-config?cleartextTrafficPermitted="true">
          ????????<trust-anchors>
          ????????????<certificates?src="system"?/>
          ????????????<certificates?src="user"?/>
          ????????</trust-anchors>
          ????</base-config>
          </network-security-config>

          這樣即表示,App信任用戶CA證書,讓系統(tǒng)對(duì)用戶CA證書的校驗(yàn)給予通過。更多相關(guān)信息,詳見

          Network security configuration:

          https://developer.android.com/training/articles/security-config

          調(diào)低targetSdkVersion < 24

          如果想抓一個(gè)App的包,可以找個(gè)歷史版本,只需要其targetSdkVersion < 24即可。然而,隨著GooglePlay開始限制targetSdkVersion,現(xiàn)在要求其必須>=26,2019年8月1日后必須>=28,國內(nèi)應(yīng)用市場也開始逐步響應(yīng)這種限制。絕大多數(shù)App的targetSdkVersion都將大于24了,也就意味著抓HTTPS的包越來越難操作了。

          平行空間抓包

          如果我們希望抓targetSdkVersion >= 24的應(yīng)用的包,那又該怎么辦呢?我們可以使用平行空間或者VirtualApp來曲線救國。平行空間和VirtualApp這種多開應(yīng)用可以作為宿主系統(tǒng)來運(yùn)行其它應(yīng)用,如果平行空間和VirtualApp的targetSdkVersion < 24,那么問題也就解決了。

          在此,我推薦使用平行空間,相比部分開源的VirtualApp,平行空間運(yùn)行得更加穩(wěn)定。但必須注意平行空間的版本4.0.8625以下才是targetSdkVersion < 24,別安裝錯(cuò)了。當(dāng)然,HttpCanary的設(shè)置中是可以直接安裝平行空間的。

          安裝到系統(tǒng)CA證書目錄

          對(duì)于Root的機(jī)器,這是最完美最佳的解決方案。如果把CA證書安裝到系統(tǒng)CA證書目錄中,那這個(gè)假CA證書就是真正洗白了,不是真的也是真的了。由于系統(tǒng)CA證書格式都是特殊的.0格式,我們必須將抓包工具內(nèi)置的CA證書以這種格式導(dǎo)出,HttpCanary直接提供了這種導(dǎo)出選項(xiàng)。

          操作路徑:設(shè)置 -> SSL證書設(shè)置 -> 導(dǎo)出HttpCanary根證書 -> System Trusted(.0)。

          826efd2d0f55533ff6afd1ad7f8b878c.webp圖片

          PS. 很不幸的HttpCanary v2.8.0前導(dǎo)出的證書名稱可能不正確,建議升級(jí)到v2.8.0以上版本操作。

          導(dǎo)出.0格式的證書后,可以使用MT管理器將.0文件復(fù)制到/etc/security/cacerts/目錄下,或者通過adb remount然后push也可(這里稍微提一下,別在sdcard里找這個(gè)目錄)。

          / ?Firefox證書安裝 ?/

          火狐瀏覽器Firefox自行搞了一套CA證書管理,無論是系統(tǒng)CA證書還是用戶CA證書,F(xiàn)irefox通通都不認(rèn)可。這種情況,我們需要將CA證書通過特殊方式導(dǎo)入到Firefox中,否則Firefox瀏覽網(wǎng)頁就無法工作了。

          HttpCanary v2.8.0版本提供了Firefox證書導(dǎo)入選項(xiàng)。在設(shè)置 -> SSL證書設(shè)置 -> 添加HttpCanary根證書至Firefox 中:

          dc0e3b78424109101dc69473109eadf3.webp圖片

          點(diǎn)擊右上角復(fù)制按鈕將url復(fù)制到粘貼板,然后保持此頁面不動(dòng),打開Firefox粘貼輸入復(fù)制的url。

          a3afdc1cc82b7aa8386fe3644a7a5665.webp圖片

          出現(xiàn)下載證書彈框后,一定要手動(dòng)勾上:信任用來標(biāo)志網(wǎng)站和信任用來標(biāo)志電子郵件用戶。然后確定即可。

          / ?公鑰證書固定 ?/

          證書固定(Certificate Pinning)是指Client端內(nèi)置Server端真正的公鑰證書。在HTTPS請(qǐng)求時(shí),Server端發(fā)給客戶端的公鑰證書必須與Client端內(nèi)置的公鑰證書一致,請(qǐng)求才會(huì)成功。

          在這種情況下,由于MITM Server創(chuàng)建的公鑰證書和Client端內(nèi)置的公鑰證書不一致,MITM Server就無法偽裝成真正的Server了。這時(shí),抓包就表現(xiàn)為App網(wǎng)絡(luò)錯(cuò)誤。已知的知名應(yīng)用,比如餓了么,就采用了證書固定。

          另外,有些服務(wù)器采用的自簽證書(證書不是由真正CA發(fā)行商簽發(fā)的),這種情況App請(qǐng)求時(shí)必須使用證書固定。

          證書固定的一般做法是,將公鑰證書(.crt或者.cer等格式)內(nèi)置到App中,然后創(chuàng)建TrustManager時(shí)將公鑰證書加進(jìn)去。很多應(yīng)用還會(huì)將內(nèi)置的公鑰證書偽裝起來或者加密,防止逆向提取,比如餓了么就偽裝成了png,當(dāng)然對(duì)公鑰證書偽裝或者加密沒什么太大必要,純粹自欺欺人罷了。

          證書固定對(duì)抓包是個(gè)非常麻煩的阻礙,不過我們總是有辦法繞過的,就是麻煩了點(diǎn)。

          JustTrustMe破解證書固定

          Xposed和Magisk都有相應(yīng)的模塊,用來破解證書固定,實(shí)現(xiàn)正常抓包。破解的原理大致是,Hook創(chuàng)建SSLContext等涉及TrustManager相關(guān)的方法,將固定的證書移除。

          基于VirtualApp的Hook機(jī)制破解證書固定

          Xposed和Magisk需要刷機(jī)等特殊處理,但是如果不想刷機(jī)折騰,我們還可以在VirtualApp中加入Hook代碼,然后利用VirtualApp打開目標(biāo)應(yīng)用進(jìn)行抓包。當(dāng)然,有開發(fā)者已經(jīng)實(shí)現(xiàn)了相關(guān)的功能。詳見:

          案例1:

          https://github.com/PAGalaxyLab/VirtualHook

          案例2:

          https://github.com/rk700/CertUnpinning

          不過,這里CertUnpinning插件的代碼有點(diǎn)問題,要改改。

          導(dǎo)入真正的公鑰證書和私鑰

          如果Client固定了公鑰證書,那么MITM Server必須持有真正的公鑰證書和匹配的私鑰。如果開發(fā)者具有真正服務(wù)端的公鑰證書和私鑰,(比如百度的公鑰證書和私鑰百度的后端開發(fā)肯定有),如果真有的話,可以將其導(dǎo)入HttpCanary中,也可以完成正常抓包。

          在設(shè)置 -> SSL證書設(shè)置 -> 管理SSL導(dǎo)入證書 中,切換到服務(wù)端,然后導(dǎo)入公鑰證書+私鑰,支持.p12和.bks格式文件。

          / ?雙向認(rèn)證 ?/

          SSL/TLS協(xié)議提供了雙向認(rèn)證的功能,即除了Client需要校驗(yàn)Server的真實(shí)性,Server也需要校驗(yàn)Client的真實(shí)性。這種情況,一般比較少,但是還是有部分應(yīng)用是開啟了雙向認(rèn)證的。比如匿名社交應(yīng)用Soul部分接口就使用了雙向認(rèn)證。使用了雙向認(rèn)證的HTTPS請(qǐng)求,同樣無法直接抓包。

          關(guān)于雙向認(rèn)證的原理

          首先,雙向認(rèn)證需要Server支持,Client必須內(nèi)置一套公鑰證書 + 私鑰。在SSL/TLS握手過程中,Server端會(huì)向Client端請(qǐng)求證書,Client端必須將內(nèi)置的公鑰證書發(fā)給Server,Server驗(yàn)證公鑰證書的真實(shí)性。

          注意,這里的內(nèi)置的公鑰證書有區(qū)別于前面第5點(diǎn)的公鑰證書固定,雙向認(rèn)證內(nèi)置的公鑰證書+私鑰是額外的一套,不同于證書固定內(nèi)置的公鑰證書。

          如果一個(gè)Client既使用證書固定,又使用雙向認(rèn)證,那么Client端應(yīng)該內(nèi)置一套公鑰證書 + 一套公鑰證書和私鑰。第一套與Server端的公鑰證書相同,用于Client端系統(tǒng)校驗(yàn)與Server發(fā)來的證書是否相同,即證書固定;第二套SSL/TLS握手時(shí)公鑰證書發(fā)給Server端,Server端進(jìn)行簽名校驗(yàn),即雙向認(rèn)證。

          用于雙向認(rèn)證的公鑰證書和私鑰代表了Client端身份,所以其是隱秘的,一般都是用.p12或者.bks文件+密鑰進(jìn)行存放。由于是內(nèi)置在Client中,存儲(chǔ)的密鑰一般也是寫死在Client代碼中,有些App為了防反編譯會(huì)將密鑰寫到so庫中,比如S匿名社交App,但是只要存在于Client端中都是有辦法提取出來的。

          雙向認(rèn)證抓包

          這里以S匿名社交App為例,講解下如何抓取使用了雙向認(rèn)證的App的HTTPS包。如果服務(wù)器使用了Nginx且開啟了雙向認(rèn)證,抓包時(shí)會(huì)出現(xiàn)400 Bad Request的錯(cuò)誤,如下:

          d0f5f3a7791ac98a222590a054ede0bc.webp圖片af4b603f91e09430e372ea648ccc9d96.webp圖片

          有些服務(wù)器可能不會(huì)返回404,直接請(qǐng)求失敗。接下來看,如何使用HttpCanary配置雙向認(rèn)證抓包。

          首先,解壓APK,提取出.p12或者.bks文件,二進(jìn)制的文件一般存放都在raw或者assets目錄。

          70a4885eede3f0805c91a37b3d75e9e5.webp圖片

          將client.p12文件導(dǎo)入手機(jī),然后在HttpCanary的設(shè)置 -> SSL證書設(shè)置 -> 管理SSL導(dǎo)入證書中,切換到客戶端(因?yàn)樾枰浣oMITM Client),然后導(dǎo)入.p12文件。

          由于雙向認(rèn)證的公鑰證書和私鑰是受密鑰保護(hù)的,所以需要輸入密碼:

          c8334557ca19ced66ad35f6cac4a057f.webp圖片

          一般通過逆向可以從APK中提取出密鑰,具體操作這里略過。輸入密鑰后,需要輸入映射域名,這里使用通配符*映射所有相關(guān)域名:

          d2ee09ab8221af0382adfe619600e2d6.webp圖片

          導(dǎo)入完成后如下:

          可以點(diǎn)進(jìn)證書詳情查看細(xì)節(jié),這個(gè)client.p12文件包含公鑰證書和私鑰,是用于雙向認(rèn)證的。

          51070ab23bc68d7e98e9b42bcf34aab8.webp圖片

          配置完成后,重新進(jìn)行抓包,看看效果。

          b3e59ad1701a2c20c9a220fd43e204d9.webp圖片

          可以看到,之前400 Bad Request的兩個(gè)要求雙向認(rèn)證的請(qǐng)求成功了!

          / ?SSL重協(xié)商 ?/

          有些服務(wù)器可能會(huì)開啟SSL重協(xié)商,即SSL/TLS握手成功后發(fā)送請(qǐng)求時(shí)服務(wù)器會(huì)要求重新握手。這種情況一般比較少,但是也不排除,已知的應(yīng)用比如 10000社區(qū) 就使用了SSL重協(xié)商。

          由于Android系統(tǒng)對(duì)SSL重協(xié)商是有限支持,所以部分系統(tǒng)版本抓包會(huì)失敗,表現(xiàn)為網(wǎng)絡(luò)異常。在Android 8.1以下,SslSocket是完全支持SSL重協(xié)商的,但是SSLEngine卻是不支持SSL重協(xié)商的,而HttpCanary解析SSL/TLS使用的是SSLEngine。在Android 8.1及以上,SSLEngine和SslSocket統(tǒng)一了實(shí)現(xiàn),故是支持SSL重協(xié)商的。

          所以,如果確認(rèn)服務(wù)器使用了SSL重協(xié)商,請(qǐng)使用8.1及以上版本系統(tǒng)進(jìn)行抓包。

          / ?非Http協(xié)議抓包 ?/

          如果確認(rèn)了以上幾點(diǎn),HttpCanary仍然抓包失敗,那么極有可能使用的并非是HTTP協(xié)議。比如像微信聊天,視頻直播等,使用的就不是HTTP協(xié)議,這種情況需要使用其它的抓包工具,比如Packet Capture這種直接解析TCP/UDP協(xié)議的,但是往往非HTTP協(xié)議的數(shù)據(jù)包即使抓到了也無法解析出來,因?yàn)榇蟾怕识际嵌M(jìn)制而非文本格式的。

          / ?總結(jié) ?/

          抓包是個(gè)技術(shù)活兒,需要對(duì)網(wǎng)絡(luò)協(xié)議有大致的了解,對(duì)抓包感興趣的同學(xué)可以多查閱TCP、UDP、SSL/TLS、HTTP等相關(guān)資料。

          HttpCanary是專業(yè)的HTTP協(xié)議抓包工具,專注HTTP協(xié)議三十年(吹過頭了),不過目前還不支持QUIC/HTTP3這種新協(xié)議,等QUIC/HTTP3正式應(yīng)用起來再說吧。

          關(guān)于HttpCanary的使用可以看我的視頻:?

          https://www.bilibili.com/video/BV1e24y1f72m/?spm_id_from=333.999.0.0


          推薦閱讀


          App逆向|App一般逆向流程記錄

          手把手教你用Google Pixel刷機(jī)和Roo




          瀏覽 82
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  激情国产福利 | 亚洲狼友视频 | 午夜久久精品嫖妓av一区二区三区 | 日本一级A片在线观看视频 | 天天天干夜夜夜 |