日常Android滲透過(guò)程中蜓陌,會(huì)經(jīng)常遇見(jiàn)https證書校驗(yàn)(http就不存在證書校驗(yàn)了,直接抓包便可)吩蔑,不能抓取數(shù)據(jù)包钮热。APP是HTTPS的服務(wù)提供方自己開(kāi)發(fā)的客戶端,開(kāi)發(fā)者可以先將自己服務(wù)器的證書打包內(nèi)置到自己的APP中烛芬,或者將證書簽名內(nèi)置到APP中隧期,當(dāng)客戶端在請(qǐng)求服務(wù)器建立連接期間收到服務(wù)器證書后飒责,先使用內(nèi)置的證書信息校驗(yàn)一下服務(wù)器證書是否合法,如果不合法仆潮,直接斷開(kāi)宏蛉。
環(huán)境
windows10
burpsuite
jeb3
情況分類
情況1,客戶端不存在證書校驗(yàn)鸵闪,服務(wù)器也不存在證書校驗(yàn)檐晕。
情況2暑诸,客戶端存在校驗(yàn)服務(wù)端證書蚌讼,服務(wù)器也不存在證書校驗(yàn),單項(xiàng)校驗(yàn)个榕。
情況3篡石、客戶端存在證書校驗(yàn),服務(wù)器也存在證書校驗(yàn)西采,雙向校驗(yàn)凰萨。
情況1
舉個(gè)例子:
1、可以拿到apk文件械馆,利用jeb3反編譯apk文件胖眷,反編譯成功,Ctrl+f -->搜索checkClientTrusted或者checkServerTrusted字符串,如下
結(jié)果如下:
反編譯成java代碼霹崎,如下
分析得知珊搀,apk程序客戶端與服務(wù)端都沒(méi)有存在證書校驗(yàn)。設(shè)置代理尾菇,偽造證書境析,成功抓取數(shù)據(jù)包。
情況2
舉個(gè)例子:
1派诬、可以拿到apk文件劳淆,利用jeb3反編譯apk文件,反編譯成功默赂,Ctrl+f -->搜索checkClientTrusted字符串,如下
反編譯成java代碼沛鸵,如下
偽造證書代理,抓取數(shù)據(jù)包出現(xiàn)如下:
存在證書校驗(yàn)缆八,不能成功進(jìn)行抓取數(shù)據(jù)包曲掰。客戶端校驗(yàn)服務(wù)端證書耀里,這個(gè)過(guò)程由于客戶端操作蜈缤,存在不可控因素,可通過(guò)客戶端進(jìn)行繞過(guò)https校驗(yàn)冯挎。
繞過(guò)思路1
反編譯apk底哥,找到校驗(yàn)證書方法咙鞍,將校驗(yàn)部分刪除,從而變成情況1趾徽,成功抓取數(shù)據(jù)包续滋。如下
利用Androidkiller.exe反編譯apk文件,找到checkServerTrusted方法的smali代碼:
將所有校驗(yàn)部分刪除孵奶,如下:
反編譯apk文件疲酌,jeb打開(kāi)重打包的apk。如下
安裝重打包的apk了袁,運(yùn)行朗恳,設(shè)置代理,抓取數(shù)據(jù)包
繞過(guò)思路2
JustTrustMe.apk 是一個(gè)用來(lái)禁用载绿、繞過(guò) SSL 證書檢查的基于 Xposed 模塊粥诫。JustTrustMe 是將 APK 中所有用于校驗(yàn) SSL 證書的 API 都進(jìn)行了 Hook,從而繞過(guò)證書檢查崭庸。xposed的54的可以運(yùn)行怀浆,高版本沒(méi)有測(cè)試,可以自行測(cè)試怕享。
使用如下:
重啟設(shè)備执赡,抓取數(shù)據(jù)包,成功抓取函筋,如下:
繞過(guò)思路3
Frida進(jìn)行繞過(guò)(具體細(xì)節(jié)看參考1)沙合,F(xiàn)rida安裝教程參考,可以下載這里腳本驻呐。其中application.py腳本灌诅,我修改了一下:
# -*- coding: utf-8 -*-
import frida, sys, re, sys, os
import codecs, time
APP_NAME = ""
def sbyte2ubyte(byte):
return (byte % 256)
def print_result(message):
print ("[!] Received: [%s]" %(message))
def on_message(message, data):
if 'payload' in message:
data = message['payload']
if type(data) is str:
print_result(data)
elif type(data) is list:
a = data[0]
if type(a) is int:
hexstr = "".join([("%02X" % (sbyte2ubyte(a))) for a in data])
print_result(hexstr)
print_result(hexstr.decode('hex'))
else:
print_result(data)
print_result(hexstr.decode('hex'))
else:
print_result(data)
else:
if message['type'] == 'error':
print (message['stack'])
else:
print_result(message)
def main():
try:
with codecs.open("hooks.js", 'r', encoding='utf8') as f:
jscode = f.read()
process = frida.get_usb_device().attach(APP_NAME)
script = process.create_script(jscode)
script.on('message', on_message)
print ("[*] Intercepting on (pid: )...")
script.load()
sys.stdin.read()
except KeyboardInterrupt:
print ("[!] Killing app...")
if __name__ == "__main__":
if (len(sys.argv) > 1):
APP_NAME = str(sys.argv[1])
main()
else:
print("must input two arg")
print("For exanple: python application.py packName")
這里以com.flick.flickcheck包名為例,首先pc端運(yùn)行啟動(dòng)frida服務(wù)器腳本startFridaService.py含末,pc端運(yùn)行命令如下:
python application.py com.flick.flickcheck
設(shè)置代理猜拾,抓取數(shù)據(jù)包:
情況3
雙向認(rèn)證:apk客戶端對(duì)服務(wù)器證書進(jìn)行認(rèn)證,服務(wù)器對(duì)客戶端證書進(jìn)行認(rèn)證佣盒,防止證書被篡改挎袜。
客戶端
首先我們嘗試使用 JustTrustMe.apk進(jìn)行繞過(guò),如果發(fā)現(xiàn)繞過(guò)不了肥惭,可能客戶端還存在其他校驗(yàn)盯仪,這里發(fā)現(xiàn)一個(gè)還使用了,如下
下載JustTrustMe的源代碼蜜葱,進(jìn)行編譯全景,增加對(duì)這兩個(gè)函數(shù)的hook,繞過(guò)攔截請(qǐng)求牵囤。重新編譯繞過(guò)的JustTrustMe1.apk
爸黄,下載安裝如下:
勾選滞伟,重啟設(shè)備 (真機(jī)需要重啟設(shè)備xposed才能生效,模擬器軟重啟便可生效)炕贵,再次請(qǐng)求登錄數(shù)據(jù)包梆奈,客戶端返回:
成功繞過(guò)客戶端驗(yàn)證,成功抓取數(shù)據(jù)包称开,查看服務(wù)端返回?cái)?shù)據(jù)包
這里客戶端可嘗試frida hook進(jìn)行繞過(guò)那個(gè)兩個(gè)網(wǎng)絡(luò)攔截方法亩钟,可自己嘗試。
服務(wù)端
服務(wù)器認(rèn)證鳖轰,是因?yàn)榉?wù)端存有客戶端的公鑰清酥,客戶端自己用私鑰進(jìn)行簽名,服務(wù)端用公鑰進(jìn)行驗(yàn)證脆霎。
因此总处,客戶端私鑰一般都是存放在apk本身內(nèi),在apk里找到私鑰睛蛛,便可利用私鑰對(duì)證書進(jìn)行簽名。
1胧谈、拿到apk忆肾,如果存在殼,先進(jìn)行脫殼菱肖,不存在客冈,則直接查看apk的目錄,在assets目錄下發(fā)現(xiàn)了用于雙向認(rèn)證的證書庫(kù)文件稳强,
要使用證書庫(kù)场仲,我們還需要找到證書庫(kù)的密碼,jeb反編譯apk退疫,搜索字符串證書名字字符串 :
反編譯此方法:
發(fā)現(xiàn)證書調(diào)用KeyStore.getInstance方法進(jìn)行簽名渠缕,KeyStore.load的方法進(jìn)行加載私鑰,這里如果apk有殼(加固)褒繁,可以通過(guò)hook這兩個(gè)函數(shù)拿到簽名方法與私鑰亦鳞。
偽造服務(wù)端信任證書,可使用Burpsuite進(jìn)行操作棒坏,User options--->SSL--->Client SSL Certificates燕差,點(diǎn)擊Add:
結(jié)果
再次抓包,如下:
成功繞過(guò)服務(wù)器校驗(yàn)坝冕。
參考
1徒探、https://github.com/WooyunDota/DroidDrops/blob/master/2018/Frida.Android.Practice.md