Analyzing Phishing Emails logo

Analyzing Phishing Emails

Community
trilwu
analyzing-phishing-emails

Triage and forensically analyze reported phishing safely — extract the raw message, read the Received chain, verify SPF/DKIM/DMARC, detect display-name and lookalike spoofing, unwrap redirects and SafeLinks/URLDefense, decode quishing QR codes, triage attachments, and pull IOCs for hunting. Use when handed a reported phishing email, a suspicious .eml or .msg file, a set of email headers to analyze, a malicious attachment or link to triage, or a business email compromise or spoofing case.

Overview

Publishertrilwu
Repositorysecskills
Skill nameanalyzing-phishing-emails
Stars
144
Forks
15
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by trilwu on GitHub. Read the source before you install it.

Installation

Install the Analyzing Phishing Emails AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/trilwu/secskills.git /tmp/secskills
mkdir -p .claude/skills
cp -r /tmp/secskills/secskills-defense/skills/analyzing-phishing-emails .claude/skills/analyzing-phishing-emails
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Analyzing Phishing Emails in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Analyzing Phishing Emails on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Analyzing Phishing Emails is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

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: httphxxp, .[.], @[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.comv=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

Frequently asked questions

What does the Analyzing Phishing Emails AI skill do?

Triage and forensically analyze reported phishing safely — extract the raw message, read the Received chain, verify SPF/DKIM/DMARC, detect display-name and lookalike spoofing, unwrap redirects and SafeLinks/URLDefense, decode quishing QR codes, triage attachments, and pull IOCs for hunting. Use when handed a reported phishing email, a suspicious .eml or .msg file, a set of email headers to analyze, a malicious attachment or link to triage, or a business email compromise or spoofing case.

Why use Analyzing Phishing Emails on TypingMind?

Because you install it once and use it with any model. Analyzing Phishing Emails is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Analyzing Phishing Emails in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/trilwu/secskills/tree/main/secskills-defense/skills/analyzing-phishing-emails. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Analyzing Phishing Emails?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Analyzing Phishing Emails?

As many as you like. As long as a model supports skills, you can use Analyzing Phishing Emails with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Analyzing Phishing Emails AI skill free?

Yes. It is published on GitHub by trilwu under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇