Phishing Email Investigation Guide: Headers, IOCs, and Containment
A phishing email investigation has two parallel tracks: evidence collection and active containment. The goal in the first 30 minutes is to characterize the threat (credential harvesting, malware delivery, BEC pretexting), extract all IOCs, and pull the message from inboxes before additional users engage with it. This playbook covers each step with the specific commands and queries.
Preserving and Staging the Evidence
Save the original .eml file before anything else. In Outlook: File > Save As > .msg, then convert to .eml; in Gmail: three dots > Show original > Download. Create a dedicated phishing investigation folder or workspace separate from production systems. Never click links in the original email -- all analysis should be performed on copies in an isolated environment. If analyzing on a workstation, use an isolated VM or a remote browser service such as Browserling or URLScan.io. Timestamp everything: when the email was reported, when it was received (from headers), and when investigation started. These timestamps matter for incident documentation and SLA reporting.
Reading the Email Headers
Where to find raw headers: Outlook (File > Properties > Internet Headers), Gmail (three dots > Show original), M365 Admin (Message Trace). For visual analysis, paste headers into https://toolbox.googleapps.com/apps/messageheader/ to get a structured delivery path diagram.
Key headers to extract:
From:(display name -- often spoofed to impersonate a trusted sender)Return-Path:(bounce address -- often reveals the true sender domain)Reply-To:(where replies go -- commonly abused in BEC attacks)Received:(chain of mail servers -- read bottom-up, each entry is one hop)X-Originating-IP:(original client IP, when present)Authentication-Results:(SPF/DKIM/DMARC verdicts added by your MX gateway)
Manual IP check: nslookup -type=PTR [sending_IP] then whois [sending_IP].
Check sending IP against blocklists:
curl "https://api.abuseipdb.com/api/v2/check?ipAddress=[IP]" -H "Key: [your_key]"
Briefings like this, every morning before 9am.
Threat intel, active CVEs, and campaign alerts, distilled for practitioners. 50,000+ subscribers. No noise.
Extracting and Checking IOCs
Defang all IOCs before sharing: replace https:// with hxxps:// and . with [.] when pasting into tickets, emails, or Slack.
URL analysis (safe -- no click required):
- URLScan.io submission:
curl -X POST https://urlscan.io/api/v1/scan/ \
-H 'API-Key: [key]' \
-d '{"url": "[url]", "visibility": "private"}'
- VirusTotal URL lookup:
curl "https://www.virustotal.com/vtapi/v2/url/report?apikey=[key]&resource=[url]"
File and attachment analysis:
- Get SHA256 hash:
shasum -a 256 attachment.pdf - VirusTotal file lookup:
curl "https://www.virustotal.com/vtapi/v2/file/report?apikey=[key]&resource=[sha256]" - Confirm MIME type:
file attachment.pdf(verify it is actually a PDF and not a renamed executable)
Sender infrastructure check: run whois [sending_domain] and note the domain registration date. Domains registered under 30 days ago are a high-confidence malicious signal and should be treated as confirmed infrastructure.
Pulling the Message from M365 Mailboxes
First, confirm delivery scope using the M365 Admin Center: Exchange Admin Center > Mail flow > Message trace. Search by sender address and the date range to identify every mailbox that received the message.
PowerShell commands for bulk search and delete (requires Compliance Center access):
# Create the compliance search
New-ComplianceSearch -Name "Phish-[date]" -ExchangeLocation All `
-ContentMatchQuery 'subject:"[exact subject line]"'
# Start the search
Start-ComplianceSearch -Identity "Phish-[date]"
# Check results
Get-ComplianceSearch -Identity "Phish-[date]" | FL
# Soft-delete from all matched mailboxes
New-ComplianceSearchAction -SearchName "Phish-[date]" -Purge -PurgeType SoftDelete
Confirm deletion by re-running the search and verifying ResultsCount = 0. Soft-delete moves messages to the Recoverable Items folder, which preserves them for legal hold if needed while removing them from user view.
Pulling the Message from Google Workspace
Google Admin Console path: Reports > Email Log Search > search by sender address or subject line. This shows every user who received the message and the delivery status.
For bulk removal, Google Vault (Workspace Vault) is the fastest path: New Matter > Email search > set sender and date range > Export and confirm scope > Delete. Vault requires a Workspace Business or Enterprise license.
For programmatic removal using the Gmail API with a service account that has domain-wide delegation:
# Install google-api-python-client
pip install google-api-python-client google-auth
# Use the Admin SDK Directory API to iterate user list
# Use the Gmail API messages.list with q="from:[sender]" per user
# Use messages.trash or messages.delete per message ID
For smaller organizations without Vault, the Admin Console email log search combined with per-user Gmail trash is a workable manual fallback.
Closing the Loop -- Indicators and Lessons
IOC documentation template (capture all of these for every investigation):
- Sender email address and display name
- Return-Path domain
- Sending IP and hosting provider
- All URLs found in the message body
- Attachment file names and SHA256 hashes
- Subject line (exact)
- Date and time received (UTC)
- Number of mailboxes hit
- Number of users who clicked or replied
Blocking actions: add the sending domain to the email gateway blocklist, add URLs to the proxy or DNS filter, add the sending IP to the perimeter firewall deny list. Coordinate all three simultaneously so a new email from the same infrastructure is blocked at multiple layers.
User communication:
- Users who received but did not click: a one-sentence awareness note is sufficient. Do not create alarm.
- Users who clicked a link: immediate follow-up call to confirm whether credentials were entered. If credential submission is confirmed, escalate to full incident response: password reset, session revocation, audit of account activity.
Metrics to capture for post-incident reporting: time from initial report to containment action, number of mailboxes hit, number of users who clicked, whether any credentials were submitted.
The bottom line
Phishing investigation is a race between your analysis and the next user click. Preserve the email first, pull the delivery scope from your mail platform, extract and defang IOCs, check threat intel, then issue the purge command. The 30-minute window is tight but achievable if you have the commands ready before an incident.
Frequently asked questions
What information should I collect first when investigating a phishing email?
Before doing anything else, preserve the original email with full headers as an .eml file or forward to a dedicated phishing mailbox. Never investigate the email in the production inbox -- use a secure analysis environment.
How do I read email headers to trace where the message came from?
Read Received: headers bottom-up. Each hop adds one header. The bottom-most Received: header shows the originating IP. Use nslookup to reverse-resolve it and check against SPF records for the sender domain.
How do I check SPF, DKIM, and DMARC results in email headers?
Look for Authentication-Results: header added by your mail gateway. Format: spf=pass/fail, dkim=pass/fail, dmarc=pass/fail. DMARC fail means the message did not come from an authorized sender.
How do I pull a phishing email from all mailboxes in Microsoft 365?
Use `Search-Mailbox` (older) or `New-ComplianceSearch` in the Security & Compliance Center. The command: `New-ComplianceSearch -Name "Phishing Hunt" -ExchangeLocation All -ContentMatchQuery 'subject:"[exact subject]"'` then `Start-ComplianceSearch`.
What threat intel sources should I check for phishing IOCs?
VirusTotal for URL and file hash reputation. URLScan.io for URL behavior. URLhaus for malware distribution URLs. PhishTank for confirmed phishing pages. Shodan for the sending IP.
When should I detonate a phishing attachment and how?
Only in an isolated sandbox -- never on a workstation. Options: Any.run (interactive), Joe Sandbox, Hybrid Analysis, Triage (tria.ge). Submit the file hash to VirusTotal first; if it's known malware, skip detonation.
Sources & references
Free resources
Critical CVE Reference Card 2025–2026
25 actively exploited vulnerabilities with CVSS scores, exploit status, and patch availability. Print it, pin it, share it with your SOC team.
Ransomware Incident Response Playbook
Step-by-step 24-hour IR checklist covering detection, containment, eradication, and recovery. Built for SOC teams, IR leads, and CISOs.
Get threat intel before your inbox does.
50,000+ security professionals read Decryption Digest for early warnings on zero-days, ransomware, and nation-state campaigns. Free, weekly, no spam.
Unsubscribe anytime. We never sell your data.

Founder & Cybersecurity Evangelist, Decryption Digest
Cybersecurity professional with expertise in threat intelligence, vulnerability research, and enterprise security. Covers zero-days, ransomware, and nation-state operations for 50,000+ security professionals weekly.
The Mythos Brief is free.
AI that finds 27-year-old zero-days. What it means for your security program.
