Map lateral movement paths, trace credential harvesting through the kill chain, correlate identity events with Advanced Hunting KQL queries, assess the blast radius of compromised accounts, and remediate attack paths to harden your Active Directory environment.
Microsoft Defender for Identity (MDI) builds behavioral profiles and lateral movement graphs that reveal how an attacker could pivot from a compromised account to high-value targets such as Domain Admins. This advanced lab walks you through a complete identity-based attack path investigation. from initial reconnaissance through credential harvesting, lateral movement, and domain dominance. You will use the MDI portal, Defender XDR Advanced Hunting (KQL), entity timelines, and MITRE ATT&CK mappings to reconstruct the full kill chain and determine the blast radius. The lab concludes with containment, remediation of insecure attack paths, and documentation of findings in a structured incident report.
Woodgrove Bank, a mid-size financial services firm, has detected anomalous identity activity across its Active Directory environment during routine monitoring. The SOC has received MDI alerts indicating network reconnaissance, suspicious Kerberos activity, and credential access. all originating from a single workstation in the trading floor. A threat intelligence advisory indicates that APT groups are actively targeting financial institutions using identity-based attack chains that exploit over-privileged service accounts and stale admin credentials.
Regulatory requirements (PCI-DSS, SOX) mandate full investigation and incident documentation within 72 hours, with evidence of root-cause analysis and remediation steps. Your mission: trace the full attack path, determine scope and impact, contain the threat, remediate the weaknesses, and produce a comprehensive incident report.
Over 80% of breaches involve compromised credentials; understanding attack paths is essential for proactive defense. Financial services firms face average breach costs exceeding $5.9 million. rapid investigation and containment directly reduce exposure. Regulatory frameworks (PCI-DSS, SOX, GDPR) require documented incident response with evidence of root-cause analysis. Remediating lateral movement paths before exploitation reduces your attack surface by eliminating avenues an adversary would use to reach crown-jewel assets.
MDI continuously analyzes authentication traffic, group memberships, and session data to compute lateral movement paths (LMPs). the shortest routes an attacker could take from any account to a sensitive target.
# Enumerate local admin group members across workstations to understand LMP inputs
$computers = Get-ADComputer -Filter {OperatingSystem -like "*Windows 10*"} -Properties OperatingSystem |
Select-Object -ExpandProperty Name
foreach ($computer in $computers) {
try {
$admins = Invoke-Command -ComputerName $computer -ScriptBlock {
Get-LocalGroupMember -Group "Administrators" | Select-Object Name, ObjectClass
} -ErrorAction Stop
Write-Host "`n[$computer] Local Administrators:" -ForegroundColor Cyan
$admins | Format-Table -AutoSize
} catch {
Write-Host "[$computer] Unreachable" -ForegroundColor Yellow
}
}Before investigating attack paths, identify which accounts are classified as sensitive in MDI and which additional accounts should be tagged.
# Find all accounts with AdminCount=1 (elevated privilege history)
$adminAccounts = Get-ADUser -Filter {AdminCount -eq 1} -Properties AdminCount, MemberOf,
LastLogonDate, PasswordLastSet, Enabled |
Select-Object Name, SamAccountName, Enabled, LastLogonDate, PasswordLastSet,
@{N='Groups';E={($_.MemberOf | ForEach-Object { ($_ -split ',')[0] -replace 'CN=' }) -join '; '}}
$adminAccounts | Sort-Object Name | Format-Table -AutoSize -Wrap
Write-Host "`nTotal accounts with AdminCount=1: $($adminAccounts.Count)" -ForegroundColor Cyan
# Identify stale admin accounts (no logon in 90+ days)
$stale = $adminAccounts | Where-Object {
$_.LastLogonDate -lt (Get-Date).AddDays(-90) -and $_.Enabled -eq $true
}
Write-Host "Stale admin accounts (90+ days inactive): $($stale.Count)" -ForegroundColor Yellow
$stale | Format-Table Name, SamAccountName, LastLogonDate -AutoSizeUse the MDI lateral movement graph to visualize which accounts can reach sensitive targets and through which machines.
# Query sessions on intermediary machines to validate LMP data
$intermediaryHosts = @("WS-TRADE-01", "WS-TRADE-02", "SRV-APP-03")
foreach ($host_ in $intermediaryHosts) {
Write-Host "`n=== Sessions on $host_ ===" -ForegroundColor Cyan
try {
$sessions = Invoke-Command -ComputerName $host_ -ScriptBlock {
query user 2>$null | ForEach-Object { $_.Trim() }
} -ErrorAction Stop
$sessions | ForEach-Object { Write-Host $_ }
} catch {
Write-Host "Cannot query sessions on $host_" -ForegroundColor Yellow
}
}
# Check cached credentials on a target machine (requires local admin)
Invoke-Command -ComputerName "WS-TRADE-01" -ScriptBlock {
# List credential profiles cached on this machine
cmdkey /list 2>$null
}Simulate the first phase of an identity-based attack: reconnaissance. The attacker enumerates accounts, groups, and trusts to identify targets before moving laterally.
testuser01)# Reference: scripts/mdi/Invoke-MDIReconSimulation.ps1
# Run from the test workstation as a standard domain user
# --- Phase 1: Account and Group Enumeration ---
Write-Host "[RECON] Enumerating privileged groups..." -ForegroundColor Cyan
$groups = @("Domain Admins", "Enterprise Admins", "Schema Admins",
"Account Operators", "Backup Operators")
foreach ($group in $groups) {
$members = Get-ADGroupMember -Identity $group -ErrorAction SilentlyContinue
Write-Host " $group : $($members.Count) members" -ForegroundColor Gray
}
# --- Phase 2: SPN Enumeration (Kerberoasting recon) ---
Write-Host "`n[RECON] Enumerating Service Principal Names..." -ForegroundColor Cyan
$spnAccounts = Get-ADUser -Filter {ServicePrincipalName -ne "$null"} `
-Properties ServicePrincipalName, MemberOf |
Select-Object SamAccountName, @{N='SPN';E={$_.ServicePrincipalName -join '; '}}
$spnAccounts | Format-Table -AutoSize
# --- Phase 3: Trust Enumeration ---
Write-Host "`n[RECON] Enumerating domain trusts..." -ForegroundColor Cyan
Get-ADTrust -Filter * | Select-Object Name, Direction, TrustType | Format-Table -AutoSize
# --- Phase 4: Account policy recon ---
Write-Host "[RECON] Reading default domain password policy..." -ForegroundColor Cyan
Get-ADDefaultDomainPasswordPolicy | Format-List ComplexityEnabled, LockoutThreshold,
MaxPasswordAge, MinPasswordAge, MinPasswordLengthnet group, nltest, or PowerShell AD cmdlets.Open the reconnaissance alert and perform a structured investigation to determine scope and intent.
// KQL: Query identity reconnaissance events for the source user
IdentityDirectoryEvents
| where Timestamp > ago(24h)
| where ActionType in ("Account Enumeration", "Group Enumeration",
"LDAP query", "SAM-R query")
| where AccountName == "testuser01"
| project Timestamp, ActionType, AccountName, DeviceName,
TargetAccountDisplayName, AdditionalFields
| sort by Timestamp descSimulate the next phase: the attacker harvests credentials from the compromised workstation. In a real scenario, tools like Mimikatz would extract cached credentials from LSASS memory.
# Simulate interactive logons that cache credentials on WS-TRADE-01
# Run these from a Domain Admin PowerShell session on the test DC
# Create test sessions (simulates an admin logging in to a workstation)
$cred = Get-Credential -Message "Enter svc-backup (service account) credentials"
Invoke-Command -ComputerName "WS-TRADE-01" -Credential $cred -ScriptBlock {
Write-Host "Session established as $env:USERNAME on $env:COMPUTERNAME"
# This caches the credential in LSASS memory
}
# Simulate NTLM authentication that MDI will detect
$adminCred = Get-Credential -Message "Enter test-admin credentials"
New-PSDrive -Name "SimShare" -PSProvider FileSystem -Root "\\WS-TRADE-01\C$" `
-Credential $adminCred -ErrorAction SilentlyContinue
Remove-PSDrive -Name "SimShare" -ErrorAction SilentlyContinue
Write-Host "[SIM] Credential caching simulation complete" -ForegroundColor Green
Write-Host "[SIM] Check MDI for 'Suspected identity theft (pass-the-hash)' alerts" -ForegroundColor YellowReconstruct the attacker’s lateral movement by correlating alerts, entity activity, and authentication logs across the kill chain.
// KQL: Reconstruct a lateral movement attack chain chronologically across three kill chain phases
// WHAT: Combines reconnaissance, credential access, and lateral movement events into a unified timeline
// WHY: Incident investigation requires mapping the exact sequence: How did the attacker get in,
// what credentials did they steal, and where did they move? This query joins three event
// categories to show the complete kill chain from initial recon through domain compromise.
// TABLES: IdentityDirectoryEvents (recon), IdentityLogonEvents (credential access + lateral movement)
// FIELDS:
// - ActionType: e.g., "Enumeration", "LDAP", "SAM-R" for recon; logon events for credential/lateral
// - LogonType: "Interactive" = console logon, "RemoteInteractive" = RDP, "Network" = SMB/WMI
// - Phase column labels each event for structured analysis
// OUTPUT: Chronological timeline with Phase, Timestamp, Action, Device, and Account columns
// Phase 1 (Recon) should appear first, followed by Phase 2 (CredAccess), then Phase 3 (Lateral)
let attackerAccount = "testuser01";
let timeWindow = 24h;
// Step 1: Initial reconnaissance - LDAP queries, group enumeration, SAM-R calls
let recon = IdentityDirectoryEvents
| where Timestamp > ago(timeWindow)
| where AccountName == attackerAccount
| where ActionType has_any ("Enumeration", "LDAP", "SAM-R")
| project Phase="1-Recon", Timestamp, ActionType, DeviceName, AccountName;
// Step 2: Credential access - logons on the compromised host where credentials are cached in LSASS
let credAccess = IdentityLogonEvents
| where Timestamp > ago(timeWindow)
| where DeviceName == "WS-TRADE-01" // The initially compromised workstation
| where LogonType in ("Interactive", "RemoteInteractive", "Network")
| project Phase="2-CredAccess", Timestamp, ActionType, DeviceName,
AccountName, LogonType;
// Step 3: Lateral movement - harvested credentials used to access other machines
let lateral = IdentityLogonEvents
| where Timestamp > ago(timeWindow)
| where AccountName in ("svc-backup", "test-admin") // Accounts whose creds were stolen
| where DeviceName != "WS-TRADE-01" // Exclude the source machine
| project Phase="3-Lateral", Timestamp, ActionType, DeviceName,
AccountName, LogonType;
// Combine all phases into a single chronological view
union recon, credAccess, lateral
| sort by Timestamp ascDeep-dive into the entity timeline for each compromised account and machine to identify all attacker actions.
testuser01svc-backup, test-admin// KQL: Build a comprehensive entity activity timeline across all three MDI identity tables
// WHAT: Combines logon events, directory changes, and LDAP/DNS queries for a single user identity
// WHY: During investigation, you need a 360-degree view of everything a suspected compromised
// account did. Each table captures different activity types:
// - IdentityLogonEvents: Authentication events (who logged in where, using which protocol)
// - IdentityDirectoryEvents: AD changes (password resets, group modifications, object creation)
// - IdentityQueryEvents: LDAP/DNS queries (what the account searched for in the directory)
// OUTPUT: Unified chronological timeline with Category, Action, Device, and contextual Details
// Look for: Recon queries followed by logons to unusual machines = lateral movement pattern
let targetUser = "testuser01";
let lookback = 48h;
// Logon events - shows where and how the user authenticated
let logons = IdentityLogonEvents
| where Timestamp > ago(lookback)
| where AccountName == targetUser
| project Timestamp, Category="Logon", Action=ActionType, Device=DeviceName,
Details=strcat("LogonType: ", LogonType, " | Protocol: ", Protocol);
// Directory events - shows what AD objects the user modified
let dirEvents = IdentityDirectoryEvents
| where Timestamp > ago(lookback)
| where AccountName == targetUser
| project Timestamp, Category="Directory", Action=ActionType, Device=DeviceName,
Details=tostring(AdditionalFields);
// Query events - shows what LDAP/DNS lookups the user performed (recon indicator)
let queryEvents = IdentityQueryEvents
| where Timestamp > ago(lookback)
| where AccountName == targetUser
| project Timestamp, Category="Query", Action=ActionType, Device=DeviceName,
Details=strcat("QueryType: ", QueryType, " | Target: ", QueryTarget);
union logons, dirEvents, queryEvents
| sort by Timestamp ascWrite Advanced Hunting queries to correlate identity events across multiple tables and surface hidden attacker activity.
// KQL: Correlate recon with credential access. find users who
// performed enumeration followed by logon to sensitive machines
let reconUsers = IdentityDirectoryEvents
| where Timestamp > ago(24h)
| where ActionType has_any ("Enumeration", "SAM-R")
| distinct AccountName;
IdentityLogonEvents
| where Timestamp > ago(24h)
| where AccountName in (reconUsers)
| where DeviceName has_any ("DC", "SRV", "SQL")
| summarize LogonCount=count(), Devices=make_set(DeviceName),
Protocols=make_set(Protocol) by AccountName
| where LogonCount > 3
| sort by LogonCount desc// KQL: Detect anomalous logon patterns. accounts authenticating
// to machines they have never accessed before (first-time access)
let baseline = IdentityLogonEvents
| where Timestamp between (ago(30d) .. ago(1d))
| where Application == "Active Directory"
| summarize KnownDevices=make_set(DeviceName) by AccountName;
IdentityLogonEvents
| where Timestamp > ago(24h)
| where Application == "Active Directory"
| join kind=inner baseline on AccountName
| where DeviceName !in (KnownDevices)
| project Timestamp, AccountName, DeviceName, LogonType, Protocol,
DestinationIPAddress
| sort by Timestamp descIdentityLogonEvents, IdentityDirectoryEvents, and IdentityQueryEvents tables are the three pillars of identity hunting in Defender XDR. Cross-joining them reveals patterns invisible in any single table.Kerberos ticket manipulation is a hallmark of advanced identity attacks. MDI detects overpass-the-hash, Golden Ticket, and forged PAC anomalies. Use KQL to hunt for suspicious ticket activity.
// KQL: Detect potential overpass-the-hash attacks by correlating NTLM and Kerberos events
// WHAT: Finds accounts that authenticate via NTLM then immediately switch to Kerberos within 5min
// WHY: Overpass-the-hash (MITRE ATT&CK T1550.002) is a technique where an attacker uses a stolen
// NTLM hash to request a Kerberos TGT, which then provides full Kerberos authentication.
// The telltale signature is: NTLM auth from IP X, followed by Kerberos auth from the same IP
// within seconds to minutes. Legitimate users don't exhibit this pattern because their
// workstations use Kerberos natively (NTLM is only a fallback).
// OUTPUT: Account, device, NTLM timestamp, Kerberos timestamp, and time delta in seconds
// TimeDelta < 60 seconds is highly suspicious; < 300 seconds warrants investigation
IdentityLogonEvents
| where Timestamp > ago(24h)
| where Protocol == "NTLM"
| where Application == "Active Directory"
| project NtlmTime=Timestamp, AccountName, SourceIP=IPAddress, DeviceName
| join kind=inner (
IdentityLogonEvents
| where Timestamp > ago(24h)
| where Protocol == "Kerberos"
| where Application == "Active Directory"
| project KerbTime=Timestamp, AccountName, SourceIP=IPAddress, DeviceName
) on AccountName, SourceIP
// The Kerberos request must follow the NTLM auth within a 5-minute window
| where KerbTime between (NtlmTime .. (NtlmTime + 5m))
| project AccountName, DeviceName, NtlmTime, KerbTime,
TimeDelta=datetime_diff('second', KerbTime, NtlmTime)
| sort by NtlmTime desc// KQL: Detect Kerberos tickets using weak RC4 encryption (Kerberoasting/Golden Ticket indicator)
// WHAT: Finds Kerberos authentication using RC4 encryption (type 0x17/0x18) instead of AES
// WHY: Modern AD environments should use AES (0x12) for Kerberos. RC4 (0x17 = RC4-HMAC) is
// used by attack tools like Rubeus and Mimikatz because RC4 tickets are faster to crack.
// Golden Ticket attacks also commonly use RC4 encryption. Any RC4 Kerberos traffic in
// an AES-enforced environment is a strong indicator of credential-based attacks.
// FIELD: AdditionalFields.TicketEncryptionType - 0x17 = RC4-HMAC, 0x12 = AES-256
// OUTPUT: Accounts using RC4 encryption with timestamps and failure codes
// FailureCode "0x0" = success (ticket was issued), non-zero = request failed
IdentityLogonEvents
| where Timestamp > ago(24h)
| where Protocol == "Kerberos"
| where Application == "Active Directory"
| extend TicketDetails = parse_json(AdditionalFields)
| where TicketDetails.TicketEncryptionType in ("0x17", "0x18") // RC4-HMAC encryption types
| project Timestamp, AccountName, DeviceName, DestinationDeviceName,
EncryptionType=tostring(TicketDetails.TicketEncryptionType),
FailureCode=tostring(TicketDetails.FailureCode)
| sort by Timestamp descMap each phase of the observed attack to the MITRE ATT&CK framework for structured analysis and reporting.
# Generate MITRE ATT&CK mapping for the attack path
$attackMapping = @(
[PSCustomObject]@{
Phase = "Reconnaissance"
Tactic = "TA0043. Reconnaissance"
Technique = "T1087.002. Account Discovery: Domain Account"
Evidence = "LDAP enumeration of Domain Admins, Enterprise Admins"
MDIAlert = "Account enumeration reconnaissance"
},
[PSCustomObject]@{
Phase = "Reconnaissance"
Tactic = "TA0007. Discovery"
Technique = "T1069.002. Permission Groups Discovery: Domain Groups"
Evidence = "Enumeration of privileged security groups"
MDIAlert = "Account enumeration reconnaissance"
},
[PSCustomObject]@{
Phase = "Credential Access"
Tactic = "TA0006. Credential Access"
Technique = "T1003.001. OS Credential Dumping: LSASS Memory"
Evidence = "Credential harvesting from WS-TRADE-01"
MDIAlert = "Suspected identity theft (pass-the-hash)"
},
[PSCustomObject]@{
Phase = "Lateral Movement"
Tactic = "TA0008. Lateral Movement"
Technique = "T1550.002. Use Alternate Auth Material: Pass the Hash"
Evidence = "NTLM authentication with harvested hashes"
MDIAlert = "Suspected identity theft (pass-the-hash)"
},
[PSCustomObject]@{
Phase = "Lateral Movement"
Tactic = "TA0008. Lateral Movement"
Technique = "T1021.002. Remote Services: SMB/Windows Admin Shares"
Evidence = "SMB access to admin shares on SRV-APP-03"
MDIAlert = "Lateral movement path detected"
},
[PSCustomObject]@{
Phase = "Privilege Escalation"
Tactic = "TA0004. Privilege Escalation"
Technique = "T1558.003. Steal or Forge Kerberos Tickets: Kerberoasting"
Evidence = "SPN enumeration followed by TGS requests with RC4"
MDIAlert = "Suspected Kerberoasting activity"
}
)
$attackMapping | Format-Table -AutoSize -Wrap
$attackMapping | Export-Csv -Path "MITRE_ATT&CK_Mapping.csv" -NoTypeInformation
Write-Host "`nMITRE mapping exported to MITRE_ATT&CK_Mapping.csv" -ForegroundColor GreenDetermine the full scope of the compromise by assessing what each compromised account could access and which systems may have been affected.
# Assess blast radius for compromised accounts
$compromisedAccounts = @("testuser01", "svc-backup", "test-admin")
foreach ($account in $compromisedAccounts) {
Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host "BLAST RADIUS: $account" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
$user = Get-ADUser -Identity $account -Properties MemberOf, LastLogonDate,
PasswordLastSet, AdminCount, ServicePrincipalName
# Group memberships
Write-Host "`n[Groups]" -ForegroundColor Yellow
$user.MemberOf | ForEach-Object {
$groupName = ($_ -split ',')[0] -replace 'CN='
$group = Get-ADGroup $groupName -Properties GroupScope
Write-Host " . $groupName ($($group.GroupScope))"
}
# Machines where credentials may be cached (recent logons)
Write-Host "`n[Recent Logon Machines]" -ForegroundColor Yellow
$logons = Get-WinEvent -ComputerName "DC01" -FilterHashtable @{
LogName='Security'; Id=4624; StartTime=(Get-Date).AddDays(-7)
} -ErrorAction SilentlyContinue |
Where-Object { $_.Properties[5].Value -eq $account } |
Select-Object @{N='Machine';E={$_.Properties[11].Value}} -Unique
$logons | ForEach-Object { Write-Host " . $($_.Machine)" }
# SPNs (if service account)
if ($user.ServicePrincipalName) {
Write-Host "`n[SPNs. Kerberoasting risk]" -ForegroundColor Red
$user.ServicePrincipalName | ForEach-Object { Write-Host " . $_" }
}
Write-Host "`n[Risk Assessment]" -ForegroundColor Yellow
$risk = if ($user.AdminCount -eq 1) { "CRITICAL. Has admin privileges" }
elseif ($user.ServicePrincipalName) { "HIGH. Service account with SPN" }
else { "MEDIUM. Standard user" }
Write-Host " Risk Level: $risk" -ForegroundColor $(if($risk -match "CRITICAL"){"Red"}elseif($risk -match "HIGH"){"Yellow"}else{"White"})
}Execute immediate containment actions to stop the attacker’s progress and prevent further lateral movement.
# Containment Actions. execute with Domain Admin privileges
$incidentId = "MDI-2026-0342"
$compromised = @("testuser01", "svc-backup")
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
foreach ($account in $compromised) {
Write-Host "`n[CONTAIN] Processing: $account" -ForegroundColor Red
# 1. Disable the account immediately
Disable-ADAccount -Identity $account
Write-Host " [OK] Account disabled" -ForegroundColor Green
# 2. Reset the password to a random complex value
$newPassword = [System.Web.Security.Membership]::GeneratePassword(32, 8)
Set-ADAccountPassword -Identity $account -Reset `
-NewPassword (ConvertTo-SecureString $newPassword -AsPlainText -Force)
Write-Host " [OK] Password reset" -ForegroundColor Green
# 3. Invalidate existing Kerberos tickets (force krbtgt if needed)
$user = Get-ADUser $account -Properties DistinguishedName
Set-ADUser $account -Replace @{
'msDS-AllowedToDelegateTo' = @()
} -ErrorAction SilentlyContinue
Write-Host " [OK] Delegation permissions cleared" -ForegroundColor Green
# 4. Log the containment action
$logEntry = [PSCustomObject]@{
Timestamp = $timestamp
IncidentId = $incidentId
Account = $account
Action = "Disabled, password reset, delegation cleared"
Responder = $env:USERNAME
}
$logEntry | Export-Csv "Containment_Log_$incidentId.csv" -Append -NoTypeInformation
Write-Host " [OK] Action logged" -ForegroundColor Green
}
# 5. Isolate compromised workstations via Defender for Endpoint
Write-Host "`n[CONTAIN] Initiate device isolation for WS-TRADE-01 via Defender XDR portal" -ForegroundColor Yellow
Write-Host " Navigate to: Defender XDR > Assets > Devices > WS-TRADE-01 > Isolate device" -ForegroundColor GrayRemove the structural weaknesses in your Active Directory that enabled the attack path. Focus on eliminating unnecessary privileges and reducing credential exposure.
# Remediation Actions: harden the attack surface
# 1. Remove unnecessary local admin rights
$workstations = @("WS-TRADE-01", "WS-TRADE-02")
foreach ($ws in $workstations) {
Write-Host "`n[REMEDIATE] Cleaning local admins on $ws" -ForegroundColor Cyan
Invoke-Command -ComputerName $ws -ScriptBlock {
$localAdmins = Get-LocalGroupMember -Group "Administrators"
foreach ($admin in $localAdmins) {
# Keep only Domain Admins and the built-in Administrator
if ($admin.Name -notmatch "Domain Admins|Administrator$") {
Remove-LocalGroupMember -Group "Administrators" -Member $admin.Name `
-ErrorAction SilentlyContinue
Write-Host " Removed: $($admin.Name)" -ForegroundColor Yellow
}
}
}
}
# 2. Convert SPN service accounts to gMSA (eliminates Kerberoasting risk)
Write-Host "`n[REMEDIATE] Creating gMSA to replace svc-backup..." -ForegroundColor Cyan
New-ADServiceAccount -Name "gmsa-backup$" `
-DNSHostName "gmsa-backup.woodgrove.local" `
-PrincipalsAllowedToRetrieveManagedPassword "SRV-APP-03$" `
-ServicePrincipalNames "MSSQLSvc/SRV-APP-03.woodgrove.local:1433" `
-Enabled $true
Write-Host " [OK] gMSA created. update application to use gmsa-backup$" -ForegroundColor Green
# 3. Enable LAPS on intermediary machines
Write-Host "`n[REMEDIATE] Enabling LAPS on workstations..." -ForegroundColor Cyan
$workstations | ForEach-Object {
Set-ADComputer $_ -Replace @{
'ms-Mcs-AdmPwdExpirationTime' = 0
} -ErrorAction SilentlyContinue
}
Write-Host " [OK] LAPS expiration reset. passwords will rotate on next GP refresh" -ForegroundColor Green
# 4. Restrict privileged account logon to Tier 0 assets only
Write-Host "`n[REMEDIATE] Configuring logon restrictions for Domain Admins..." -ForegroundColor Cyan
Write-Host " Apply GPO: Deny log on locally / Deny log on through Remote Desktop" -ForegroundColor Gray
Write-Host " Scope: All workstations and member servers (not DCs)" -ForegroundColor GrayCreate a comprehensive incident report that documents the full investigation, suitable for compliance review and executive briefing.
# Generate Incident Report
$report = @"
============================================================
INCIDENT REPORT. IDENTITY-BASED ATTACK PATH
============================================================
Incident ID : MDI-2026-0342
Classification : Identity Compromise. Lateral Movement
Severity : High
Status : Contained / Remediation In Progress
Date Detected : $(Get-Date -Format "yyyy-MM-dd")
Analyst : $env:USERNAME
------------------------------------------------------------
1. EXECUTIVE SUMMARY
------------------------------------------------------------
An identity-based attack path was detected originating from
workstation WS-TRADE-01 on the trading floor. The attacker
performed Active Directory reconnaissance, harvested cached
credentials, and attempted lateral movement to server assets.
The attack was contained within $([math]::Round((New-TimeSpan -Start (Get-Date).AddHours(-4) -End (Get-Date)).TotalMinutes)) minutes of detection.
------------------------------------------------------------
2. ATTACK TIMELINE
------------------------------------------------------------
Phase 1. Reconnaissance : Account/group enumeration via LDAP
Phase 2. Credential Access : Credential harvesting from LSASS
Phase 3. Lateral Movement : Pass-the-hash to SRV-APP-03
Phase 4. Containment : Accounts disabled, host isolated
------------------------------------------------------------
3. COMPROMISED ASSETS
------------------------------------------------------------
Accounts : testuser01, svc-backup
Machines : WS-TRADE-01, SRV-APP-03 (attempted)
Data : No evidence of data exfiltration
------------------------------------------------------------
4. MITRE ATT&CK MAPPING
------------------------------------------------------------
T1087.002. Account Discovery: Domain Account
T1069.002. Permission Groups Discovery
T1003.001. OS Credential Dumping: LSASS Memory
T1550.002. Pass the Hash
T1558.003. Kerberoasting (attempted)
------------------------------------------------------------
5. CONTAINMENT ACTIONS
------------------------------------------------------------
- Compromised accounts disabled and passwords reset
- WS-TRADE-01 isolated via Defender for Endpoint
- Kerberos tickets invalidated
- Delegation permissions revoked
------------------------------------------------------------
6. REMEDIATION ACTIONS
------------------------------------------------------------
- Removed unnecessary local admin rights on workstations
- Converted svc-backup to gMSA (eliminates Kerberoasting)
- Enabled LAPS for local admin password rotation
- Restricted Domain Admin logon to Tier 0 assets only
- Added sensitive accounts to Protected Users group
------------------------------------------------------------
7. RECOMMENDATIONS
------------------------------------------------------------
- Deploy Credential Guard on all workstations (30 days)
- Implement PAM solution for just-in-time admin access
- Schedule monthly attack path reviews
- Conduct tabletop exercise for identity breach response
============================================================
"@
$report | Out-File -FilePath "Incident_Report_MDI-2026-0342.txt" -Encoding UTF8
Write-Host $report
Write-Host "`nReport saved to Incident_Report_MDI-2026-0342.txt" -ForegroundColor Green| Resource | Description |
|---|---|
| Understand lateral movement paths | How MDI identifies and maps lateral movement attack vectors |
| Entity tags in MDI | Configure sensitive and honeytoken entity tags |
| IdentityLogonEvents table | Schema reference for identity logon hunting queries |
| IdentityDirectoryEvents table | Schema reference for directory change hunting queries |
| IdentityQueryEvents table | Schema reference for identity query hunting |
| Lateral movement alerts | Investigating lateral movement detections in MDI |
| Reconnaissance alerts | Understanding and investigating reconnaissance detections |
| MITRE ATT&CK: Lateral Movement | Lateral movement tactic reference and technique catalog |
| Identity security assessments | Posture recommendations and remediation guidance |
| Windows LAPS overview | Local Administrator Password Solution deployment guide |