抓包技術(shù)分析及SSL PINNING保護方案

要分析抓包的技術(shù)首先要介紹數(shù)字證書是什么辽社,一切的抓包手段都是圍繞數(shù)字證書做文章

數(shù)字證書

TLS 握手的作用之一是身份認證,被驗證的一方需要提供一個身份證明钾恢,在 HTTPS 的世界里手素,這個身份證明就是 TLS 證書鸳址,或者稱為 數(shù)字證書

JDK 中用 java.security.cert.X509Certificate 來表示一個證書,它繼承自抽象類 java.scurity.cert.Certificate泉懦,通過 X509Certificate 我們可以獲取證書的信息,例如x509Certificate.getSubjectDN().getName()


數(shù)字證書構(gòu)成.png

x509Certificate.getSubjectDN().getName()獲取到的是證書的Subject's Name的信息即證書擁有者稿黍,內(nèi)容是一組符合 X.500 規(guī)范的 DN(Distinguished Name)

CN=*,OU=IT Department,O=China Merchants Bank Co., Ltd,L=Shenzhen,C=CN

這是從我們證書中獲取到的信息,DN的屬性含義如圖所示

DN參數(shù)

通過命令openssl x509 -in base64.cer –text 查看證書信息崩哩,輸出如圖所示
可以看出巡球,一個 Certificate 由 Data 和 Signature 兩部分組成。其中 Data 包含的內(nèi)容有:
證書版本號:X.509v3
序列號:一個 CA 機構(gòu)內(nèi)是唯一的邓嘹,但不是全局唯一
簽名算法:簽名的計算公式為RSA(sha256(Data), IssuerPrivateKey)
簽發(fā)者:DN(Distinguished Name)
有效期:證書的有效期間 [Not Before, Not After]
證書擁有者:也是一個 DN公鑰長度一般是 2048bit酣栈,1024bit已經(jīng)被證明不安全
擴展字段:證書所攜帶的域名信息會配置在 SAN 中(X509v3 Subject Alternative Name)
Signature 位于證書最末尾,簽名算法 sha256WithRSAEncryption 在 Data 域內(nèi)已經(jīng)指明 汹押,而 RSA 進行非對稱加密所需的私鑰(Private Key)則是由 Issuer 提供矿筝,Issuer 是一個可以簽發(fā)證書的證書,由證書權(quán)威 CA 提供棚贾,CA 需要保證證書的有效性窖维。
因為 Signature 是 RSA 算法生成的,那么客戶端拿到 TLS 證書之后妙痹,需要 Issuer 的公鑰(Public Key)才能解碼出 Data 的摘要铸史。
然而證書只攜帶了 Issuer 的 DN,并沒有公鑰细诸,為了弄清楚客戶端如何獲取公鑰沛贪,我們需要先搞明白 Certificate Chain(證書鏈)。


證書信息

證書鏈

一個完整的證書鏈一般由三種類型的證書組成

  • Root Certificate (DigiCert Global Root CA) :
    根證書
    Root Certificate是由Root CAs 發(fā)布震贵,一個Root CAs 下包含多個Intermediate CAs 利赋,同理一個Root Certificate下可以包含多個Intermediate Certificate。根證書是CA自己的證書猩系,是證書驗證鏈的開頭
  • Intermediate Certificate (DigiCert SHA2 Secure Server CA):
    中間證書或者叫做中介證書
    Intermediate Certificate是由Intermediate CAs 發(fā)布媚送,一個Intermediate CAs 下可以包含多個Intermediate CAs ,同理一個Intermediate Certificate下可以包含多個Intermediate Certificate也可以包含End-entity Certificate寇甸。CA會使用Intermediate Certificate 替代Root Certificate去做服務(wù)器端的證書簽名塘偎,確保根證書密鑰絕對不可訪問
  • End-entity Certificate (user.cmbchina.com):
    終端證書即用戶證書
    包含用來加密傳輸數(shù)據(jù)的公鑰的證書,是HTTPS中使用的證書拿霉。 End-entity Certificate上面幾級證書都是為了保證End-entity Certificate未被篡改吟秩,保證是CA簽發(fā)的合法證書,進而保證End-entity Certificate中的公鑰未被篡改


    證書鏈

證書鏈驗證

1.客戶端得到服務(wù)端返回的證書绽淘,通過讀取得到 服務(wù)端證書的發(fā)布機構(gòu)(Issuer)
2.客戶端去操作系統(tǒng)查找這個發(fā)布機構(gòu)的的證書涵防,如果是不是根證書就繼續(xù)遞歸下去直到拿到根證書。
3.匹配客戶端保存的可信任CA與根證書的CA沪铭,確保根證書的合法性
4.用 根證書的公鑰 去 解密驗證 上一層證書的合法性壮池,再拿上一層證書的公鑰去驗證更上層證書的合法性偏瓤;遞歸回溯。
5.最后驗證服務(wù)器端的證書是 可信任

證書鏈驗證

關(guān)于證書鏈信任認證過程可以參考我的另一篇文檔

抓包原理-中間人攻擊

前面基礎(chǔ)性內(nèi)容已經(jīng)鋪墊完畢椰憋,現(xiàn)在正式分析抓包技術(shù)
根據(jù)流程可以得出需要讓中間人攻擊生效厅克,必須讓客戶端的證書連驗證能夠通過,并且現(xiàn)在幾乎所有攻擊手段都是從這入手橙依,實現(xiàn)原理上可以分為兩大類:
1.攻擊客戶端CA信任庫证舟,讓系統(tǒng)在誤認為偽證書是可以信任的,從而向中間人發(fā)送信息票编。手段包括
手機系統(tǒng)中安裝偽證書
root手段導(dǎo)入偽證書至證書庫
修改rom中系統(tǒng)證書庫并燒錄系統(tǒng)
例如Charles褪储,Burp卵渴,Magisk慧域,Packet Capture(VPN)都是使用這種方法
SSL PINING正是對抗這種技術(shù)的方法

抓包流程

2.通過腳本或者框架hook驗證證書的方法,主要手段有:
修改系統(tǒng)checkServerTrusted或者TrustManager等涉及驗證或者整理證書的相關(guān)代碼浪读,返回他們需要的結(jié)果
針對有自己的證書驗證邏輯的第三方框架例如OKHttp昔榴,則hook修改CertificationPinner等方法
APP使用自己封裝的通信方法,則通過逆向代碼hook相關(guān)方法
Xposed+JustTrustMe或者Frida使用的是這種方法碘橘,針對這種技術(shù)則要避免將涉及通信的代碼暴露互订,可以使用混淆,加殼等多種手段

hook腳本代碼

SSL PINNING與雙向認證

綠色表示ssl pinning在正常HTTPS通信過程中增加的操作
紅色表示雙向認證在正常HTTPS通信過程中增加的操作


ssl pinning及雙向認證流程
ssl pinning與系統(tǒng)認證的區(qū)別

SSL PINNING本地證書管理

SSL PINNING唯一缺點即是如何對本地綁定的證書進行更新痘拆,針對該問題研究了一種解決方案方案:

  • 證書服務(wù)器:搭建一個CA服務(wù)器專門用于更新證書或者在驗證證書時通過訪問CA服務(wù)器驗證
  • 與證書服務(wù)器通信內(nèi)容及證書間比對都采用不可逆加密信息仰禽,防止中間人拿到通信內(nèi)容反推出明文
  • 建立客戶端及證書服務(wù)器端黑名單,盡可能減少與通信次數(shù)并增加中間人攻擊成本
  • 證書服務(wù)器與客戶端采用相同加密算法纺蛆,保證加密后信息一致


    證書服務(wù)器

Hook對抗方案

在攻擊手段中吐葵,hook代碼是一個較難防范的點,針對常用的Xposed框架可以做一下防范措施:

  • 檢測進程中使用so名中包含關(guān)鍵"hack|inject|hook|call" 的信息


  • 檢測手機是否被root:含有su程序和ro.secure是否為1


  • 防止被Hook的方式就是可以查看XposedBridge這個類桥氏,有一個全局的hook開關(guān)温峭,所有有的應(yīng)用在啟動的時候就用反射把這個值設(shè)置成true,這樣Xposed的hook功能就是失效了

  • Xposed的hook原理的就是在程序啟動都注入jar功能字支,所以安裝hook模塊之后凤藏,每個應(yīng)用內(nèi)部都包含了這個Xposed功能jar,就相當(dāng)于你的應(yīng)用中有了Xposed的所有功能類堕伪,所以在應(yīng)用中反射Xposed的類是可以成功的


  • 如果應(yīng)用被Xposed進行hook操作之后揖庄,拋出的異常堆棧信息中就會包含Xposed字樣,所以可以通過應(yīng)用自身內(nèi)部拋出異常來檢測是否包含Xposed字段來進行防護


    image.png
  • 如何在代碼中執(zhí)行shell命令并返回結(jié)果

public static ArrayList<String> executeCommand(String[] shellCmd){
        String line = null;
        ArrayList<String> fullResponse = new ArrayList<String>();
        Process localProcess = null;
        try {
            Log.d("gscgsc","excute cmd");
            localProcess = Runtime.getRuntime().exec(shellCmd);
        } catch (Exception e) {
            return null;
        }
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(localProcess.getOutputStream()));
        BufferedReader in = new BufferedReader(new InputStreamReader(localProcess.getInputStream()));
        try {
            while ((line = in.readLine()) != null) {
                Log.d("gscgsc","Line received: " + line);
                fullResponse.add(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        Log.d("gscgsc","–> response was: " + fullResponse);
        return fullResponse
}

SSL PINING實現(xiàn)

String hostname = "xxx.com";
CertificatePinner certificatePinner = new CertificatePinner.Builder()
        .add(hostname, "sha256/afwiKY3RxoMmLkuRW1l7QsPZTJPwDS2pdDROQjXw8ig=")
        .add(hostname, "sha256/klO23nT2ehFDXCfx3eHTDRESMz3asj1muO+4aIdjiuY=")
        .add(hostname, "sha256/grX4Ta9HpZx6tSHkmCrvpApTQGo67CYDnvprLg5yRME=")
        .build();

OkHttpClient client = new OkHttpClient.Builder()
        .certificatePinner(certificatePinner)
        .build();

Request request = new Request.Builder()
        .url("https://" + hostname)
        .build();

client.newCall(request).execute();

SSL PINING實現(xiàn)原理

證書校驗時機
private void connectTls(ConnectionSpecSelector connectionSpecSelector) throws IOException {
    //包裝socket
    sslSocket = (SSLSocket) sslSocketFactory.createSocket(
            rawSocket, address.url().host(), address.url().port(), true /* autoClose */);
    //配置socket參數(shù)
    ConnectionSpec connectionSpec = connectionSpecSelector.configureSecureSocket(sslSocket);
    //建立握手
    sslSocket.startHandshake();
    Handshake unverifiedHandshake = Handshake.get(sslSocket.getSession());
    //證書校驗
    address.certificatePinner().check(address.url().host(),
            unverifiedHandshake.peerCertificates());
    //檢驗無異常則保存連接
    String maybeProtocol = connectionSpec.supportsTlsExtensions()
            ? Platform.get().getSelectedProtocol(sslSocket)
            : null;
}

//校驗證書與本地證書
public void check (String hostname, List < Certificate > peerCertificates)
throws SSLPeerUnverifiedException {
    for (int p = 0, pinsSize = pins.size(); p < pinsSize; p++) {
        //加密后本地證書的存儲
        Pin pin = pins.get(p);
        //sha256加密
        if (pin.hashAlgorithm.equals("sha256/")) {
            if (sha256 == null) sha256 = sha256(x509Certificate);
            if (pin.hash.equals(sha256)) return; // Success!
        }
        //sha1加密
        else if (pin.hashAlgorithm.equals("sha1/")) {
            if (sha1 == null) sha1 = sha1(x509Certificate);
            if (pin.hash.equals(sha1)) return; // Success!
        }
    }
    //校驗失敗拋出異常
    throw new SSLPeerUnverifiedException(message.toString());
}

結(jié)果如下


結(jié)果
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末欠雌,一起剝皮案震驚了整個濱河市蹄梢,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌桨昙,老刑警劉巖检号,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件腌歉,死亡現(xiàn)場離奇詭異,居然都是意外死亡齐苛,警方通過查閱死者的電腦和手機翘盖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凹蜂,“玉大人馍驯,你說我怎么就攤上這事÷耆” “怎么了汰瘫?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長擂煞。 經(jīng)常有香客問我混弥,道長,這世上最難降的妖魔是什么对省? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任蝗拿,我火速辦了婚禮,結(jié)果婚禮上蒿涎,老公的妹妹穿的比我還像新娘哀托。我一直安慰自己,他們只是感情好劳秋,可當(dāng)我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布仓手。 她就那樣靜靜地躺著,像睡著了一般玻淑。 火紅的嫁衣襯著肌膚如雪嗽冒。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天岁忘,我揣著相機與錄音辛慰,去河邊找鬼。 笑死干像,一個胖子當(dāng)著我的面吹牛帅腌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播麻汰,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼速客,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了五鲫?” 一聲冷哼從身側(cè)響起溺职,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后浪耘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體乱灵,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年七冲,在試婚紗的時候發(fā)現(xiàn)自己被綠了痛倚。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡澜躺,死狀恐怖蝉稳,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情掘鄙,我是刑警寧澤耘戚,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站操漠,受9級特大地震影響收津,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜颅夺,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一朋截、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧吧黄,春花似錦、人聲如沸唆姐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽奉芦。三九已至赵抢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間声功,已是汗流浹背烦却。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留先巴,地道東北人其爵。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像伸蚯,于是被迫代替她去往敵國和親摩渺。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,779評論 2 354