HackBlue

Tools · Incident response playbooks · 06 / 20

Building an incident timeline from logs and artifacts

Normalize timestamps to UTC, merge events from endpoints, identity, network, and cloud logs into one timeline, and use it to find patient zero and the attacker’s path.

10 min read · practice only with authorization

Why a timeline

A timeline turns scattered findings into a story: first access, what the attacker did, which accounts and hosts were involved, and when containment happened. It reveals gaps where evidence is missing and helps answer the questions leadership and regulators will ask.

How to build it

Convert every timestamp to UTC and record the source’s original time zone. Use a consistent format: time, source, host, account, event, and evidence reference. Start with high-confidence anchors such as the first alert and known malicious file creation, then expand outward. Keep the master timeline in a shared spreadsheet or a tool such as Timesketch, which supports collaborative tagging.

  • UTC everywhere
  • One row per event, with evidence reference
  • Mark confidence: confirmed, likely, unknown
  • Note gaps explicitly

Lab: merge three sources

Export small CSVs from three lab sources: Windows Security events, a proxy or firewall log, and sign-in logs. Use pandas to normalize timestamps to UTC, add a source column, and sort into one timeline. Then mark the earliest suspicious event and write a three-sentence narrative of what happened.

Snippet
import pandas as pd
sec = pd.read_csv('security.csv'); sec['time'] = pd.to_datetime(sec['TimeCreated']).dt.tz_convert('UTC'); sec['source'] = 'windows'
prx = pd.read_csv('proxy.csv'); prx['time'] = pd.to_datetime(prx['timestamp'], utc=True); prx['source'] = 'proxy'
sig = pd.read_csv('signins.csv'); sig['time'] = pd.to_datetime(sig['createdDateTime'], utc=True); sig['source'] = 'entra'
cols = ['time', 'source', 'host', 'user', 'event']
timeline = pd.concat([d.reindex(columns=cols) for d in (sec, prx, sig)]).sort_values('time')
timeline.to_csv('timeline.csv', index=False)
print(timeline.head(30).to_string(index=False))

Pitfalls

Mixing local times and UTC, trusting file timestamps that can be altered, and assuming the first alert is the first event. Attackers often operate for days before an alert fires; look backward from the earliest known event for the initial access.

Diagram

Rows from a merged timeline

Every row cites its source.

UTCsourceevidence

08:41:07 UTC entra

j.doe sign-in from 203.0.113.45, MFA approved
New ASN, new browser

08:52:30 UTC proxy

FIN-LT-042 GET https://files.example.net/a.ps1
200, 14 KB

08:52:41 UTC windows

FIN-LT-042 4688 powershell.exe -File a.ps1
Parent explorer.exe

Check yourself

1. Which time zone should a master timeline use?

2. Why look at events before the first alert?

3. Which open-source tool supports collaborative timeline analysis?