Windows Internals
Almost every Windows exploit is “an attacker made the kernel call something with the wrong privileges.” PrintNightmare was RpcAddPrinterEx handing out SYSTEM. HiveNightmare was BUILTIN\Users getting read on SAM. Zerologon was a Netlogon AES-CFB8 collision. To read these exploits you must know the registry layout, how services register, what WMI event subscriptions look like in raw form, and which ETW provider writes which Event ID. Without that, you are reading CVEs as prose instead of as code.
The Core Concept
Section titled “The Core Concept”Windows is split between user mode (ring 3) and kernel mode (ring 0), with a stable syscall boundary exposed through ntdll.dll. Each user-mode process has an access token (logon SID, user SID, group SIDs, privilege mask, integrity level); every securable object has a security descriptor (DACL + SACL + owner). Authorization is a single function — SeAccessCheck in ntoskrnl.exe — that walks the DACL against the token.
┌─────────────────────────────────────────────────────┐│ User mode (ring 3) ││ app.exe → kernel32.dll → ntdll.dll → syscall ││ │ ││ ▼ Nt* functions │├─────────────────────────────────────────────────────┤│ Kernel mode (ring 0) ││ ntoskrnl.exe ││ SeAccessCheck → Ob* object manager ││ → Ps* process & threads ││ → Mm* memory manager ││ win32k.sys (GUI subsystem) ││ drivers (TCP/IP, WSK, file system filter) │└─────────────────────────────────────────────────────┘The Registry is a hierarchical key/value database stored in hive files. Five root hives: HKEY_LOCAL_MACHINE (file C:\Windows\System32\config\SYSTEM, SOFTWARE, SAM, SECURITY), HKEY_USERS (one per loaded profile, NTUSER.DAT), HKEY_CLASSES_ROOT (HKLM\SOFTWARE\Classes merged with HKCU\SOFTWARE\Classes), HKEY_CURRENT_USER (alias), HKEY_CURRENT_CONFIG (HKLM\SYSTEM\CurrentControlSet\Hardware Profiles\Current).
How It Works
Section titled “How It Works”- Process and token model. A process is created via
CreateProcess→NtCreateUserProcess. The new process inherits a primary token from the parent (unlessCreateProcessAsUseris used). Integrity Level (Low/Medium/High/System) is encoded as a mandatory-label ACE in the token.whoami /allprints it:Mandatory Label\High Mandatory Level. - Privileges — 35 distinct bit flags in the token. The ones that matter for post-ex:
SeDebugPrivilege— open any process (includinglsass.exe); granted to Administrators by default.SeImpersonatePrivilege— let a thread act as another user viaImpersonateNamedPipeClient/RpcImpersonateClient. Granted to Service accounts. Base of PrintSpoofer, JuicyPotato, GodPotato.SeAssignPrimaryTokenPrivilege+SeIncreaseQuotaPrivilege— potato-style token theft.SeTcbPrivilege— “act as part of the operating system”; LSASS, winlogon, services.exe hold it.
- Service registration — services are persisted under
HKLM\SYSTEM\CurrentControlSet\Services\<name>:ImagePath(REG_EXPAND_SZ) — full command line. This is where attackers putpowershell -enc ...or a payload EXE.Type—0x10=SERVICE_WIN32_OWN_PROCESS,0x20=SERVICE_WIN32_SHARE_PROCESS,0x1= kernel driver.Start—0Boot,1System,2Auto,3Manual (demand),4Disabled.ObjectName— account the service logs in as (LocalSystemdefault).FailureActions— what to do on crash; this is the persistence trick (reboot-on-fail → re-execute payload).
- WMI persistence — three objects in
root\subscription:The consumer is stored in__EventFilter → Query: SELECT * FROM __InstanceModificationEventWITHIN 60 WHERE TargetInstance ISA 'Win32_LocalTime'AND TargetInstance.Hour = 8CommandLineEventConsumer → CommandLineTemplate = "powershell -nop -w hidden -c ..."__FilterToConsumerBinding → links the two by ReferenceC:\Windows\System32\wbem\Repository\OBJECTS.DATA— an ESE database.取证:Get-WmiObject -Namespace root\subscription -Class __EventConsumer,wmic /namespace:\\root\subscription path __EventFilter, or Sysmon Event ID 19/20/21 (WmiFilter/Consumer/Binding registration). - ETW providers — Event Tracing for Windows is the kernel-level logging substrate. Critical provider GUIDs:
Microsoft-Windows-Sysmon{5770385F-C22A-43E0-BF4C-06F5698FFBD9}Microsoft-Windows-PowerShell{A0C1853B-5C40-4B15-8766-3CF1C8F3A15C}— Event ID 4104 (ScriptBlock), 4103 (Module), 400 (Engine lifecycle).Microsoft-Windows-WMI-Activity{1418EF04-B0B4-4623-BF7E-D74AB87BBEAD}— Event ID 5861 (permanent subscription registration).Microsoft-Windows-DNS-Client{1C95126E-7EEA-49A9-A3FE-A378B03DDB4D}— Event ID 3008 (DNS query).Microsoft-Windows-Kernel-Process{22FB2CD6-0E7B-422B-A0C7-2FAD1FD0E716}— process create/exit with image hash.
Common Techniques
Section titled “Common Techniques”| Technique | Description | Detection Difficulty |
|---|---|---|
| PrintNightmare (CVE-2021-1675/34527) | RpcAddPrinterEx → spoolss loads attacker DLL as SYSTEM via AddPrinterDriver | Medium — Event ID 808 in Microsoft-Windows-PrintService |
| HiveNightmare (CVE-2021-36934) | Auto-creates SAM shadow copies readable by BUILTIN\Users; NTLM hashes dumped | Easy — icacls C:\Windows\System32\config\SAM shows BUILTIN\Users:(R) |
| Zerologon (CVE-2020-1472) | Netlogon AES-CFB8 with IV=0 → all-zero plaintext in 1/256 attempts → domain admin | Medium — event 4742 (computer account change) spikes |
| WMI subscription persistence | Filter+Consumer+Binding registered to fire payload on schedule | Medium — Sysmon 19/20/21 + WMI-Activity 5861 |
Service ImagePath tampering | Replace ImagePath of an unused service with payload | Easy — Sysmon 13 (registry value set on Services key) |
| Token impersonation via named pipe | ImpersonateNamedPipeClient after connecting SYSTEM pipe to your client | Medium — Sysmon 17/18 named pipe created/connected |
| Kerberoasting | Request TGS for SPN-enabled account; offline-crack RC4-HMAC ticket | Hard — Event 4769 is normal noise |
Hands-On Commands
Section titled “Hands-On Commands”# List services and their ImagePath; look for non-Microsoft signed binariesGet-CimInstance Win32_Service | Select Name, StartName, PathName, State
# Find services you can modify (write-dACL on the registry key or on the binary)accesschk.exe -uwcqv "Authenticated Users" *# Or with PowerView:Get-ModifiableService
# Read all WMI permanent subscriptions on the boxGet-WmiObject -Namespace root\subscription -Class __EventFilterGet-WmiObject -Namespace root\subscription -Class CommandLineEventConsumerGet-WmiObject -Namespace root\subscription -Class __FilterToConsumerBinding
# Enumerate interesting ETW providers (note the GUID — used by log collectors)logman query providers | findstr /i "powershell sysmon dns-client"
# Find the Sysmon configuration (rules XML) in the registryreg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WINEVT\Channels\Microsoft-Windows-Sysmon/Operational# The configuration itself lives in HKLM\SYSTEM\CurrentControlSet\Services\SysmonDrv\Parameters
# Dump your own token with full detailwhoami /allwhoami /priv# SeImpersonatePrivilege enabled is the starting point for PrintSpoofer / GodPotato
# Find files that have the rare `BUILTIN\Users:(R)` ACL — HiveNightmare surfaceicacls C:\Windows\System32\config\*Detection — Defender View
Section titled “Detection — Defender View”Sysmon Event IDs (Microsoft’s free host logger; events flow to Microsoft-Windows-Sysmon/Operational):
| EID | Meaning |
|---|---|
| 1 | ProcessCreate (command line, parent, hashes) |
| 3 | NetworkConnect (process → ip:port) |
| 7 | ImageLoaded (DLL load — catch in-memory reflection via signature) |
| 8 | CreateRemoteThread |
| 10 | ProcessAccess (OpenProcess with PROCESS_VM_READ) — catches mimikatz-style LSASS access |
| 11 | FileCreate |
| 12/13/14 | Registry create/set/delete value |
| 15 | FileCreateStreamHash (alternate data streams) |
| 17/18 | PipeEvent (named pipe created/connected) |
| 19/20/21 | WmiFilter / WmiConsumer / WmiBinding |
| 22 | DNSEvent |
MITRE ATT&CK T1003.001 — OS Credential Dumping: LSASS Memory (mimikatz sekurlsa::logonpasswords).
MITRE ATT&CK T1547.009 — Boot or Logon Autostart: HKLM\SYSTEM\CurrentControlSet\Services ImagePath.
MITRE ATT&CK T1546.003 — Event Triggered Execution: WMI Event Subscription.
MITRE ATT&CK T1218.011 — System Binary Proxy Execution: rundll32.exe.
Windows Security Event IDs that matter for privilege escalation:
- 4624 — logon (look at
LogonType: 2 Interactive, 3 Network, 9 NewCredentials, 10 RemoteInteractive). - 4672 — special privileges assigned to new logon (admin logon).
- 4688 — process creation (if
ProcessCreationAuditingenabled). - 4720/4732 — account created / added to group.
- 4742 — computer account changed (Zerologon).
- 4769 — Kerberos TGS request (Kerberoasting).
Wazuh rule 920 / 60004 — Sysmon Event ID 1: suspicious parent [verify].
Evasion Techniques
Section titled “Evasion Techniques”AMSI bypass. Windows 10+ routes all PowerShell script content through AMSI (amsi.dll!AmsiScanBuffer) before execution. A common bypass patches the in-memory AmsiScanBuffer to return AMSI_RESULT_CLEAN (0x80070057):
# Memory-patch the .NET AmsiScanBuffer prologue to return E_INVALIDARG.$a=[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils');$b=$a.GetField('amsiInitFailed','NonPublic,Static');$b.SetValue($null,$true)Detection: Sysmon Event ID 7 with ImageLoaded=amsi.dll plus Event ID 8 (CreateRemoteThread into amsi.dll), PowerShell 4104 script block containing AmsiUtils or amsiInitFailed (signatures: Set-Content, [Ref].Assembly).
Constrained Language Mode bypass. System lock-down policy sets ExecutionContext.SessionState.LanguageMode = ConstrainedLanguage. Variables work, but type accelerators like [Activator]::CreateInstance fail. Bypass requires writing to a whitelisted path or injecting into a FullLanguage process (often wsmprovhost.exe over WinRM). Defense: enforce via HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\__PSLockdownPolicy=4 plus AppLocker or WDAC.
ETW patching. Patching EtwNotificationRegister or ntdll!EtwEventWrite to ret before logging causes ETW consumers (Defender for Endpoint, Sysmon) to drop events. Detection: Sysmon Event ID 7 (ntdll.dll loaded) plus 8 (CreateRemoteThread) into ntdll.dll. Or use MonitorBase provider to log writes to protected memory regions.
Credential theft via SeImpersonatePrivilege. Modern potato exploits use PrintSpoofer-style named-pipe impersonation rather than the older DCOM/RPCSS SeImpersonate abuse. Defense: Sysmon Event ID 17/18 named pipe events filtered for \\pipe\spoolss, \\pipe\lsass, plus Event ID 1 for spoolsv.exe spawning cmd.exe.
| Evasion | What it breaks | How to detect |
|---|---|---|
| AMSI memory patch | Antimalware scan of script content | EID 8 thread into amsi.dll; EID 4104 with amsiInitFailed |
ETW EtwEventWrite patch | Event Tracing for Windows | EID 7 load of ntdll.dll is normal — alert on EID 8 into ntdll from non-svchost |
| CLM (Constrained Language Mode) | Script-block capability | Event ID 400 Engine state=Available then a 4104 from a CLM-blocked path |
amsiInitFailed=true reflection trick | Reflection-based bypass | Event ID 4104 with the literal amsiInitFailed string |
⚠️ What caught me: A Kerberoasting engagement where the customer “had it covered” with a 4769 alert and RC4 downgrade detection. They did. They missed one thing: the attacker re-issued the TGS request using AES-256 (no downgrade) by setting
[KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96]in the AS-REQ options. The 4769 fired withTicket Encryption: 0x12(AES-256-CTS-HMAC-SHA1-96) and looked normal. The crackable field wasTicket Encryption— RC4 tickets have0x17. The lesson: alert on0x17is correct, but the absence of0x17does not mean no Kerberoasting. AES tickets can be cracked too, just slowly.
Lab Practice
Section titled “Lab Practice”VM: Windows Server 2019 Evaluation (17623) joined to a Windows 10 Enterprise 21H2 client in a workgroup called LAB.LOCAL. Enable Sysmon with SwiftOnConfiguration policy. Enable PowerShell Script Block Logging (HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging\EnableScriptBlockLogging=1).
Objective:
- Read
HKLM\SYSTEM\CurrentControlSet\Services\WinDefend\Startand explain the value. - Create a
__EventFilter+CommandLineEventConsumer+__FilterToConsumerBindingthat runscmd.exeon minute intervals; verify you see Sysmon Event IDs 19/20/21 in the Sysmon Operational log. - Run
PrintSpoofer.exe -i -c "cmd.exe"from aLocalServicecontext (usesc.exeto start a service withobj=NT AUTHORITY\LocalServiceandtype=own). Verify LSASS gets a new logon session (Security Event 4624 LogonType=3) and Sysmon Event ID 1 for the newcmd.exe. - Enable the WMI-Activity ETW provider and
wmicto inspect__InstanceModificationEventhistory.
Expected flag format: flag{serviceStart_4_wmiSysmon_21_printSpoofer_4624type3}.
Detection that should fire: Sysmon EID 19, 20, 21 (WMI binding); EID 1 (cmd.exe as SYSTEM child of services.exe); Security 4624 LogonType=3 with Special Privileges.
Interview Questions
Section titled “Interview Questions”Conceptual: name the three components of a Windows access token and explain which one changes when a process impersonates a client.
Technical: walk through what happens when CreateProcess is called — name every kernel object created (Section, Token, Process, Thread, Job), and which one is duplicated from the parent.
Scenario: a customer reports that a service that was supposed to be Disabled (Start=4) is still spawning cmd.exe every 30 seconds. What are three places you would check, and which one is most likely to be a WMI binding?
What is the difference between HKLM\SYSTEM\CurrentControlSet and HKLM\SYSTEM\Select\Current? Why does an attacker who can write HKLM\SYSTEM\Setup effectively get persistence across CurrentControlSet renumberings?
Technical: explain why SeImpersonatePrivilege is dangerous but SeChangeNotifyPrivilege is not, in terms of the syscall/service operations each one gates. Name one potato exploit that does not use named-pipe impersonation.
Related Modules
Section titled “Related Modules”→ F1 (Networking Fundamentals) · F2 (Linux Internals) · F7 (PowerShell Fundamentals)