SuperAPI AI Directory

analyzing-phishing-emails

Office & productivity

View repository

Updated 10-16 02:31

About this skill

Analyzing Phishing Emails

An email is a stack of claims — who sent it, where it came from, that its links are safe — and phishing analysis is checking each claim against evidence the sender could not forge: the Received chain, the authentication results, and the true destination of every link and attachment. The From header is a display, not a fact. Anyone can type any address into it; your job is to find the evidence that agrees or disagrees.

When to Use

  • A user reports a suspicious email and you need a verdict and IOCs
  • You have a .eml or .msg file to analyze offline
  • You are handed raw headers and asked whether a message is spoofed
  • A message carries a link or attachment that needs safe triage
  • A business email compromise, invoice-fraud, or vendor-impersonation case
  • Confirming whether a domain or brand was spoofed against your users

When NOT to Use

  • You extracted an attachment and need to detonate it — come here first to safely extract and defang it, then hand the payload to analyzing-malware
  • The phish already succeeded and you are chasing the mailbox/OAuth compromise in the tenant — use investigating-m365-entra
  • You are building the phishing campaign, not analyzing one — use performing-social-engineering
  • The broader incident the phish kicked off — use responding-to-incidents
  • Analyzing the callback traffic from a detonated payload — use analyzing-network-traffic

Safe Handling — Do This First

Treat every reported message as live. The failure mode is not misreading a header; it is clicking a link in a production mail client or double-clicking an attachment on your own host.

  • Never open the message in a live client. Attacker-controlled remote images fire a read beacon; one click on a link authenticates you to their harvester.
  • Work from the raw source only — the .eml/.msg, not a forwarded copy. Forwarding rewrites headers and strips the evidence you need.
  • Defang every indicator before it touches a report, ticket, or chat: http → hxxp, . → [.], @ → [at]. So http://evil.com/login becomes hxxp://evil[.]com/login. Defanging prevents an accidental click downstream and stops link-preview bots from detonating it for you.
  • Extract and detonate only in an isolated VM with no host sharing and simulated or monitored egress — see analyzing-malware for the build.

Getting the Raw Message

The visible email is a rendering. You need the source with all headers.

  • Outlook/Exchange: save as .msg, or in OWA use "View message source".
  • Gmail: "Show original" → Download Original gives a .eml.
  • .msg → readable: msgconvert sample.msg produces a .eml (RFC822).
  • Inspect structure: emldump.py sample.eml lists MIME parts and indices; emldump.py -s 4 -d sample.eml dumps part 4 (an attachment) without opening it. A .msg is an OLE compound file — oledump.py (DidierStevens) lists its streams.
  • View full headers: read the top block of the raw file directly, or paste into Message Header Analyzer (MHA) / Google's mha / MXToolbox Header Analyzer for a parsed hop table.

Keep the original file hashed and untouched; work on copies.

The Received Chain

The Received: headers are added by each mail server the message passes through, newest at the top. Read them bottom-up: the bottom-most Received is the originating server — the earliest, least-forgeable hop.

Received: from mail.contoso.com (mail.contoso.com [203.0.113.9])
    by mx.recipient.com ... ; Tue, 21 Jul 2026 09:14:02 +0000   <- final hop
Received: from smtp.sketchy-vps.ru ([185.220.101.5])
    by mail.contoso.com ...   ; Tue, 21 Jul 2026 09:13:58 +0000  <- origin
  • Trace the originating IP: the bottom hop's [bracketed IP]. Geolocate and WHOIS it (whois 185.220.101.5), check reputation, and reconcile it against the claimed sender. A "From: ceo@contoso.com" that originates on a Russian VPS is your finding.
  • Spot forged hops: attackers prepend fake Received lines to fabricate a reputable origin. Only hops added by servers you trust are reliable — trust breaks at the first server outside your control. A hop that references a server not present in the next hop's by is invented.
  • Timezone and hop-time anomalies: hop timestamps should increase upward by seconds. Negative deltas, multi-hour jumps, or a mix of implausible timezones indicate forgery or relay through odd infrastructure.
  • Reconcile with the claimed sender: the origin domain, its PTR/rDNS, and the From domain should tell one coherent story. They usually do not in a phish.

Authentication Results

SPF, DKIM, and DMARC are the forgery-resistant checks. The receiving server records them in Authentication-Results. Read it, and re-verify rather than trusting a summary.

Authentication-Results: mx.recipient.com;
  spf=pass (sender IP is 185.220.101.5) smtp.mailfrom=bounce.sketchy-vps.ru;
  dkim=pass header.d=sketchy-vps.ru header.s=selector1;
  dmarc=fail (p=reject sp=reject dis=none) header.from=contoso.com
  • SPF authenticates the envelope sender (Return-Path / smtp.mailfrom / MAIL FROM), not the visible From. Values: pass (IP is authorized for the envelope domain), fail (hard -all reject), softfail (~all, suspicious but delivered), neutral/none (no policy). Check the domain's record: dig txt contoso.com and read the v=spf1 ... string.
  • DKIM is a cryptographic signature over selected headers and the body. dkim=pass proves the message was signed by the key at d='s selector and not modified. The load-bearing question is alignment: does header.d= match the From domain? A valid signature from d=mailer-xyz.com on a message claiming From: contoso.com is not contoso. Re-verify with dkimverify < sample.eml (dkimpy) and fetch the key via dig txt selector1._domainkey.contoso.com.
  • DMARC ties SPF/DKIM to the visible From via alignment and applies the domain owner's policy. dmarc=pass requires SPF or DKIM to pass AND be aligned with header.from. Read the policy: dig txt _dmarc.contoso.com → v=DMARC1; p=reject; .... p=reject/quarantine with dmarc=fail means the owner told you to distrust it.
  • ARC (ARC-Seal/ARC-Authentication-Results) preserves upstream auth results across forwarders that would otherwise break SPF/DKIM. Use it to see how auth looked before a mailing list or gateway relayed the message.
  • Envelope vs header From: Return-Path/envelope-from is what bounces go to and what SPF checks; the header From: is what the user sees. Phishers make them differ — a benign-looking From with a throwaway envelope domain that happens to pass SPF is the classic pattern.

Display-Name and Lookalike Spoofing

Much phishing passes authentication because it comes from a real mailbox on a lookalike domain. The auth checks pass for that domain; the deception is visual.

  • Display-name spoofing: From: "IT Helpdesk" <random@gmail.com>. The name is a free-text label; read the actual address.
  • Cousin / lookalike domains: cont0so.com, contoso-support.com, contoso.co. Diff against the real domain character by character.
  • Homoglyph / IDN: Unicode characters that render like ASCII (Cyrillic а for Latin a). Punycode-encoded domains appear in headers as xn-- — e.g. xn--cntoso-.... Decode with idn / python3 -c "print('xn--80ak6aa92e.com'.encode().decode('idna'))" and compare the rendered form.
  • Reply-To mismatch: From: ceo@contoso.com but Reply-To: ceo.contoso@gmail.com. The reply silently goes to the attacker — a hallmark of BEC.
  • BEC with no payload: pure text asking for a wire transfer, gift cards, or W-2 data. No link, no attachment, nothing to sandbox. The signal is entirely in the headers (Reply-To, origin, auth) and the pretext.

Header Forensics

  • Message-ID sanity: format is <unique@sending-domain>. The domain should match the sending infrastructure. A Message-ID domain that disagrees with the origin, or a malformed/duplicated ID, suggests a spoofing tool.
  • X-Originating-IP: some webmail stamps the true client IP here — pivot on it, but note it is client-suppliable and can be forged.
  • X-Mailer / User-Agent: reveals the sending client. Bulk-phish kits and scripts (PHPMailer, Python, custom mailers) look nothing like Outlook or the claimed sender's normal stack.
  • Mailer fingerprints: legitimate bulk senders (SendGrid, Amazon SES, Mailchimp) add characteristic X- headers and Received paths. Their presence on a "personal" note from your CEO is a contradiction.

URL Analysis

Every link is a claim about where it goes. Resolve it without visiting it.

  • Unwrap redirects and shorteners: expand bit.ly/t.co with curl -sI hxxp://bit[.]ly/xyz (read Location:, do not follow) or a preview service. Chase every hop to the real landing page.
  • Decode wrapper rewrites — the real URL is inside the wrapper:
    • Microsoft SafeLinks: https://*.safelinks.protection.outlook.com/?url=<encoded>&... — URL-decode the url= parameter.
    • Proofpoint URLDefense: https://urldefense.com/v3/__<encoded>__;... — decode with the published urldefense decoder (v2/v3 schemes differ). These wrappers hide the destination; always extract the original.
  • Quishing (QR-code phishing): the payload is an image, not a link. Extract the image part (emldump.py -s N -d), then decode: zbarimg qr.png or python3 -c "from PIL import Image; import pyzbar.pyzbar as z; print(z.decode(Image.open('qr.png')))". Analyze the decoded URL like any other.
  • Intent — harvest vs delivery: a link to a cloned login page (Microsoft, DocuSign, a bank) is credential harvesting; a link that downloads a file is malware delivery. They need different responses.
  • Detonate safely: submit the URL to urlscan.io (use unlisted/private scans for targeted phish so you don't tip the actor) or a sandbox, and pull the real landing page, screenshot, and served content. Extract the landing page and any kit files for the IOC set.

Attachment Analysis

Identify and defang before anything executes.

  • Hash and identify: sha256sum att.ext && file att.ext. Extract with emldump.py -s N -d sample.eml > att.ext — never by double-clicking.
  • Common delivery wrappers: HTML smuggling (a .html that assembles a payload in-browser via a Blob), ISO/IMG/VHD (mount bypasses MOTW), LNK shortcuts, OneNote (.one) with embedded scripts, and password-protected archives (password in the email body defeats gateway scanning).
  • Documents/macros: exiftool att.docx for metadata and authoring fingerprints; oleid att.xls and olevba --deobf att.xls / oledump.py att.doc for macros; rtfobj att.rtf for embedded objects.
  • Once identified, hand the live payload to analyzing-malware for sandboxed detonation, unpacking, and C2 extraction. This skill's job is safe extraction and triage, not detonation.

Pulling and Packaging IOCs

Extract a clean, defanged indicator set for blocking and hunting:

  • Sender infrastructure: originating IP, envelope-from domain, From/cousin domains, Reply-To, Message-ID domain, mailer fingerprints.
  • URLs: the wrapped and unwrapped forms, final landing page, shortener chain, and any kit hostnames from urlscan.
  • Hashes: SHA-256 of every attachment and of decoded/downloaded payloads.
  • Hunting selectors: subject lines, sender display names, and body fingerprints to search the mail gateway and other mailboxes.

Package these for producing-threat-intelligence when the phish is part of a tracked campaign, and for reporting-security-findings for the writeup.

Scoping the Campaign

One report is rarely the only recipient. Find the rest before you close.

  • M365: Search-UnifiedAuditLog and Content Search / New-ComplianceSearch for the subject, sender, and URL across all mailboxes; hard-delete or quarantine matches via Get-QuarantineMessage / eDiscovery purge.
  • Mail gateway (Proofpoint, Mimecast, Defender for O365): search message trace / Threat Explorer for the sender domain, URL, and attachment hash to enumerate every recipient and whether anyone clicked or replied.
  • If any recipient interacted, the phish may have succeeded — pivot to investigating-m365-entra for tenant-side hunting (sign-ins, inbox rules, OAuth grants) and to responding-to-incidents for the broader response.

Rationalizations to Reject

  • "SPF passed, so it's legitimate." SPF authenticates the envelope domain, not the visible From. A passing SPF on a lookalike or throwaway envelope domain is exactly what a competent phish shows. Check DMARC alignment.
  • "DKIM is valid, so it's from them." A valid signature only proves the d= domain signed it. If d= isn't aligned with the From domain, it's signed by someone else. Alignment is the question, not signature validity.
  • "No attachment or link, so it's harmless." BEC and payment-fraud phish carry neither — the weapon is the pretext and the Reply-To. Read the headers.
  • "DMARC failed but it was delivered, so it's fine." Delivery reflects the receiver's enforcement config, not the message's legitimacy. dmarc=fail with p=reject is the sender's domain telling you to distrust it.
  • "The From address is our real domain, so it's internal." The From header is free text. Without aligned SPF/DKIM and a plausible origin hop, an internal-looking From means nothing.
  • "I'll just click the link to see where it goes." Clicking authenticates you to a harvester or fires a beacon. Resolve URLs with headers-only requests, wrapper decoders, and urlscan — never a live browser.
  • "The gateway let it through, so it's clean." Gateways miss lookalike domains, freshly registered infrastructure, HTML smuggling, and password- protected archives by design. A delivered message is not a vetted one.

ATT&CK Coverage

Generated from secskills-core/ttp-index.json — edit that file, then run python3 scripts/sync_attack.py --write. Re-verify IDs against the current ATT&CK release before citing them in a report.

Reconnaissance (TA0043)

  • T1598 Phishing for Information — see also performing-social-engineering

Initial Access (TA0001)

  • T1566 Phishing — see also performing-social-engineering
  • T1566.001 Spearphishing Attachment — see also performing-social-engineering, analyzing-malware
  • T1566.002 Spearphishing Link — see also performing-social-engineering

Detection content for any of these: engineering-detections. Proactive search: hunting-threats. Post-compromise: responding-to-incidents.

References

  • analyzing-malware — sandboxed detonation and C2 extraction of attachments
  • investigating-m365-entra — tenant-side hunting when the phish succeeded
  • performing-social-engineering — building phishing campaigns (offensive)
  • analyzing-network-traffic — callback traffic from a detonated payload
  • producing-threat-intelligence — pivoting IOCs into tracked campaigns
  • reporting-security-findings — writing up the triage and verdict
  • oletools (olevba, oleid, rtfobj), oledump.py/emldump.py (DidierStevens suite), msgconvert (Email::Outlook::Message, Perl), and exiftool for message and attachment parsing
  • Message Header Analyzer (MHA) and MXToolbox for parsing the Received chain and querying SPF/DKIM/DMARC records
  • urlscan.io and VirusTotal for URL/file detonation and reputation
  • PhishTool for guided end-to-end phishing analysis and reporting