Lateral Movement & Domain Compromise¶
When to use this
Evidence that an attacker is no longer on one box — logons appearing across hosts with one account, admin shares accessed, services installed remotely, or signs the domain itself is compromised (DCSync, golden ticket, krbtgt concerns, mass GPO changes). This is the highest-stakes on-prem scenario: if the domain is owned, every credential and every host is suspect.
1. Triage (first 15 minutes)¶
- Establish which accounts and which hosts are involved so far. Is a privileged account (Domain Admin, or a service account with wide rights) implicated?
- Look for the choke-point technique: LSASS dumping (creds stolen), then Pass-the-Hash / Kerberoasting (creds used), then PsExec/WMI/WinRM (movement).
- Check for domain-level compromise signs: DCSync (replication from a non-DC),
krbtgtactivity, new Domain Admins, GPO changes pushing payloads. - Do not start resetting everything blindly yet — scope first so containment is complete and simultaneous, or the attacker re-enters.
2. Collect¶
| Source | What | Where |
|---|---|---|
| DC Security logs | Kerberos/NTLM auth for the whole domain | 4768/4769/4771/4776, 4662 (DCSync), 4720/4728/4732 (account/group changes) |
| Each involved host | Logon + execution + service artifacts | KAPE / Velociraptor fleet hunt |
| AD | Group membership, ACL changes, new objects | AD audit, BloodHound collection for attack paths |
| Network | Internal auth & movement | Zeek ntlm.log, kerberos.log, smb_files.log, internal 445/135/3389/5985 |
Velociraptor is ideal here — hunt one artifact (e.g. Windows.EventLogs.RDPAuth, LSASS-access, a specific service name) across all hosts at once.
3. Analyse — map the movement graph¶
- Credential theft points: where was LSASS dumped? Every host with Sysmon 10 LSASS access is a place creds were harvested.
- Which credential, where used: pivot each compromised account through 4624 type 3 NTLM and 4648 to see every host it reached. Build the source→target graph (Arkime Connections view does this visually).
- Movement technique per hop: PsExec
7045+5145, WMI/WinRM parents, RDP4624/10+4778. - Domain compromise:
- DCSync:
4662on a DC with replication GUIDs (DS-Replication-Get-Changes) from a non-DC account, or Zeek/ArkimedrsuapiRPC — someone pulling password hashes from AD. - Golden/silver ticket: TGTs/TGS with anomalies (lifetime, missing
4768for a ticket that's in use, encryption downgrades). Ifkrbtgtmay be stolen, a golden ticket grants domain-wide access invisibly. - New privileged accounts / group changes:
4720→4732into Domain Admins;4728into privileged global groups. - AdminSDHolder / ACL backdoors, GPO abuse: persistence at the domain level.
- DCSync:
4. Contain / Eradicate¶
Containment must be coordinated and near-simultaneous, or the attacker moves as you clean:
- Isolate all known compromised hosts at once.
- Reset credentials: every account the attacker touched, all privileged accounts, and — if the DC or a domain admin was compromised — reset
krbtgttwice (two resets, waited out, invalidate golden tickets), then plan a broader tiered reset. - Remove attacker-created accounts, group memberships, ACL changes, GPOs, and persistence on every host.
- Revoke Kerberos tickets where possible; block C2/exfil.
- Rebuild DCs from clean media if DC-level compromise is confirmed — you cannot trust a compromised DC.
5. Recover & lessons¶
- Restore into a tiered, credential-reset environment. Validate AD integrity (no lingering backdoor ACLs/GPOs/accounts) with BloodHound and AD audits.
- Harden: tier 0/1/2 admin model (workstation creds can't reach servers/DCs), LAPS, Protected Users group, LSASS protection + Credential Guard, disable NTLM where possible, AES Kerberos, monitor
4662DCSync and4768/4769anomalies, and privileged-access workstations for admins.
Useful queries¶
index=botsv3 sourcetype=WinEventLog EventCode=4624 Logon_Type=3 Authentication_Package=NTLM
| eval user=mvindex(Account_Name,1)
| where NOT match(user,"\\$$")
| stats dc(host) as targets, values(host) as where_to, values(Source_Network_Address) as from by user
| where targets >= 3
| sort - targets
4624 type 3 = network logon, NTLM package. One non-computer account authenticating to three or more distinct hosts over NTLM is the lateral-movement fan-out — values(host) lists where it went and values(Source_Network_Address) where from. See Pass-the-Hash.
index=botsv3 sourcetype=WinEventLog EventCode=4662 Access_Mask=0x100
| where match(Properties,"(?i)DS-Replication-Get-Changes|1131f6a|9923a32a")
| table _time, host, Account_Name, Object_Name, Properties
4662 on a DC with the replication extended-right GUIDs (DS-Replication-Get-Changes-All) from an account that isn't a DC is DCSync — the attacker is pulling password hashes straight from Active Directory. Any non-DC, non-service account here is critical.
index=botsv3 sourcetype=WinEventLog EventCode IN (4720,4728,4732,4756)
| eval action=case(EventCode==4720,"user created",EventCode==4728,"added to global group",EventCode==4732,"added to local group",EventCode==4756,"added to universal group")
| search Group_Name IN ("Domain Admins","Enterprise Admins","Administrators","Schema Admins") OR EventCode=4720
| table _time, host, Subject_Account_Name, action, Account_Name, Member_Name, Group_Name
| sort 0 _time
New accounts and additions to privileged groups. An addition to Domain/Enterprise Admins outside a change window, especially minutes after a 4720 account creation, is domain persistence.