Analyzing Phishing Email Headers Overview Email headers contain critical metadata that reveals the true origin, routing path, and authentication status of emails. Analyzing these headers is a foundational skill for identifying phishing attempts, verifying sender authenticity, and gathering threat intelligence. This skill covers systematic extraction and interpretation of email headers using both manual techniques and automated tools. Prerequisites - Basic understanding of SMTP protocol and email delivery - Familiarity with DNS records (MX, TXT, SPF, DKIM, DMARC) - Python 3.8+ installed - Acce…

, received_value)\n if date_match:\n hop.timestamp = date_match.group(1).strip()\n\n proto_match = re.search(r'with\\s+(ESMTP[SA]*|SMTP[SA]*|HTTP[S]?|LMTP)',\n received_value, re.IGNORECASE)\n if proto_match:\n hop.protocol = proto_match.group(1).upper()\n\n return hop\n\n\ndef parse_authentication_results(auth_header: str) -> AuthenticationResult:\n \"\"\"Parse Authentication-Results header.\"\"\"\n result = AuthenticationResult()\n\n spf_match = re.search(r'spf=(pass|fail|softfail|neutral|none|temperror|permerror)',\n auth_header, re.IGNORECASE)\n if spf_match:\n result.spf = spf_match.group(1).lower()\n\n spf_domain_match = re.search(r'smtp\\.mailfrom=([\\w.\\-@]+)', auth_header, re.IGNORECASE)\n if spf_domain_match:\n result.spf_domain = spf_domain_match.group(1)\n\n dkim_match = re.search(r'dkim=(pass|fail|none|neutral|temperror|permerror)',\n auth_header, re.IGNORECASE)\n if dkim_match:\n result.dkim = dkim_match.group(1).lower()\n\n dkim_domain_match = re.search(r'header\\.[di]=([\\w.\\-]+)', auth_header, re.IGNORECASE)\n if dkim_domain_match:\n result.dkim_domain = dkim_domain_match.group(1)\n\n dmarc_match = re.search(r'dmarc=(pass|fail|none|bestguesspass|temperror|permerror)',\n auth_header, re.IGNORECASE)\n if dmarc_match:\n result.dmarc = dmarc_match.group(1).lower()\n\n dmarc_domain_match = re.search(r'header\\.from=([\\w.\\-]+)', auth_header, re.IGNORECASE)\n if dmarc_domain_match:\n result.dmarc_domain = dmarc_domain_match.group(1)\n\n compauth_match = re.search(r'compauth=(\\w+)', auth_header, re.IGNORECASE)\n if compauth_match:\n result.compauth = compauth_match.group(1)\n\n return result\n\n\ndef geolocate_ip(ip_address: str) -> str:\n \"\"\"Geolocate an IP address using ip-api.com (free, no key required).\"\"\"\n if not HAS_REQUESTS or not ip_address:\n return \"unknown\"\n try:\n resp = requests.get(f\"http://ip-api.com/json/{ip_address}\",\n timeout=5,\n params={\"fields\": \"country,city,org,status\"})\n if resp.status_code == 200:\n data = resp.json()\n if data.get(\"status\") == \"success\":\n return f\"{data.get('city', '')}, {data.get('country', '')} ({data.get('org', '')})\"\n except Exception:\n pass\n return \"unknown\"\n\n\ndef reverse_dns_lookup(ip_address: str) -> str:\n \"\"\"Perform reverse DNS lookup on an IP address.\"\"\"\n if not ip_address:\n return \"\"\n try:\n hostname = socket.gethostbyaddr(ip_address)\n return hostname[0]\n except (socket.herror, socket.gaierror, OSError):\n return \"\"\n\n\ndef check_abuseipdb(ip_address: str, api_key: str = \"\") -> dict:\n \"\"\"Check IP against AbuseIPDB (requires API key).\"\"\"\n if not HAS_REQUESTS or not api_key or not ip_address:\n return {}\n try:\n headers = {\"Key\": api_key, \"Accept\": \"application/json\"}\n params = {\"ipAddress\": ip_address, \"maxAgeInDays\": \"90\"}\n resp = requests.get(\"https://api.abuseipdb.com/api/v2/check\",\n headers=headers, params=params, timeout=10)\n if resp.status_code == 200:\n return resp.json().get(\"data\", {})\n except Exception:\n pass\n return {}\n\n\ndef analyze_indicators(analysis: HeaderAnalysis) -> list:\n \"\"\"Detect phishing indicators from parsed header data.\"\"\"\n indicators = []\n\n # Check From vs Return-Path mismatch\n if (analysis.from_domain and analysis.return_path_domain and\n analysis.from_domain != analysis.return_path_domain):\n indicators.append(PhishingIndicator(\n category=\"sender_mismatch\",\n description=f\"From domain ({analysis.from_domain}) differs from \"\n f\"Return-Path domain ({analysis.return_path_domain})\",\n severity=\"high\",\n raw_value=f\"From: {analysis.from_domain}, Return-Path: {analysis.return_path_domain}\"\n ))\n\n # Check From vs Reply-To mismatch\n if (analysis.from_domain and analysis.reply_to_domain and\n analysis.from_domain != analysis.reply_to_domain):\n indicators.append(PhishingIndicator(\n category=\"reply_to_mismatch\",\n description=f\"From domain ({analysis.from_domain}) differs from \"\n f\"Reply-To domain ({analysis.reply_to_domain})\",\n severity=\"high\",\n raw_value=f\"From: {analysis.from_domain}, Reply-To: {analysis.reply_to_domain}\"\n ))\n\n # Check SPF failure\n if analysis.authentication.spf in (\"fail\", \"softfail\"):\n indicators.append(PhishingIndicator(\n category=\"authentication_failure\",\n description=f\"SPF check returned {analysis.authentication.spf}\",\n severity=\"high\" if analysis.authentication.spf == \"fail\" else \"medium\",\n raw_value=f\"spf={analysis.authentication.spf}\"\n ))\n\n # Check DKIM failure\n if analysis.authentication.dkim == \"fail\":\n indicators.append(PhishingIndicator(\n category=\"authentication_failure\",\n description=\"DKIM signature verification failed\",\n severity=\"high\",\n raw_value=\"dkim=fail\"\n ))\n\n # Check DMARC failure\n if analysis.authentication.dmarc == \"fail\":\n indicators.append(PhishingIndicator(\n category=\"authentication_failure\",\n description=\"DMARC policy check failed\",\n severity=\"critical\",\n raw_value=\"dmarc=fail\"\n ))\n\n # Check for missing Message-ID\n if not analysis.message_id:\n indicators.append(PhishingIndicator(\n category=\"missing_header\",\n description=\"Message-ID header is missing\",\n severity=\"medium\",\n raw_value=\"\"\n ))\n\n # Check for suspicious X-Mailer\n suspicious_mailers = [\n \"PHPMailer\", \"King Phisher\", \"GoPhish\", \"Swaks\",\n \"Sendinblue\", \"Mass Mailer\", \"Bulk Mailer\"\n ]\n if analysis.x_mailer:\n for mailer in suspicious_mailers:\n if mailer.lower() in analysis.x_mailer.lower():\n indicators.append(PhishingIndicator(\n category=\"suspicious_mailer\",\n description=f\"Suspicious X-Mailer detected: {analysis.x_mailer}\",\n severity=\"high\",\n raw_value=analysis.x_mailer\n ))\n break\n\n # Check for too few received hops (direct injection)\n if len(analysis.received_hops) \u003c= 1:\n indicators.append(PhishingIndicator(\n category=\"routing_anomaly\",\n description=\"Very few Received hops - possible direct SMTP injection\",\n severity=\"medium\",\n raw_value=f\"Hop count: {len(analysis.received_hops)}\"\n ))\n\n # Check for missing authentication results\n auth = analysis.authentication\n if auth.spf == \"none\" and auth.dkim == \"none\" and auth.dmarc == \"none\":\n indicators.append(PhishingIndicator(\n category=\"no_authentication\",\n description=\"No email authentication results found (SPF, DKIM, DMARC all absent)\",\n severity=\"high\",\n raw_value=\"\"\n ))\n\n return indicators\n\n\ndef calculate_risk_score(indicators: list) -> tuple:\n \"\"\"Calculate risk score from indicators. Returns (score, level).\"\"\"\n severity_weights = {\"critical\": 30, \"high\": 20, \"medium\": 10, \"low\": 5}\n score = 0\n for indicator in indicators:\n score += severity_weights.get(indicator.severity, 0)\n\n score = min(score, 100)\n\n if score >= 70:\n level = \"CRITICAL\"\n elif score >= 50:\n level = \"HIGH\"\n elif score >= 30:\n level = \"MEDIUM\"\n elif score >= 10:\n level = \"LOW\"\n else:\n level = \"CLEAN\"\n\n return score, level\n\n\ndef analyze_headers(raw_headers: str, enrich: bool = False,\n abuseipdb_key: str = \"\") -> HeaderAnalysis:\n \"\"\"\n Main analysis function. Parses raw email headers and produces\n a complete HeaderAnalysis report.\n \"\"\"\n analysis = HeaderAnalysis()\n\n # Calculate hash of raw input for evidence tracking\n analysis.file_hash = hashlib.sha256(raw_headers.encode()).hexdigest()\n\n # Parse using Python's email library\n parser = HeaderParser()\n msg = parser.parsestr(raw_headers)\n\n # Extract basic fields\n analysis.from_address = msg.get(\"From\", \"\")\n analysis.from_domain = extract_domain(analysis.from_address)\n analysis.return_path = msg.get(\"Return-Path\", \"\")\n analysis.return_path_domain = extract_domain(analysis.return_path)\n analysis.reply_to = msg.get(\"Reply-To\", \"\")\n analysis.reply_to_domain = extract_domain(analysis.reply_to)\n analysis.message_id = msg.get(\"Message-ID\", \"\")\n analysis.subject = msg.get(\"Subject\", \"\")\n analysis.date = msg.get(\"Date\", \"\")\n analysis.x_mailer = msg.get(\"X-Mailer\", \"\") or msg.get(\"User-Agent\", \"\")\n\n # Extract X-Originating-IP\n x_orig = msg.get(\"X-Originating-IP\", \"\")\n if x_orig:\n ip_match = re.search(r'(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})', x_orig)\n if ip_match:\n analysis.x_originating_ip = ip_match.group(1)\n\n # Parse Received headers (they appear in reverse order)\n received_headers = msg.get_all(\"Received\", [])\n for i, received in enumerate(received_headers):\n hop = parse_received_header(received, len(received_headers) - i)\n if enrich and hop.ip_address:\n hop.geo_location = geolocate_ip(hop.ip_address)\n hop.reverse_dns = reverse_dns_lookup(hop.ip_address)\n analysis.received_hops.append(hop)\n\n # Reverse to chronological order (first hop first)\n analysis.received_hops.reverse()\n\n # Parse Authentication-Results\n auth_results = msg.get(\"Authentication-Results\", \"\")\n if auth_results:\n analysis.authentication = parse_authentication_results(auth_results)\n\n # Also check ARC-Authentication-Results\n arc_auth = msg.get(\"ARC-Authentication-Results\", \"\")\n if arc_auth and analysis.authentication.spf == \"none\":\n analysis.authentication = parse_authentication_results(arc_auth)\n\n # Extract URLs from headers\n url_pattern = r'https?://[^\\s\u003c>\"\\')\\]>]+'\n all_header_text = raw_headers\n analysis.urls_in_headers = list(set(re.findall(url_pattern, all_header_text)))\n\n # Detect phishing indicators\n analysis.indicators = analyze_indicators(analysis)\n\n # Calculate risk score\n analysis.risk_score, analysis.risk_level = calculate_risk_score(analysis.indicators)\n\n # Enrich with threat intelligence if requested\n if enrich and analysis.x_originating_ip and abuseipdb_key:\n abuse_data = check_abuseipdb(analysis.x_originating_ip, abuseipdb_key)\n if abuse_data and abuse_data.get(\"abuseConfidenceScore\", 0) > 50:\n analysis.indicators.append(PhishingIndicator(\n category=\"threat_intelligence\",\n description=f\"IP {analysis.x_originating_ip} has abuse confidence \"\n f\"score of {abuse_data['abuseConfidenceScore']}%\",\n severity=\"critical\",\n raw_value=json.dumps(abuse_data)\n ))\n # Recalculate risk\n analysis.risk_score, analysis.risk_level = calculate_risk_score(analysis.indicators)\n\n return analysis\n\n\ndef format_report(analysis: HeaderAnalysis) -> str:\n \"\"\"Format analysis results as a human-readable report.\"\"\"\n lines = []\n lines.append(\"=\" * 70)\n lines.append(\" PHISHING EMAIL HEADER ANALYSIS REPORT\")\n lines.append(\"=\" * 70)\n lines.append(f\" Generated: {datetime.now(timezone.utc).isoformat()}\")\n lines.append(f\" Evidence Hash: {analysis.file_hash[:16]}...\")\n lines.append(\"\")\n\n # Risk Assessment\n lines.append(f\" RISK LEVEL: {analysis.risk_level} (Score: {analysis.risk_score}/100)\")\n lines.append(\"-\" * 70)\n\n # Sender Information\n lines.append(\"\\n[SENDER INFORMATION]\")\n lines.append(f\" From: {analysis.from_address}\")\n lines.append(f\" Return-Path: {analysis.return_path}\")\n lines.append(f\" Reply-To: {analysis.reply_to}\")\n lines.append(f\" Subject: {analysis.subject}\")\n lines.append(f\" Date: {analysis.date}\")\n lines.append(f\" Message-ID: {analysis.message_id}\")\n lines.append(f\" X-Mailer: {analysis.x_mailer}\")\n if analysis.x_originating_ip:\n lines.append(f\" Origin IP: {analysis.x_originating_ip}\")\n\n # Authentication Results\n lines.append(\"\\n[AUTHENTICATION RESULTS]\")\n auth = analysis.authentication\n spf_icon = \"PASS\" if auth.spf == \"pass\" else \"FAIL\" if auth.spf in (\"fail\", \"softfail\") else \"NONE\"\n dkim_icon = \"PASS\" if auth.dkim == \"pass\" else \"FAIL\" if auth.dkim == \"fail\" else \"NONE\"\n dmarc_icon = \"PASS\" if auth.dmarc == \"pass\" else \"FAIL\" if auth.dmarc == \"fail\" else \"NONE\"\n lines.append(f\" SPF: {spf_icon} ({auth.spf}) domain={auth.spf_domain}\")\n lines.append(f\" DKIM: {dkim_icon} ({auth.dkim}) domain={auth.dkim_domain}\")\n lines.append(f\" DMARC: {dmarc_icon} ({auth.dmarc}) domain={auth.dmarc_domain}\")\n\n # Routing Path\n lines.append(f\"\\n[ROUTING PATH] ({len(analysis.received_hops)} hops)\")\n for hop in analysis.received_hops:\n lines.append(f\" Hop {hop.hop_number}: {hop.server_from} -> {hop.server_by}\")\n if hop.ip_address:\n lines.append(f\" IP: {hop.ip_address}\")\n if hop.geo_location and hop.geo_location != \"unknown\":\n lines.append(f\" Location: {hop.geo_location}\")\n if hop.protocol:\n lines.append(f\" Protocol: {hop.protocol}\")\n if hop.timestamp:\n lines.append(f\" Time: {hop.timestamp}\")\n\n # Phishing Indicators\n if analysis.indicators:\n lines.append(f\"\\n[PHISHING INDICATORS] ({len(analysis.indicators)} found)\")\n for i, ind in enumerate(analysis.indicators, 1):\n lines.append(f\" {i}. [{ind.severity.upper()}] {ind.description}\")\n if ind.raw_value:\n lines.append(f\" Value: {ind.raw_value}\")\n else:\n lines.append(\"\\n[PHISHING INDICATORS] None detected\")\n\n # URLs in Headers\n if analysis.urls_in_headers:\n lines.append(f\"\\n[URLS IN HEADERS] ({len(analysis.urls_in_headers)} found)\")\n for url in analysis.urls_in_headers[:10]:\n lines.append(f\" - {url}\")\n\n lines.append(\"\\n\" + \"=\" * 70)\n lines.append(\" END OF REPORT\")\n lines.append(\"=\" * 70)\n\n return \"\\n\".join(lines)\n\n\ndef main():\n parser = argparse.ArgumentParser(\n description=\"Analyze email headers for phishing indicators\"\n )\n input_group = parser.add_mutually_exclusive_group(required=True)\n input_group.add_argument(\"--file\", \"-f\", help=\"Path to file containing raw headers\")\n input_group.add_argument(\"--eml\", \"-e\", help=\"Path to .eml file\")\n input_group.add_argument(\"--stdin\", action=\"store_true\", help=\"Read headers from stdin\")\n\n parser.add_argument(\"--enrich\", action=\"store_true\",\n help=\"Enrich with IP geolocation and reverse DNS\")\n parser.add_argument(\"--abuseipdb-key\", default=\"\",\n help=\"AbuseIPDB API key for threat intelligence\")\n parser.add_argument(\"--json\", action=\"store_true\",\n help=\"Output results as JSON\")\n parser.add_argument(\"--output\", \"-o\", help=\"Write report to file\")\n\n args = parser.parse_args()\n\n # Read input\n if args.stdin:\n raw_headers = sys.stdin.read()\n elif args.eml:\n with open(args.eml, \"rb\") as f:\n msg = BytesParser(policy=policy.default).parse(f)\n raw_headers = str(msg)\n else:\n with open(args.file, \"r\", encoding=\"utf-8\", errors=\"replace\") as f:\n raw_headers = f.read()\n\n # Analyze\n analysis = analyze_headers(\n raw_headers,\n enrich=args.enrich,\n abuseipdb_key=args.abuseipdb_key\n )\n\n # Output\n if args.json:\n output = json.dumps(asdict(analysis), indent=2, default=str)\n else:\n output = format_report(analysis)\n\n if args.output:\n with open(args.output, \"w\", encoding=\"utf-8\") as f:\n f.write(output)\n print(f\"Report written to {args.output}\")\n else:\n print(output)\n\n # Exit code based on risk\n if analysis.risk_level in (\"CRITICAL\", \"HIGH\"):\n sys.exit(2)\n elif analysis.risk_level == \"MEDIUM\":\n sys.exit(1)\n else:\n sys.exit(0)\n\n\nif __name__ == \"__main__\":\n main()\n","content_type":"text/x-python; charset=utf-8","language":"python","size":20358,"content_sha256":"6fa0ccb19e26ab52d118f1b85c44ea7d0cdc0c10add196313b5d0d7c16166180"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Analyzing Phishing Email Headers","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Overview","type":"text"}]},{"type":"paragraph","content":[{"text":"Email headers contain critical metadata that reveals the true origin, routing path, and authentication status of emails. Analyzing these headers is a foundational skill for identifying phishing attempts, verifying sender authenticity, and gathering threat intelligence. This skill covers systematic extraction and interpretation of email headers using both manual techniques and automated tools.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Prerequisites","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Basic understanding of SMTP protocol and email delivery","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Familiarity with DNS records (MX, TXT, SPF, DKIM, DMARC)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Python 3.8+ installed","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Access to email client that can export raw headers (Outlook, Gmail, Thunderbird)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Key Concepts","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Critical Header Fields","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Received","type":"text","marks":[{"type":"strong"}]},{"text":": Chain of mail servers the message passed through (read bottom to top)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"From / Return-Path / Reply-To","type":"text","marks":[{"type":"strong"}]},{"text":": Sender identity fields (often spoofed)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Authentication-Results","type":"text","marks":[{"type":"strong"}]},{"text":": SPF, DKIM, DMARC verification outcomes","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"X-Originating-IP","type":"text","marks":[{"type":"strong"}]},{"text":": Original sender IP address","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Message-ID","type":"text","marks":[{"type":"strong"}]},{"text":": Unique identifier; anomalies indicate spoofing","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"X-Mailer / User-Agent","type":"text","marks":[{"type":"strong"}]},{"text":": Email client used to compose the message","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Red Flags in Headers","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Mismatched ","type":"text"},{"text":"From","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"Return-Path","type":"text","marks":[{"type":"code_inline"}]},{"text":" domains","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"SPF/DKIM/DMARC failures in ","type":"text"},{"text":"Authentication-Results","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Suspicious ","type":"text"},{"text":"Received","type":"text","marks":[{"type":"code_inline"}]},{"text":" chains with unfamiliar relay servers","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"X-Originating-IP","type":"text","marks":[{"type":"code_inline"}]},{"text":" from unexpected geographies","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Missing or malformed ","type":"text"},{"text":"Message-ID","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Unusual ","type":"text"},{"text":"X-Mailer","type":"text","marks":[{"type":"code_inline"}]},{"text":" values (e.g., mass-mailing tools)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Implementation Steps","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 1: Extract Raw Email Headers","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"Gmail: Open email -> Three dots -> \"Show original\"\nOutlook: Open email -> File -> Properties -> Internet Headers\nThunderbird: View -> Message Source (Ctrl+U)","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 2: Parse Headers with Python","type":"text"}]},{"type":"paragraph","content":[{"text":"Use the ","type":"text"},{"text":"scripts/process.py","type":"text","marks":[{"type":"code_inline"}]},{"text":" script to automate header analysis including IP geolocation, authentication validation, and anomaly detection.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 3: Validate Authentication Chain","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Check SPF alignment: Does the sending IP match the domain's SPF record?","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Check DKIM signature: Is the cryptographic signature valid?","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Check DMARC policy: Does the message pass DMARC alignment?","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 4: Trace Mail Route","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Read ","type":"text"},{"text":"Received","type":"text","marks":[{"type":"code_inline"}]},{"text":" headers from bottom to top","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Map each hop's IP to organization/location","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Identify unexpected relays or delays","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 5: Correlate with Threat Intelligence","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Look up originating IP on AbuseIPDB, VirusTotal","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Check sending domain age on WHOIS","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Search for known phishing infrastructure patterns","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Tools & Resources","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"MXToolbox Header Analyzer","type":"text","marks":[{"type":"strong"}]},{"text":": https://mxtoolbox.com/EmailHeaders.aspx","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Google Admin Toolbox","type":"text","marks":[{"type":"strong"}]},{"text":": https://toolbox.googleapps.com/apps/messageheader/","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"AbuseIPDB","type":"text","marks":[{"type":"strong"}]},{"text":": https://www.abuseipdb.com/","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"VirusTotal","type":"text","marks":[{"type":"strong"}]},{"text":": https://www.virustotal.com/","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"PhishTank","type":"text","marks":[{"type":"strong"}]},{"text":": https://phishtank.org/","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Validation","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Successfully parse headers from 3 different email providers","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Correctly identify authentication pass/fail status","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Accurately trace email routing path","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Detect at least 3 phishing indicators in a sample phishing email","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"analyzing-phishing-email-headers","tags":["phishing","email-security","social-engineering","dmarc","awareness","header-analysis","forensics"],"author":"@skillopedia","domain":"cybersecurity","source":{"stars":5,"repo_name":"community-skills","origin_url":"https://github.com/autohandai/community-skills/blob/HEAD/analyzing-phishing-email-headers/SKILL.md","repo_owner":"autohandai","body_sha256":"538cdfcbc3409ec315bb27c06dc009c8da714c5e51bc855f700a942d7dc2193f","cluster_key":"3946284c727427fd2d485961d5395e9b7f44fea1c55fd8de798754975e9bf3ad","clean_bundle":{"format":"clean-skill-bundle-v1","source":"autohandai/community-skills/analyzing-phishing-email-headers/SKILL.md","attachments":[{"id":"bf2832fd-409b-50b6-92dc-df99fd484d3d","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/bf2832fd-409b-50b6-92dc-df99fd484d3d/attachment.md","path":"assets/template.md","size":1955,"sha256":"2fa1663034d17efa5ca58a254c4749220e8abf1b5ca3386fd9c12bd0ee43a6d1","contentType":"text/markdown; charset=utf-8"},{"id":"00f351ad-19eb-5bb9-a364-639cf8be4794","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/00f351ad-19eb-5bb9-a364-639cf8be4794/attachment.md","path":"references/api-reference.md","size":2554,"sha256":"a9be80d881e3d7291d04a446cdf3c849b78531d6517703cf1b38b61077dfe8e0","contentType":"text/markdown; charset=utf-8"},{"id":"0d924556-201b-5c4c-b1e8-fa7ee0743552","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/0d924556-201b-5c4c-b1e8-fa7ee0743552/attachment.md","path":"references/standards.md","size":2223,"sha256":"20d9c74f263a62adb398385e27c6bbb67177be5dc2177c983d177c3afe8c4ab9","contentType":"text/markdown; charset=utf-8"},{"id":"039a11af-5ff6-5b88-85f0-6887462f44ef","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/039a11af-5ff6-5b88-85f0-6887462f44ef/attachment.md","path":"references/workflows.md","size":2791,"sha256":"224869487fb2714b80ecc0f7aa170ba16e2948bdfd6a7e020e020cd13473caea","contentType":"text/markdown; charset=utf-8"},{"id":"2700b704-63ad-5a6f-b137-0ff5c3819f90","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/2700b704-63ad-5a6f-b137-0ff5c3819f90/attachment.py","path":"scripts/agent.py","size":7482,"sha256":"4a236313e45d36b806950e38f2ce2c05d30fadd5163fa14d31290857e02e8f2a","contentType":"text/x-python; charset=utf-8"},{"id":"2165497d-d93b-516d-9c7f-5b47ba116223","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/2165497d-d93b-516d-9c7f-5b47ba116223/attachment.py","path":"scripts/process.py","size":20358,"sha256":"6fa0ccb19e26ab52d118f1b85c44ea7d0cdc0c10add196313b5d0d7c16166180","contentType":"text/x-python; charset=utf-8"}],"bundle_sha256":"53fa1c40af85a5721fadfbde8874f21884b805f6c05f126ac22974bb4615d3b7","attachment_count":6,"text_attachments":6,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"analyzing-phishing-email-headers/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"security","category_label":"Security"},"exact_dupes_collapsed_into_this":0},"license":"Apache-2.0","version":"v1","category":"security","subdomain":"phishing-defense","import_tag":"clean-skills-v1","description":"Email headers contain critical metadata that reveals the true origin, routing path, and authentication status of emails. Analyzing these headers is a foundational skill for identifying phishing attemp"}},"renderedAt":1782987840650}

Analyzing Phishing Email Headers Overview Email headers contain critical metadata that reveals the true origin, routing path, and authentication status of emails. Analyzing these headers is a foundational skill for identifying phishing attempts, verifying sender authenticity, and gathering threat intelligence. This skill covers systematic extraction and interpretation of email headers using both manual techniques and automated tools. Prerequisites - Basic understanding of SMTP protocol and email delivery - Familiarity with DNS records (MX, TXT, SPF, DKIM, DMARC) - Python 3.8+ installed - Acce…