Lesson 3 of 5 · 20 min read

Post-Incident Lessons Learned — From Incident to Improvement

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:

NOT a blame meeting. Ground rules:

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    |