KEYBOARD SHORTCUTS
Next section→ / ]
Previous section← / [
Jump to section1 – 9
Print playbookP
Toggle themeT
Close / dismissEsc
This menu?
H3AD-IR / PHISHBOOK
PHISHING INCIDENT PLAYBOOK
OPEN PHISHOPS ↗

OVERVIEW

This playbook covers the end-to-end phishing incident response workflow from first alert to ticket closure. Use PHISHOPS alongside this document to track case state and collect IOCs.

1Phishing emails reported by users or caught by an email gateway or SIEM rule.
2Business Email Compromise (BEC) attempts targeting finance, executives, or privileged accounts.
3Credential harvesting campaigns with or without payloads.
4Malware delivery via email attachment or embedded URL redirect chain.
This is a reference document. Use PHISHOPS to track active case inputs, IOC collection, and step completion. The "Open PHISHOPS" button in the top bar links directly.
LevelCriteriaResponse SLAOwner
P1 CRITICALLink clicked or attachment opened, auth anomaly confirmed, active session compromise15 minL3 + IR team
P2 HIGHDelivered to exec/finance/IT, credential harvesting page, targeted spear phish30 minL2
P3 MEDIUMDelivered, mass campaign, no confirmed click, low-quality payload2 hrL1
P4 LOWQuarantined or blocked before delivery, no user exposure4 hrL1
02Initial Triage: collect envelope fields, confirm auth results, set severity.
03Header Analysis: trace relay chain, analyze X-Originating-IP, review auth failures.
04URL Analysis: extract, defang, and sandbox all links without direct visit.
05Attachment Analysis: hash lookup, detonation, C2 and process IOC extraction.
06Identity and Impact: confirm click, pull Okta logs, check for MFA bypass or session theft.
07Containment: block, revoke, recall, and preserve evidence in the correct order.
08Escalation: apply L1/L2/L3 criteria, hand off to IR if thresholds are met.
09Query Templates: pre-built KQL/SPL/XQL for each investigation phase.

INITIAL TRIAGE

Establish context before any analysis. Collect envelope fields, confirm auth results at a high level, assess scope, and set initial severity.

T1566.001 Spearphishing Attachment T1566.002 Spearphishing Link
1Obtain raw email in EML or MSG format from the gateway or the user who reported it.
2Record sender address, Reply-To, Return-Path, recipient list, subject line, and receipt timestamp.
3Confirm the alert source: user report, SIEM rule, email gateway alert, or SOAR ticket.
4Check gateway disposition: delivered, quarantined, blocked, or recalled.
5Estimate delivery scope: one user, a role-based group, a department, or org-wide.
6Flag if the recipient is a high-value target: executive, finance team, IT/security, privileged service account.
SignalPass meansFail / Missing meansNext action
SPFSender IP is authorized by the domain's DNS recordIP not listed in SPF, or no SPF record existsFlag; cross-check X-Originating-IP in headers
DKIMCryptographic signature valid and domain-alignedSignature invalid, missing, or domain-misalignedFlag; check for email replay or modification
DMARCPasses at least one of SPF or DKIM with alignmentBoth fail, or no DMARC record on sender domainHigh suspicion; note policy: none/quarantine/reject
ESCALATE IMMEDIATELYSPF fail + DKIM fail + sender domain is a lookalike of a known vendor or internal domain. Treat as P1 targeted phish regardless of other signals until proven otherwise.
INITIAL TRIAGE ENRICHMENT
BY SENDER IP (paste X-Originating-IP or gateway relay IP)
BY SENDER EMAIL
EXTRACT ALL IOCs FROM RAW EMAIL BODY

HEADER ANALYSIS

Trace the full relay chain, verify authentication results line by line, and identify the true sending IP. Anomalies here often confirm spoofing or infrastructure abuse.

T1566.001 T1566.002 T1078.004 Valid Accounts: Cloud
1Read Received headers from bottom to top. The bottom entry is the originating server; the top is the final delivery point.
2Note every relay IP and hostname. Flag any server that is geographically inconsistent with the claimed sender domain or that has no PTR record.
3Check for unexpected relay hops through unknown or low-reputation hosting providers.
4Extract X-Originating-IP if present. This is the client IP that submitted the message to the first relay, often the attacker's true egress.
5Review Message-ID format. Legitimate senders have consistent Message-ID patterns. Randomly generated or mismatched domain Message-IDs are suspicious.
6Check the timestamp delta between Received hops. Long gaps may indicate message manipulation.
ResultMeaningRisk level
SPF passSending IP matches the domain's SPF recordLow (but can still be spoofed via subdomain)
SPF softfail (~all)IP not authorized but owner prefers no hard blockMedium, flag for review
SPF fail (-all)IP explicitly not authorized, should be rejectedHigh
DKIM passSignature valid, message unmodified in transitLow
DKIM fail / noneNo signature, or signature invalidHigh if combined with SPF fail
DMARC passAt least one aligned mechanism passesLow
DMARC failNeither SPF nor DKIM aligns with From domainHigh, especially with p=reject policy
NOTE:A DMARC pass does not guarantee legitimacy. Attackers can register lookalike domains with valid SPF/DKIM/DMARC and pass all checks. Always compare the From domain visually against known-good sender domains.
HEADER ENRICHMENT
ANALYZE FULL HEADER BLOCK (paste raw headers into tool)
BY X-ORIGINATING-IP
BY SENDER DOMAIN (infra mapping)

URL ANALYSIS

Extract, defang, and triage all URLs from the email body, headers, and any HTML source. Analyze redirect chains and domain infrastructure without visiting links directly.

T1566.002 Spearphishing Link T1204.001 User Execution: Malicious Link T1189 Drive-by Compromise
NEVER VISIT LINKS DIRECTLY.Use URLScan.io, VirusTotal, or CheckPhish to retrieve and render the destination safely. Direct visits can trigger fingerprinting, credential submission forms, or client-side exploits.
1Extract all URLs from the raw email: body text, HTML href attributes, and any embedded images or attachments.
2Defang before sharing or logging. Replace http with hxxp and wrap dots: domain[.]com.
3Decode any URL encoding, base64 strings, or obfuscated redirectors before analyzing the final destination.
4Use PARSE-X to extract IOCs from the raw HTML or email body in bulk before manual review.
SignalThresholdInterpretation
Domain age< 30 daysHigh risk. Newly registered domains are a primary indicator for phishing infrastructure.
Domain age30-90 daysMedium risk. Combine with other signals before escalating.
Typosquatting1-3 char difference from known brandHigh risk if targeting executives or vendor domains.
Free hosting TLD.xyz, .top, .click, .tk, .mlMedium-high. Common in commodity phishing kits.
No valid certSelf-signed or expired TLSMedium. Legitimate phishing often uses valid Let's Encrypt certs.
Landing page typeLogin form, fake O365/GoogleHigh confidence credential harvester.
URL AND DOMAIN ENRICHMENT
BY DOMAIN (infra mapping, PDNS, ASN, certs)
BY RESOLVED IP
FULL URL SANDBOX AND REPUTATION
RENDER AND SCREENSHOT (safe)
EXTRACT IOCS FROM EMAIL BODY

ATTACHMENT ANALYSIS

Hash-check before detonation. Detonate in an isolated sandbox. Extract all process, network, and file IOCs from the report before any other action.

T1566.001 Spearphishing Attachment T1204.002 User Execution: Malicious File T1059 Command and Scripting Interpreter
NEVER OPEN ON A PRODUCTION ENDPOINT.All detonation must occur in an isolated sandbox. If no sandbox is available, submit the hash to VirusTotal and MalwareBazaar for community verdicts before any other action.
1Extract the file from the email without executing it. Save to an isolated location.
2Generate SHA256 and MD5 hashes before any further action.
3Submit hash to VirusTotal and MalwareBazaar. If detection ratio is high, record the verdict and skip sandbox detonation if not required for IOC enrichment.
4Identify file type: Office doc (macro), PDF (JavaScript), script (PS1/VBS/JS), archive (ZIP/ISO/RAR), or binary (EXE/DLL).
5For Office files: check for VBA macros, XLM macros, or OLE embedded objects before detonation.
File typePrimary riskCommon technique
.docm / .xlsm / .pptmVBA macro executionPowerShell dropper, LOLBAS abuse
.pdfEmbedded JavaScript, URI redirectCredential link, JS shellcode
.zip / .iso / .imgContainer bypass of gateway AVLNK shortcut, embedded EXE
.ps1 / .vbs / .jsDirect script executionDownloader, keylogger, RAT
.exe / .dllBinary executionLoader, stealer, ransomware dropper
.lnkShortcut pointing to remote payloadHTML smuggling, ISO delivery
1Process creation tree: parent-child chain, any spawning of cmd.exe, powershell.exe, wscript.exe, or mshta.exe.
2Network callbacks: all outbound connections, DNS queries, and resolved IPs. These are your C2 indicators.
3Dropped files: paths, hashes, and purposes. Check each dropped file hash separately.
4Registry modifications: persistence keys (Run, RunOnce, scheduled tasks, services).
5MITRE ATT&CK techniques surfaced in the sandbox report: map them before closing the case.
ATTACHMENT ENRICHMENT
BY FILE HASH (SHA256 or MD5)
SANDBOX DETONATION

IDENTITY & IMPACT

Determine if the target user interacted with the phish. Review Okta and gateway logs for clicks, auth anomalies, MFA bypass attempts, and signs of active session compromise.

T1078 Valid Accounts T1539 Steal Web Session Cookie T1556 Modify Authentication Process T1621 MFA Request Generation
1Query the email gateway for click telemetry on the recipient. Proofpoint TAP, Defender for Office 365, and Mimecast all log URL clicks.
2Query endpoint telemetry for browser process spawning any URL containing the phishing domain within the suspect timeframe.
3Check proxy/DNS logs for outbound requests to the phishing domain or any domains in the redirect chain.
1Pull Okta System Log for the affected user from 2 hours before email receipt to 2 hours after.
2Look for new device enrollments, new IP addresses, or changes in user-agent string.
3Flag impossible travel: two auth events from geographically distant IPs within a short time window.
4Check for MFA prompt floods (MFA fatigue): multiple push notifications sent in rapid succession.
5Check for MFA method downgrade: switching from push to SMS or security question.
6Review new OAuth app grants or API token issuances in the window.
IndicatorWhat it suggestsAction
New session from different country after authSession token theft (AiTM phishing proxy)Revoke all sessions immediately, force re-auth
New session from VPN/proxy/Tor ASNAttacker using anonymizing infrastructureBlock the ASN range, revoke session
Admin role assignment in sessionPrivilege escalation post-compromiseP1, loop in IR immediately
Mail forwarding rule createdPersistence for ongoing data exfiltrationRemove rule, document all forwarded mail
MFA method changeAttacker locking out the legitimate userDisable account, escalate to IR
CREDENTIAL SUBMISSION CONFIRMED:Treat as full account compromise. Immediate account lock, all session revocation, password reset, MFA re-enrollment, and IR escalation are all mandatory. Do not wait for further confirmation.
IDENTITY ENRICHMENT
BY AFFECTED USER EMAIL (breach exposure check)
↗ DeHashed
OPEN ACTIVE CASE TRACKER

CONTAINMENT

Execute blocking, revocation, and evidence preservation in order. Document all IOCs before any blocking action. All steps require analyst approval before execution.

PRESERVE BEFORE BLOCKING:Export all raw evidence (EML, headers, sandbox report, Okta logs, IOC list) before executing any blocks. Blocking can destroy log context in some gateway and proxy systems.
01
Email recall and gateway block
Retract all delivered copies of the phishing email. Block sender address, Return-Path, and sender domain at the email gateway. If the email was forwarded, trace and retract those copies too.
02
URL and domain block at proxy and DNS
Block all phishing URLs and their root domains at the web proxy and DNS filtering layer. Include any domains found in the redirect chain. Use defanged IOCs when submitting tickets.
03
File hash block at endpoint
Submit the attachment hash to the EDR (CrowdStrike, Defender, SentinelOne) for organization-wide blocking. Include any dropped file hashes from sandbox analysis.
04
Account suspension and session revocation
If credential compromise is suspected: suspend the Okta user account, revoke all active sessions and OAuth tokens, reset password, and trigger MFA re-enrollment. Coordinate with the user before locking to avoid alert fatigue perception.
05
C2 IP and domain block at firewall
For attachment-based phish with confirmed C2: block all callback IPs and domains at the network perimeter firewall and DNS. Submit to your threat intel platform for org-wide propagation.
06
Evidence preservation
Export and store: raw EML file, full header analysis output, sandbox detonation report (PDF), Okta log export (CSV), URLScan screenshot of phishing page, and all IOCs in structured format. Tag with the ticket ID.

ESCALATION

Use these criteria to determine when to escalate and at what tier. If multiple triggers fire simultaneously, default to the highest applicable tier.

TriggerTierAction required
Email blocked by gateway, no deliveryL1Document, block sender, close as P4.
Email delivered, no click confirmed, low-quality payloadL1Block IOCs, recall email, close as P3.
Email delivered, targeted recipient, suspicious indicatorsL2Full analysis, identity check, notify manager if exec-targeted.
Credential harvesting page confirmed, delivery scope unknownL2Full URL analysis, identity check across all recipients.
Click confirmed, no auth anomaly yetL2Immediate identity check, suspend account if in doubt, escalate to L3.
Auth anomaly detected post-clickL3Suspend account, revoke sessions, loop in IR team, treat as P1.
MFA bypassed or downgradedL3Immediate account lock, mandatory IR escalation.
Credential submission confirmedL3Full compromise response. IR team ownership. Executive notification may apply.
Admin role assigned or mail forwarding rule created post-authL3P1. IR team. Possible breach notification scope assessment.
Malware payload executed on endpointL3Isolate endpoint, IR team, EDR containment, parallel malware analysis.
1Any confirmed credential compromise. Scope assessment and breach notification evaluation required.
2Malware executed on a production endpoint with confirmed C2 callbacks.
3Multiple users or departments targeted simultaneously in a coordinated campaign.
4Targeting of privileged accounts: IT admins, security team, finance with wire transfer authority.
5Evidence of post-exploitation persistence: registry keys, scheduled tasks, forwarding rules, new admin accounts.
TEXT IR escalation notification template
Subject: [P1 ESCALATION] Phishing - Credential Compromise - [USER] - [TICKET ID]

Team,

Escalating a confirmed phishing incident for IR ownership.

User: [user@company.com]
Timestamp of email receipt: [YYYY-MM-DD HH:MM UTC]
Confirmed action: [link clicked / credentials submitted / auth anomaly]
Auth anomaly detail: [impossible travel / MFA bypass / new session]
Current status: [account suspended / sessions revoked / pending]

IOCs collected: [X senders, Y IPs, Z URLs, W hashes]
Evidence stored: [ticket ID / SharePoint path]

Requesting IR team take ownership for scope assessment and breach review.

SOC Analyst: [name]
Ticket: [ID]

QUERY TEMPLATES

Pre-built queries for each investigation phase. Replace bracketed values with case-specific data before running. All queries are reference templates, not production-ready rules.

For production-grade detection rules and expanded query packs, see TRACERULES, QUICKTRACE, and TRACEPULSE.
KQL All emails from a suspicious sender domain in last 24h
EmailEvents
| where Timestamp > ago(24h)
| where SenderMailFromDomain =~ "[SENDER_DOMAIN]"
| project Timestamp, SenderFromAddress, RecipientEmailAddress,
          Subject, DeliveryAction, ThreatTypes, EmailDirection
KQL URL clicks from phishing domain across all users
UrlClickEvents
| where Timestamp > ago(48h)
| where Url contains "[PHISHING_DOMAIN]"
| project Timestamp, AccountUpn, Url, ActionType, IsClickedThrough, IPAddress
KQL Sign-in anomalies for affected user in a defined time window
SigninLogs
| where TimeGenerated between (
    datetime([START_TIME]) .. datetime([END_TIME]))
| where UserPrincipalName =~ "[USER@COMPANY.COM]"
| where ResultType != "0"
| project TimeGenerated, UserPrincipalName, IPAddress,
          Location, AppDisplayName, ResultType, ResultDescription
| sort by TimeGenerated asc
KQL New country sign-ins after email receipt (session token theft)
SigninLogs
| where TimeGenerated > ago(4h)
| where UserPrincipalName =~ "[USER@COMPANY.COM]"
| extend Country = tostring(LocationDetails.countryOrRegion)
| where Country !in ("[EXPECTED_COUNTRY_1]", "[EXPECTED_COUNTRY_2]")
| project TimeGenerated, UserPrincipalName, IPAddress,
          Country, AppDisplayName, UserAgent
KQL Mailbox rule creation events (persistence/exfil detection)
CloudAppEvents
| where Timestamp > ago(24h)
| where ActionType in ("New-InboxRule","Set-InboxRule")
| where AccountDisplayName =~ "[USER@COMPANY.COM]"
| extend RuleDetails = todynamic(RawEventData)
| project Timestamp, AccountDisplayName, ActionType,
          RuleDetails.Parameters, IPAddress
SPL Okta auth events for affected user in ±2h window
index=okta sourcetype=OktaIM2:log actor.alternateId="[USER@COMPANY.COM]"
| eval event_time=strftime(_time,"%Y-%m-%dT%H:%M:%SZ")
| table event_time actor.alternateId client.ipAddress
        client.geographicalContext.country
        outcome.result displayMessage authenticationContext.authenticationStep
| sort -_time
SPL Proofpoint email events by sender domain
index=email sourcetype=proofpoint sender_domain="[SENDER_DOMAIN]"
| table _time sender recipient subject action_dispo threatsInfoMap
| sort -_time
SPL Proxy logs for outbound connections to phishing domain
index=proxy src_ip="[ENDPOINT_IP]"
| search url="*[PHISHING_DOMAIN]*"
| table _time src_ip dest_host url http_method http_status bytes_out
| sort -_time
XQL Authentication events for affected user
config timeframe = 4h;
dataset = xdr_data
| filter event_type = "AUTH"
    and actor_effective_username = "[USER@COMPANY.COM]"
| fields _time, actor_effective_username, action_remote_ip,
         action_country, outcome, event_sub_type
| sort desc _time
XQL Network connections to phishing domain or C2 IP from endpoint
config timeframe = 24h;
dataset = xdr_data
| filter event_type = "NETWORK"
    and (action_remote_ip = "[C2_IP]"
         or dns_query_name contains "[PHISHING_DOMAIN]")
| fields _time, agent_hostname, actor_process_image_name,
         action_remote_ip, dns_query_name, action_remote_port
| sort desc _time
↗ TRACERULES ↗ QUICKTRACE ↗ TRACEPULSE
1 / 9 — OVERVIEW
VISITORS