Cross-Host Log Correlation
A single host's logs tell one part of the story. Correlating logs across multiple hosts — the domain controller, the compromised workstation, the file server, and the firewall — reveals the complete attack chain. This chapter covers building multi-host timelines, resolving time skew, and pivoting between log sources.
An attacker used a compromised workstation (WS01) to access a file server (FS01) and a domain controller (DC01) using stolen credentials. WS01's logs were partially cleared. But: DC01 has authentication logs (4624/4648 with logon type and source), FS01 has file access logs (4663), and the firewall has connection logs for external traffic. Correlating these three sources fills the gaps that WS01's cleared logs left. The DC logs show when the stolen credentials were used; FS01 logs show what was accessed; the firewall logs show where the data went.
Building a Multi-Host Correlated Timeline
Cross-Host Log Correlation Framework
═══════════════════════════════════════════════════════════════════
Step 1: Collect logs from all relevant hosts
├── SIEM (if available): pull all logs for the time window
├── Evtx files: \\host\c$\Windows\System32\winevt\Logs\
├── Firewall: syslog export from NGFW/proxy
├── DC: Security.evtx (authentication events)
└── File servers: Security.evtx (object access events if auditing enabled)
Step 2: Normalize to UTC
├── Confirm all host clocks are UTC or note timezone offsets
├── Document any NTP desync (check System.evtx for time-sync events)
└── Apply offsets: log_UTC = log_local + offset
Step 3: Build a unified timeline
├── Tag each event with source host
├── Sort all events chronologically
└── Look for event chains across hosts within expected latency windows
Event chain example:
02:13:05 UTC WS01 4688: powershell.exe spawned (cmd: IEX download)
02:13:07 UTC FW Outbound HTTPS to 185.220.101.47 (WS01 src IP)
02:13:12 UTC DC01 4624: jsmith logged in from WS01 (type 3 network)
02:13:15 UTC FS01 4663: jsmith accessed \\FS01\Finance\Q3-Revenue.xlsx
02:14:02 UTC FW 7.3 MB upload to 185.220.101.47 (WS01 src IP)
Reading: malware download → C2 checkin → lateral to FS01 → exfil in 57 seconds
Attackers expect you to look at the compromised host. That's where they focus their log-clearing effort. The DC, file server, and firewall are out of the attacker's direct control and are frequently untouched. A cleared Security.evtx on WS01 means nothing if DC01's 4624 log still records every session WS01 initiated, and FS01's 4663 log still records every file jsmith touched. Cross-host correlation makes log clearing largely futile — you reconstruct the attacker's actions from the hosts they couldn't reach.
Correlation Scripts
# Collect and correlate authentication events across multiple hosts
# Run from a host with network access to target systems
$HOSTS = @("DC01", "FS01", "EXCHANGE01")
$StartTime = [DateTime]::Parse("2026-09-17T02:00:00Z")
$EndTime = [DateTime]::Parse("2026-09-17T06:00:00Z")
$SuspectUser = "jsmith"
$allEvents = [System.Collections.Generic.List[PSObject]]::new()
foreach ($host in $HOSTS) {
Write-Host "Collecting from $host..."
$events = Invoke-Command -ComputerName $host -ScriptBlock {
param($start, $end, $user)
Get-WinEvent -FilterHashtable @{
LogName = "Security"
Id = @(4624, 4648, 4625, 4663, 4688)
StartTime = $start
EndTime = $end
} -ErrorAction SilentlyContinue |
Where-Object {
$_.Message -match $user -or $_.Id -in @(4688)
} |
Select-Object TimeCreated, Id, Message,
@{N="HostName"; E={$env:COMPUTERNAME}}
} -ArgumentList $StartTime, $EndTime, $SuspectUser
if ($events) { $events | ForEach-Object { $allEvents.Add($_) } }
}
# Sort by time and export
$allEvents |
Sort-Object TimeCreated |
Select-Object TimeCreated, HostName, Id,
@{N="Summary"; E={ $_.Message -split "`n" | Select-Object -First 3 | Join-String -Separator " | " }} |
Export-Csv "D:\analysis\correlated-timeline.csv" -NoTypeInformation
Write-Host "Total events correlated: $($allEvents.Count)"
When you filter event logs by username (e.g., "jsmith"), you catch every event tied to that account — including legitimate pre-attack activity that pollutes your timeline with noise. Prefer correlating by Logon ID (field 0x3e7, 0x3e5, or a specific hex value that appears in both the 4624 and the 4688/4663 events). The Logon ID ties a specific authenticated session to all process creations and file accesses within it, giving you a clean sub-timeline of just the attacker's session — not every historical action by that user account.
Key Pivot Techniques
| Starting artifact | Pivot to | What you learn |
|---|---|---|
| 4624 logon from WS01 to DC01 with jsmith | WS01 Security.evtx for 4648 (explicit credential use) at same time | Which process on WS01 initiated the DC authentication — confirms malware using stolen credentials |
| 4663 file access on FS01 | 4624 on FS01 immediately preceding the access | The logon session the file access happened under — confirms how attacker authenticated to FS01 |
| Firewall log: WS01 outbound upload to external IP | WS01 process creation logs (4688) in same time window | Which process made the outbound connection — the exfiltration tool |
| DC01 4768/4769 (Kerberoasting): service ticket requests for many SPNs in rapid succession | WS01 logs for the source of those requests (same IP/session) | Confirms Kerberoasting happened from WS01; correlate with any offline cracking indicators |
Pre-Incident Log Retention Requirements
Cross-host correlation is only possible if the logs still exist. Configure these before the incident:
| Log source | Minimum retention | What breaks if it rolls over |
|---|---|---|
| DC Security.evtx | 90 days, ≥1 GB log size | Authentication history gone — impossible to map credential use back to initial compromise date |
| File server Security.evtx (4663) | 30 days, ≥512 MB | Can't prove which files were accessed — data scope assessment fails |
| Windows Security on all endpoints | 30 days, ≥256 MB | Process creation (4688) history lost — attacker tool execution unrecoverable |
| Firewall/proxy logs | 90 days | C2 channel start date unknown — dwell time calculation fails; exfiltration volume lost |
| SIEM (forwarded) | 365 days minimum for regulated industries | Fallback when local logs roll; also the only source if local logs are cleared |
Q & A
Q: Host clocks across the environment are off by different amounts. How much does time skew matter?
It depends on the skew and the question you're asking. If you're building a 47-day investigation timeline, a 5-minute clock skew barely matters — events hours or days apart are clearly sequential. But if you're trying to determine whether a process was created before or after a network connection on the same host within a 10-second window, a 5-minute skew makes that analysis impossible. Check: (1) Each host's System event log for Event ID 1 (time adjustment) or check w32tm /query /status remotely. (2) Compare the timestamps of the same repeatable event across hosts (e.g., a scheduled task that runs at a known time on all hosts). (3) Document the skew in your case notes — courts and stakeholders want to know that you've accounted for it. For high-precision correlation (<1 minute windows), note the estimated skew in your report and flag any conclusions within the skew window as uncertain. SIEM platforms usually address this via NTP normalization, but host-collected evtx files retain the local clock timestamp.