Lessons-learned is the mechanism that turns individual incidents into organizational learning. Done well, it prevents the next incident from succeeding the same way. Done poorly (or skipped), the same attack succeeds again.
The Lessons-Learned Meeting
Timing: Within 5-7 business days of incident containment.
Attendees:
- SOC analysts who investigated
- IR team lead
- Detection engineers (if detection gaps found)
- Platform/identity owners for affected systems
- Security leadership (CISO or delegate)
NOT a blame meeting. Ground rules:
- Focus on process and systems, not individuals
- Anyone can raise any finding without fear
- Actions assigned to teams, not people by name
Structured agenda:
1. Incident timeline review (15 min)
Walk the timeline — ensure everyone has the same understanding of what happened
2. Detection gap analysis (15 min)
Which attacker actions had no alert? What would have caught them earlier?
3. Response gap analysis (15 min)
Where was response slower than SLA? Where were handoffs incomplete?
4. Prevention gap analysis (10 min)
What security control or configuration failure enabled this attack?
5. Action item assignment (15 min)
Each gap → specific action → owner → deadline → success metric
The Lessons-Learned Document
Section 1: Incident Summary (1 paragraph)
Same as the executive summary from the incident report, for context.
Section 2: What Went Well
Critical — documents what to preserve and repeat.
WHAT WENT WELL
1. jsmith@corp.com reported the suspicious email immediately instead of clicking,
enabling early detection. Security awareness training is working for this user.
2. The SOC analyst who received the phishing report correctly prioritized investigating
the UAL for MailItemsAccessed within 8 minutes of receiving the ticket.
3. Finance team was contacted before the wire was processed — the BEC attempt failed
because financial controls required verbal confirmation for large transfers.
This control should be documented and maintained.
Section 3: Detection Gaps
DETECTION GAPS
Gap 1: AiTM session token replay
Technique: T1557 (Adversary-in-the-Middle)
What happened: Attacker replayed session token from IP 185.220.101.44 at 09:21:17.
MailItemsAccessed from this IP at 09:22 (25 minutes before any alert).
No alert fired for: MailItemsAccessed from new/unknown IP within 60 min of phishing delivery.
Log source available: M365 UAL (OfficeActivity table — MailItemsAccessed, ClientIP field)
Why no alert: Detection rule doesn't exist. Data is available; rule is missing.
Action: DE-2024-0187: Write KQL rule — MailItemsAccessed from IP not seen for this user
in prior 30 days, within 90 minutes of phishing email delivery. Alert P2.
Owner: detection-engineering Deadline: 14 days
Gap 2: Inbox rule creation
Technique: T1564.008 (Email Hiding Rules)
What happened: New-InboxRule created at 09:50, not detected until manual investigation.
No alert fired for: New-InboxRule with external forwarding or deletion criteria.
Action: DE-2024-0188: Alert on New-InboxRule events where forwarding target is external
domain OR delete criteria match security-related keywords.
Owner: detection-engineering Deadline: 14 days
Section 4: Response Gaps
RESPONSE GAPS
Gap 1: MTTD was 53 minutes
Timeline: Phishing delivered 09:14. First alert 10:07 (DLP rule on volume of email read).
MailItemsAccessed events were available from 09:22 — 45 minutes of attacker
dwell before any alert. Target SLA: P2 ≤ 15 minute MTTD.
Root cause: No real-time alerting on MailItemsAccessed — DLP was the only trigger.
Action: Feeds into DE-2024-0187 above (detection rule).
Gap 2: L1 escalation note was missing victim interaction status
Timeline: L1 escalated "suspicious AiTM email" at 10:11 without noting that MailItemsAccessed
events were already present. L2 spent 12 minutes re-pulling UAL.
Root cause: L1 checklist for AiTM escalation doesn't include "check MailItemsAccessed."
Action: Update AiTM playbook — add MailItemsAccessed check to L1 investigation steps.
Playbook owner: SOC-lead. Deadline: 7 days.
Section 5: Prevention Gaps
PREVENTION GAPS
Gap 1: DMARC policy p=quarantine allowed lookalike domain to bypass spam filtering
Corp-finance.net DMARC passed (for corp-finance.net), but DMARC for corp.com is p=quarantine
not p=reject — this email was quarantined but still accessible in spam folder.
With p=reject on corp.com, the alignment failure would have caused rejection.
Action: Upgrade corp.com DMARC to p=reject. Test with sample mail flow first.
Owner: email-security Deadline: 30 days Risk: Test first — may break forwarding paths
Gap 2: Push MFA (Microsoft Authenticator) is vulnerable to AiTM
Standard push MFA provides no protection against AiTM — attacker completes MFA through proxy.
Only FIDO2/passkeys (phishing-resistant) would have prevented token theft.
Action: Finance team pilot: deploy FIDO2 security keys (YubiKey) for 10 finance users.
Success metric: zero AiTM-successful sessions against FIDO2-enrolled users.
Owner: identity-team Deadline: Q4 planning cycle Note: Budget request required.
Section 6: Action Item Summary
| ID | Gap Category | Action | Owner | Deadline | Status |
|-------------|--------------|----------------------------------|------------------|----------|---------|
| DE-2024-187 | Detection | KQL rule: MailItemsAccessed new IP| detect-eng | 14 days | Open |
| DE-2024-188 | Detection | KQL rule: New-InboxRule external | detect-eng | 14 days | Open |
| PB-2024-041 | Response | Update AiTM playbook L1 steps | soc-lead | 7 days | Open |
| EM-2024-022 | Prevention | DMARC p=reject migration | email-security | 30 days | Open |
| ID-2024-015 | Prevention | FIDO2 pilot — finance team | identity-team | Q4 plan | Open |
| SA-2024-033 | Prevention | AiTM simulation — finance team | security-aware | 60 days | Open |