Skip to content

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.

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).

  1. Process and token model. A process is created via CreateProcess → NtCreateUserProcess. The new process inherits a primary token from the parent (unless CreateProcessAsUser is used). Integrity Level (Low/Medium/High/System) is encoded as a mandatory-label ACE in the token. whoami /all prints it: Mandatory Label\High Mandatory Level.
  2. Privileges — 35 distinct bit flags in the token. The ones that matter for post-ex:
    • SeDebugPrivilege — open any process (including lsass.exe); granted to Administrators by default.
    • SeImpersonatePrivilege — let a thread act as another user via ImpersonateNamedPipeClient / 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.
  3. Service registration — services are persisted under HKLM\SYSTEM\CurrentControlSet\Services\<name>:
    • ImagePath (REG_EXPAND_SZ) — full command line. This is where attackers put powershell -enc ... or a payload EXE.
    • Type — 0x10 = SERVICE_WIN32_OWN_PROCESS, 0x20 = SERVICE_WIN32_SHARE_PROCESS, 0x1 = kernel driver.
    • Start — 0 Boot, 1 System, 2 Auto, 3 Manual (demand), 4 Disabled.
    • ObjectName — account the service logs in as (LocalSystem default).
    • FailureActions — what to do on crash; this is the persistence trick (reboot-on-fail → re-execute payload).
  4. WMI persistence — three objects in root\subscription:
    __EventFilter → Query: SELECT * FROM __InstanceModificationEvent
    WITHIN 60 WHERE TargetInstance ISA 'Win32_LocalTime'
    AND TargetInstance.Hour = 8
    CommandLineEventConsumer → CommandLineTemplate = "powershell -nop -w hidden -c ..."
    __FilterToConsumerBinding → links the two by Reference
    The consumer is stored in C:\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).
  5. 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.
TechniqueDescriptionDetection Difficulty
PrintNightmare (CVE-2021-1675/34527)RpcAddPrinterEx → spoolss loads attacker DLL as SYSTEM via AddPrinterDriverMedium — Event ID 808 in Microsoft-Windows-PrintService
HiveNightmare (CVE-2021-36934)Auto-creates SAM shadow copies readable by BUILTIN\Users; NTLM hashes dumpedEasy — 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 adminMedium — event 4742 (computer account change) spikes
WMI subscription persistenceFilter+Consumer+Binding registered to fire payload on scheduleMedium — Sysmon 19/20/21 + WMI-Activity 5861
Service ImagePath tamperingReplace ImagePath of an unused service with payloadEasy — Sysmon 13 (registry value set on Services key)
Token impersonation via named pipeImpersonateNamedPipeClient after connecting SYSTEM pipe to your clientMedium — Sysmon 17/18 named pipe created/connected
KerberoastingRequest TGS for SPN-enabled account; offline-crack RC4-HMAC ticketHard — Event 4769 is normal noise
Terminal window
# List services and their ImagePath; look for non-Microsoft signed binaries
Get-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 box
Get-WmiObject -Namespace root\subscription -Class __EventFilter
Get-WmiObject -Namespace root\subscription -Class CommandLineEventConsumer
Get-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 registry
reg 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 detail
whoami /all
whoami /priv
# SeImpersonatePrivilege enabled is the starting point for PrintSpoofer / GodPotato
# Find files that have the rare `BUILTIN\Users:(R)` ACL — HiveNightmare surface
icacls C:\Windows\System32\config\*

Sysmon Event IDs (Microsoft’s free host logger; events flow to Microsoft-Windows-Sysmon/Operational):

EIDMeaning
1ProcessCreate (command line, parent, hashes)
3NetworkConnect (process → ip:port)
7ImageLoaded (DLL load — catch in-memory reflection via signature)
8CreateRemoteThread
10ProcessAccess (OpenProcess with PROCESS_VM_READ) — catches mimikatz-style LSASS access
11FileCreate
12/13/14Registry create/set/delete value
15FileCreateStreamHash (alternate data streams)
17/18PipeEvent (named pipe created/connected)
19/20/21WmiFilter / WmiConsumer / WmiBinding
22DNSEvent

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 ProcessCreationAuditing enabled).
  • 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].

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):

Terminal window
# 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.

EvasionWhat it breaksHow to detect
AMSI memory patchAntimalware scan of script contentEID 8 thread into amsi.dll; EID 4104 with amsiInitFailed
ETW EtwEventWrite patchEvent Tracing for WindowsEID 7 load of ntdll.dll is normal — alert on EID 8 into ntdll from non-svchost
CLM (Constrained Language Mode)Script-block capabilityEvent ID 400 Engine state=Available then a 4104 from a CLM-blocked path
amsiInitFailed=true reflection trickReflection-based bypassEvent 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 with Ticket Encryption: 0x12 (AES-256-CTS-HMAC-SHA1-96) and looked normal. The crackable field was Ticket Encryption — RC4 tickets have 0x17. The lesson: alert on 0x17 is correct, but the absence of 0x17 does not mean no Kerberoasting. AES tickets can be cracked too, just slowly.

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:

  1. Read HKLM\SYSTEM\CurrentControlSet\Services\WinDefend\Start and explain the value.
  2. Create a __EventFilter + CommandLineEventConsumer + __FilterToConsumerBinding that runs cmd.exe on minute intervals; verify you see Sysmon Event IDs 19/20/21 in the Sysmon Operational log.
  3. Run PrintSpoofer.exe -i -c "cmd.exe" from a LocalService context (use sc.exe to start a service with obj=NT AUTHORITY\LocalService and type=own). Verify LSASS gets a new logon session (Security Event 4624 LogonType=3) and Sysmon Event ID 1 for the new cmd.exe.
  4. Enable the WMI-Activity ETW provider and wmic to inspect __InstanceModificationEvent history.

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.

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.

→ F1 (Networking Fundamentals) · F2 (Linux Internals) · F7 (PowerShell Fundamentals)