Android App | 您所在的位置:網(wǎng)站首頁 › 屬兔人4月出生好不好女孩 › Android App |
Android App—HTTPS證書校驗繞過
![]() Android滲透過程中,會經(jīng)常遇見https證書校驗,不能抓取數(shù)據(jù)包。就比如我手機(jī)無法Root,每次都要用到模擬器,但是有些App它會檢查是否在模擬器中運行,從而閃退無法正常使用。于是,這篇文章誕生了。 基礎(chǔ)學(xué)習(xí):APP是HTTPS的服務(wù)提供方自己開發(fā)的客戶端,開發(fā)者可以先將自己服務(wù)器的證書打包內(nèi)置到自己的APP中,或者將證書簽名內(nèi)置到APP中,當(dāng)客戶端在請求服務(wù)器建立連接期間收到服務(wù)器證書后,先使用內(nèi)置的證書信息校驗一下服務(wù)器證書是否合法,如果不合法,直接斷開 當(dāng)APP是HTTPS時,單純的使用Burpsuite無法抓取數(shù)據(jù)包,原因是APP啟用了SSL Pinning(又叫做“SSL證書綁定”) 如果這里不懂的話,可以了解以下https的建立過程: ?![]() 抓包原理: 幾乎所有網(wǎng)絡(luò)數(shù)據(jù)的抓包都是采用中間人的方式(MITM),包括大家常用的Fiddler、Charles等知名抓包工具 不論是使用burpsuite還是fiddler,當(dāng)前的抓包工具基本原理都是采用的中間人的方式。原理就是這些工具作為中間人,對客戶端偽裝成服務(wù)端,對服務(wù)端偽裝成客戶端 Android App 抓包有三種情況(https):情況1,客戶端不存在證書校驗,服務(wù)器也不存在證書校驗。情況2,客戶端存在校驗服務(wù)端證書,服務(wù)器也不存在證書校驗,單項校驗。情況3、客戶端存在證書校驗,服務(wù)器也存在證書校驗,雙向校驗。 1、使用jd-gui進(jìn)行反編譯后,全局搜索:checkClientTrusted 或者checkServerTrusted 字符串,如下圖: 情況1:apk程序客戶端與服務(wù)端都沒有存在證書校驗 ?![]() 設(shè)置代理,偽造證書,即可成功抓取數(shù)據(jù)包 情況2:存在檢測服務(wù)器端證書(SSL pinning):由于服務(wù)器并不會校驗Client(絕大部分情況),所以這個問題一般不會存在。比如Server一般不會關(guān)心Client到底是Chrome瀏覽器還是IE瀏覽器,是Android App還是iOS App,比如谷歌瀏覽器就能夠模擬移動端。當(dāng)然,Server也是可以校驗Client的,這個后面分析。 ?![]() 在無法root的設(shè)備上抓包: ?![]() SSL Pinning是一種防止中間人攻擊的技術(shù),主要機(jī)制是在客戶端發(fā)起請求–>收到服務(wù)器發(fā)來的證書進(jìn)行校驗,如果收到的證書不被客戶端信任,就直接斷開連接不繼續(xù)求情。可以發(fā)現(xiàn)中間人攻擊的要點的偽造了一個假的服務(wù)端證書給了客戶端,客戶端誤以為真。解決思路就是,客戶端也預(yù)置一份服務(wù)端的證書,比較一下就知道真假了。 SSL-pinning有兩種方式:證書鎖定(Certificate Pinning) 和公鑰鎖定( Public Key Pinning) 證書鎖定: 需要在客戶端代碼內(nèi)置僅接受指定域名的證書,而不接受作系統(tǒng)或瀏覽器內(nèi)置的CA根證書對應(yīng)的任何證書,通過這種授權(quán)方式,保障了APP與服務(wù)端通信的唯一性和安全性,因此客戶端與服務(wù)端(例如API網(wǎng)關(guān))之間的通信是可以保證絕對安全。但是CA簽發(fā)證書都存在有效期問題,缺點是在證書續(xù)期后需要將證書重新內(nèi)置到APP中 公鑰鎖定: 提取證書中的公鑰并內(nèi)置到客戶端中,通過與服務(wù)器對比公鑰值來驗證連接的正確性。制作證書密鑰時,公鑰在證書的續(xù)期前后都可以保持不變(即密鑰對不變),所以可以避免證書有效期問題,一般推薦這種做法。 https需要CA證書,我們之前說的中間人需要對客戶端偽裝成真正的服務(wù)端,要求就是當(dāng)客戶端向我們發(fā)送網(wǎng)絡(luò)請求時,我們必須能夠給指定域名簽發(fā)公鑰證書,且公鑰證書能夠通過系統(tǒng)的安全校驗。對于我們是不是真正的客戶端,通常來說服務(wù)器是不太會關(guān)心的,他是不會去關(guān)心你是谷歌瀏覽器還是百度瀏覽器,當(dāng)然了也會有例外。接下來要說的雙向驗證就是如此 繞過方案一:burpsuite CA證書安裝繞過: 在已經(jīng)root的設(shè)備上安裝CA證書,然后直接抓包即可,在本機(jī)無法取得root的情況下,通過模擬器也可抓到https數(shù)據(jù)包 繞過方案二(無需root,通用):思路: 反編譯apk,找到校驗證書方法,將校驗部分刪除,從而變成情況1,再編譯apk,成功抓取數(shù)據(jù)包 利用條件: 客戶端程序沒有對自身完整性進(jìn)行校驗應(yīng)用完整性校檢 利用Androidkiller.exe反編譯apk文件,找到checkServerTrusted方法的smali代碼: ?![]() 對齊進(jìn)行適量刪改后: ?![]() 反編譯apk文件再查看其代碼: ?![]() 安裝apk至Android設(shè)備,嘗試抓包: ?![]() ![]() Xposed框架+JustTrustMe 繞過: Xposed框架是一款開源框架,其功能是可以在不修改APK的情況下影響程序運行(修改系統(tǒng))的框架服務(wù),基于它可以制作出許多功能強(qiáng)大的模塊,且在功能不沖突的情況下同時運作。Xposed 就好比是 Google 模塊化手機(jī)的主體,只是一個框架的存在,在添加其他功能模塊(Modules)之前,發(fā)揮不了什么作用,但是沒了它也不行。也正因為如此,Xposed 具有比較高的可定制化程度。Moto X 用戶可定制手機(jī)的外觀、壁紙、開機(jī)動畫等,Xposed 則允許用戶自選模塊對手機(jī)功能進(jìn)行自定義擴(kuò)充。 JustTrustMe:https://github.com/Fuzion24/JustTrustMe/releases JustTrustMe 一個用來禁用、繞過 SSL 證書檢查的基于 Xposed 模塊。簡單來說,JustTrustMe 是將 APK 中所有用于校驗 SSL 證書的 API 都進(jìn)行了 Hook,從而繞過證書檢查 在夜神模擬器上就可以直接下載安裝: ?![]() 注意:使用Xposed時需注意,盡可能安裝至模擬器中,不然手機(jī)可能變磚。 ?![]() 將JustTrustMe.apk 拖入模擬器中,然后進(jìn)入Xposed激活并重啟 ?![]() Frida繞過,詳情參考如下:Frida詳細(xì)安裝教程https://github.com/WooyunDota/DroidDrops/blob/master/2018/Frida.Android.Practice.md 情況三:雙向認(rèn)證當(dāng)服務(wù)器啟用了證書雙向認(rèn)證之后,除了客戶端去驗證服務(wù)器端的證書外,服務(wù)器也同時需要驗證客戶端的證書,也就是會要求客戶端提供自己的證書,如果沒有通過驗證,則會拒絕連接,如果通過驗證,服務(wù)器獲得用戶的公鑰 詳細(xì)過程: (1)客戶端發(fā)起HTTPS請求,將SSL協(xié)議版本的信息發(fā)送給服務(wù)端。(2)服務(wù)端去CA機(jī)構(gòu)申請來一份CA證書,在前面提過,證書里面有服務(wù)端公鑰和簽名。將CA證書發(fā)送給客戶端(3)客戶端讀取CA證書的明文信息,采用相同的hash散列函數(shù)計算得到信息摘要(hash目的:驗證防止內(nèi)容被修改),然后用作系統(tǒng)帶的CA的公鑰去解密簽名(因為簽名是用CA的私鑰加密的),對比證書中的信息摘要。如果一致,則證明證書是可信的,然后取出了服務(wù)端公鑰(4)客戶端發(fā)送自己的客戶端證書給服務(wù)端,證書里面有客戶端的公鑰:C_公鑰(5)客戶端發(fā)送支持的對稱加密方案給服務(wù)端,供其選擇(6)服務(wù)端選擇完加密方案后,用剛才得到的C_公鑰去加密選好的加密方案(7)客戶端用自己的C_私鑰去解密選好的加密方案,客戶端生成一個隨機(jī)數(shù)(密鑰F),用剛才等到的服務(wù)端B_公鑰去加密這個隨機(jī)數(shù)形成密文,發(fā)送給服務(wù)端。(8)服務(wù)端和客戶端在后續(xù)通訊過程中就使用這個密鑰F進(jìn)行通信了。和之前的非對稱加密不同,這里開始就是一種對稱加密的方式 雙向認(rèn)證需要Server支持,Client必須內(nèi)置一套公鑰證書 + 私鑰。在SSL/TLS握手過程中,Server端會向Client端請求證書,Client端必須將內(nèi)置的公鑰證書發(fā)給Server,Server驗證公鑰證書的真實性 雙向認(rèn)證內(nèi)置的公鑰證書+私鑰是額外的一套,不同于證書固定內(nèi)置的公鑰證書 用于雙向認(rèn)證的公鑰證書和私鑰代表了Client端身份,所以其是隱秘的,一般都是用.p12或者.bks文件+密鑰進(jìn)行存放。由于是內(nèi)置在Client中,存儲的密鑰一般也是寫死在Client代碼中,有些App為了防反編譯會將密鑰寫到so庫中,比如S匿名社交App,但是只要存在于Client端中都是有辦法提取出來的 這里我們以Soul舉例: 該app直接封裝了客戶端的證書,相比于單項認(rèn)證,多了一個服務(wù)器端驗證客戶端證書的過程,而在以往的用代理工具如burp這類工具,抓取https的包時,除了瀏覽器獲取的是代理工具的證書外,默認(rèn)是不發(fā)送證書給服務(wù)器端的。burp在抓取https報文的過程中也提供了雙向認(rèn)證的證書發(fā)送,但是是使用了burp提供的證書文件,也就是CA證書。app的服務(wù)端不認(rèn)證這個burp提供的CA證書,那么我們就需要拿到匹配的證書,以其對服務(wù)端進(jìn)行匹配 首先,解壓APK,提取出.p12/.pfx或者.bks文件,二進(jìn)制的文件一般存放都在raw或者assets目錄 ?![]() 由于雙向認(rèn)證的公鑰證書和私鑰是受密鑰保護(hù)的,所以需要輸入密碼 app解密的代碼邏輯: 客戶端發(fā)送數(shù)據(jù)包以后,需要去從app中讀取這個證書文件,密碼是以硬編碼形式放在了代碼中,利用這個代碼中的密碼字段去解密證書文件,從中讀取以后,再進(jìn)行解密并回傳給服務(wù)器端進(jìn)行確認(rèn)。由此推斷,尋找證書名稱應(yīng)該就可以拿到安裝密碼 利用搜索來找client.p12的值(或者關(guān)鍵字PKCS12,這是通常讀取證書需要用到的關(guān)鍵字) 一般通過逆向可以從APK中提取出密鑰,怪我太菜java完全不會,Android滲透剛剛接觸,這里先略過,以后再來填坑…… ?![]() 詳情可以參考:APP 如何進(jìn)行HTTPS雙向認(rèn)證抓包APP無法抓包解決方案 安卓單向/雙向認(rèn)證 找到之后可以通過burp添加客戶端證書:host填寫app服務(wù)端的主域名: ?![]() 選擇app客戶端內(nèi)的client.p12證書文件,并輸入安裝密碼 ?![]() 證書成功導(dǎo)入后,勾選即可使用 雙向驗證與SSL pinning的區(qū)別:SSL pinning實際上是客戶端鎖定服務(wù)器端的證書, 在要與服務(wù)器進(jìn)行交互的時候, 服務(wù)器端會將CA證書發(fā)送給客戶端, 客戶端會調(diào)用函數(shù)對服務(wù)器端的證書進(jìn)行校驗, 與本地的服務(wù)器端證書(存放在.\asset目錄或\res\raw下)進(jìn)行比對。而雙向認(rèn)證是添加了客戶端向服務(wù)器發(fā)送CA證書, 服務(wù)器端對客戶端的證書進(jìn)行校驗的部分。在app上,https雙向認(rèn)證的方案也可以防止中間人劫持,但這種雙向認(rèn)證開銷較大,且安全性與SSL pinning一致,目前大多數(shù)app都采用SSL Pinning這種方案 CA證書:抓包應(yīng)用內(nèi)置的CA證書要洗白,必須安裝到系統(tǒng)中。而Android系統(tǒng)將CA證書又分為兩種:用戶CA證書和系統(tǒng)CA證書。顧明思議,用戶CA證書是由用戶自行安裝的,系統(tǒng)CA證書是由系統(tǒng)內(nèi)置的,很明顯后者更加真實有效 系統(tǒng)CA證書存放在/etc/security/cacerts/目錄下,名稱是CA證書subjectDN的Md5值前四位移位取或,后綴名是.0,比如00673b5b.0。考慮到安全原因,系統(tǒng)CA證書需要有Root權(quán)限才能進(jìn)行添加和刪除。 對于非Root的Android設(shè)備,用戶只能安裝用戶CA證書。 使用限制: Android從7.0開始系統(tǒng)不再信任用戶CA證書(應(yīng)用targetSdkVersion >= 24時生效,如果targetSdkVersion < 24即使系統(tǒng)是7.0+依然會信任)。也就是說即使安裝了用戶CA證書,在Android 7.0+的機(jī)器上,targetSdkVersion >= 24的應(yīng)用的HTTPS包就抓不到了 繞過方案一:配置networkSecurityConfig1、在AndroidManifest中配置networkSecurityConfig形如: ...2、在項目res目錄下新增一個文件夾,命名xml,并且新建一個xml文件,命名為network_security_config.xml,命名名稱跟上面匹配。 這樣即表示,App信任用戶CA證書,讓系統(tǒng)對用戶CA證書的校驗給予通過詳情請參考:https://developer.android.com/training/articles/security-config 最開始直接通過adb安裝,發(fā)現(xiàn)無法抓到包 ?![]() 成功抓到包: ?![]() ![]() 如果想抓一個App的包,可以找個歷史版本,只需要其targetSdkVersion < 24即可。然而,隨著GooglePlay開始限制targetSdkVersion,現(xiàn)在要求其必須>=26,2019年8月1日后必須>=28,國內(nèi)應(yīng)用市場也開始逐步響應(yīng)這種限制。然后目前絕大多數(shù)App的targetSdkVersion都大于24 繞過方案三:平行空間抓包:如果我們希望抓targetSdkVersion >= 24的應(yīng)用的包,那又該怎么辦呢?我們可以使用平行空間或者VirtualApp來曲線救國。平行空間和VirtualApp這種多開應(yīng)用可以作為宿主系統(tǒng)來運行其它應(yīng)用,如果平行空間和VirtualApp的targetSdkVersion < 24,那么問題也就解決了。 繞過方案四:安裝到系統(tǒng)CA證書目錄(需root) 非Http協(xié)議抓包:如果確認(rèn)了以上幾點,仍然抓包失敗,那么極有可能使用的并非是HTTP協(xié)議。比如像微信聊天,視頻直播等,使用的就不是HTTP協(xié)議,這種情況需要使用其它的抓包工具,比如Packet Capture這種直接解析TCP/UDP協(xié)議的,但是往往非HTTP協(xié)議的數(shù)據(jù)包即使抓到了也無法解析出來,因為大概率都是二進(jìn)制而非文本格式的。 補(bǔ)充:所有https能抓到包的前天是基于https證書校驗不嚴(yán)格,如果證書校驗嚴(yán)格的話是抓不到的 參考如下:Android平臺HTTPS抓包全方案APP抓包——Xposed+JustTrustMe關(guān)閉SSL證書驗證Android滲透測試HTTPS證書校驗繞過【移動安全】記一次APP雙向認(rèn)證抓包android系統(tǒng)https抓包問題分析APP 如何進(jìn)行HTTPS雙向認(rèn)證抓包APP無法抓包解決方案 安卓單向/雙向認(rèn)證 |
今日新聞 |
推薦新聞 |
專題文章 |
CopyRight 2018-2019 實驗室設(shè)備網(wǎng) 版權(quán)所有 |