Analyse von E-Mail-Headern für Phishing-Untersuchungen
Verwendungszweck
- Bei der Untersuchung einer vermuteten Phishing-E-Mail, um deren wahre Herkunft zu ermitteln
- Zur Überprüfung der Absenderauthentizität und Erkennung von E-Mail-Spoofing
- Während der Incident Response, wenn ein Benutzer auf einen Phishing-Link geklickt hat
- Zum Nachverfolgen des Zustellungswegs und der Relay-Server einer verdächtigen E-Mail
- Zur Validierung von SPF-, DKIM- und DMARC-Ausrichtung zur Identifizierung von Fälschungen
Voraussetzungen
- Rohe E-Mail-Header der verdächtigen Nachricht (EML- oder MSG-Format)
- Verständnis des SMTP-Protokolls und der E-Mail-Header-Felder
- Zugriff auf DNS-Abfragetools (dig, nslookup) für SPF/DKIM/DMARC-Überprüfung
- E-Mail-Header-Analysetools (MHA, emailheaders.net-Konzepte)
- Python mit E-Mail-Parsing-Bibliotheken für automatisierte Analyse
- Zugang zu Threat-Intelligence-Plattformen für IP-/Domain-Reputation
Arbeitsablauf
Schritt 1: Rohe E-Mail-Header extrahieren
# Export aus Outlook: E-Mail öffnen > Datei > Eigenschaften > Internet-Header
# Export aus Gmail: E-Mail öffnen > Drei Punkte > Original anzeigen
# Export aus Thunderbird: Ansicht > Nachrichtenquelltext
# Bei Arbeit mit EML-Datei aus forensischem Abbild
cp /mnt/evidence/Users/suspect/AppData/Local/Microsoft/Outlook/phishing_email.eml \
/cases/case-2024-001/email/
# Bei Arbeit mit PST-Datei einzelne Nachrichten extrahieren
pip install pypff
python3 << 'PYEOF'
import pypff
pst = pypff.file()
pst.open("/cases/case-2024-001/email/outlook.pst")
root = pst.get_root_folder()
def extract_messages(folder, path=""):
for i in range(folder.get_number_of_sub_messages()):
msg = folder.get_sub_message(i)
headers = msg.get_transport_headers()
subject = msg.get_subject()
if headers:
filename = f"/cases/case-2024-001/email/msg_{i}_{subject[:30]}.txt"
with open(filename, 'w') as f:
f.write(headers)
for i in range(folder.get_number_of_sub_folders()):
extract_messages(folder.get_sub_folder(i))
extract_messages(root)
PYEOF
Schritt 2: Die E-Mail-Header-Kette parsen
# Header mit der Python email-Bibliothek parsen
python3 << 'PYEOF'
import email
from email import policy
with open('/cases/case-2024-001/email/phishing_email.eml', 'r') as f:
msg = email.message_from_file(f, policy=policy.default)
print("=== WICHTIGE HEADER-FELDER ===")
print(f"From: {msg['From']}")
print(f"To: {msg['To']}")
print(f"Subject: {msg['Subject']}")
print(f"Date: {msg['Date']}")
print(f"Message-ID: {msg['Message-ID']}")
print(f"Reply-To: {msg['Reply-To']}")
print(f"Return-Path: {msg['Return-Path']}")
print(f"X-Mailer: {msg['X-Mailer']}")
print(f"X-Originating-IP: {msg['X-Originating-IP']}")
print("\n=== EMPFANGENE HEADER (von unten nach oben = chronologisch) ===")
received_headers = msg.get_all('Received')
if received_headers:
for i, header in enumerate(reversed(received_headers)):
print(f"\nHop {i+1}: {header.strip()}")
print("\n=== AUTHENTIFIZIERUNGSERGEBNISSE ===")
auth_results = msg.get_all('Authentication-Results')
if auth_results:
for result in auth_results:
print(result)
print(f"\nARC-Authentication-Results: {msg.get('ARC-Authentication-Results', 'Nicht vorhanden')}")
print(f"Received-SPF: {msg.get('Received-SPF', 'Nicht vorhanden')}")
print(f"DKIM-Signature: {msg.get('DKIM-Signature', 'Nicht vorhanden')}")
PYEOF
Schritt 3: SPF-, DKIM- und DMARC-Einträge validieren
# Die Domäne des Umschlagabsenders extrahieren
SENDER_DOMAIN="example-corp.com"
# SPF-Eintrag prüfen
dig TXT $SENDER_DOMAIN +short | grep "v=spf1"
# Beispiel: "v=spf1 include:_spf.google.com include:sendgrid.net ~all"
# DKIM-Eintrag prüfen (Selector aus DKIM-Signature-Header, z.B. "s=selector1")
DKIM_SELECTOR="selector1"
dig TXT ${DKIM_SELECTOR}._domainkey.${SENDER_DOMAIN} +short
# DMARC-Eintrag prüfen
dig TXT _dmarc.${SENDER_DOMAIN} +short
# Beispiel: "v=DMARC1; p=reject; rua=mailto:[email protected]; pct=100"
# Die sendende IP gegen SPF prüfen
# IP aus dem ersten Received-Header extrahieren
SENDING_IP="203.0.113.45"
# Manuelle SPF-Prüfung mit Python
python3 << 'PYEOF'
import spf # pip install pyspf
result, explanation = spf.check2(
i='203.0.113.45',
s='[email protected]',
h='mail.example-corp.com'
)
print(f"SPF-Ergebnis: {result}")
print(f"Erläuterung: {explanation}")
# Ergebnisse: pass, fail, softfail, neutral, none, temperror, permerror
PYEOF
# Prüfen, ob die sendende IP in bekannten schädlichen IP-Listen vorkommt
# AbuseIPDB oder VirusTotal abfragen
curl -s "https://api.abuseipdb.com/api/v2/check?ipAddress=${SENDING_IP}" \
-H "Key: YOUR_API_KEY" -H "Accept: application/json" | python3 -m json.tool
Schritt 4: Absender-Domäne und -Infrastruktur analysieren
# WHOIS-Abfrage der Absender-Domäne
whois $SENDER_DOMAIN | grep -iE '(registrar|creation|expiration|registrant|nameserver)'
# Domain-Alter prüfen (kürzlich registrierte Domänen sind verdächtig)
# DNS-Records untersuchen
dig A $SENDER_DOMAIN +short
dig MX $SENDER_DOMAIN +short
dig NS $SENDER_DOMAIN +short
# Reverse-DNS der sendenden IP
dig -x $SENDING_IP +short
# Auf ähnlich aussehende Domänen (Typosquatting) prüfen
# Vergleich mit der legitimen Domäne mittels visueller Ähnlichkeit
python3 << 'PYEOF'
import Levenshtein # pip install python-Levenshtein
legitimate = "microsoft.com"
suspicious = "micr0soft.com"
distance = Levenshtein.distance(legitimate, suspicious)
ratio = Levenshtein.ratio(legitimate, suspicious)
print(f"Editierdistanz: {distance}")
print(f"Ähnlichkeitsverhältnis: {ratio:.2%}")
if ratio > 0.8:
print("WARNUNG: Wahrscheinlich Typosquatting/ähnlich aussehende Domäne!")
PYEOF
# Domain-Reputation auf VirusTotal prüfen
curl -s "https://www.virustotal.com/api/v3/domains/${SENDER_DOMAIN}" \
-H "x-apikey: YOUR_VT_API_KEY" | python3 -m json.tool
# Prüfen, ob Reply-To von From abweicht (häufiger Phishing-Indikator)
python3 -c "
import email
with open('/cases/case-2024-001/email/phishing_email.eml') as f:
msg = email.message_from_file(f)
from_addr = email.utils.parseaddr(msg['From'])[1]
reply_to = email.utils.parseaddr(msg.get('Reply-To', msg['From']))[1]
if from_addr != reply_to:
print(f'WARNUNG: From ({from_addr}) != Reply-To ({reply_to})')
else:
print('From und Reply-To stimmen überein')
"
Schritt 5: E-Mail-Textkörper und Anhänge untersuchen
# URLs aus dem E-Mail-Textkörper extrahieren
python3 << 'PYEOF'
import email
import re
from email import policy
with open('/cases/case-2024-001/email/phishing_email.eml', 'r') as f:
msg = email.message_from_file(f, policy=policy.default)
body = msg.get_body(preferencelist=('html', 'plain'))
if body:
content = body.get_content()
urls = re.findall(r'https?://[^\s<>"\']+', content)
print("=== IM E-MAIL-TEXTKÖRPER GEFUNDENE URLs ===")
for url in set(urls):
print(f" {url}")
# Auf URL-Verschleierung prüfen (angezeigter Text != href)
href_pattern = re.findall(r'<a[^>]*href=["\']([^"\']+)["\'][^>]*>(.*?)</a>', content, re.DOTALL)
print("\n=== HYPERLINK-ANALYSE ===")
for href, text in href_pattern:
display_url = re.findall(r'https?://[^\s<]+', text)
if display_url and display_url[0] != href:
print(f" UNSTIMMIGKEIT: Angezeigt='{display_url[0]}' -> Tatsächlich='{href}'")
# Anhänge extrahieren und hashen
print("\n=== ANHÄNGE ===")
for part in msg.walk():
if part.get_content_disposition() == 'attachment':
filename = part.get_filename()
content = part.get_payload(decode=True)
import hashlib
sha256 = hashlib.sha256(content).hexdigest()
print(f" Datei: {filename}, Größe: {len(content)}, SHA-256: {sha256}")
with open(f'/cases/case-2024-001/email/attachments/{filename}', 'wb') as af:
af.write(content)
PYEOF
# Anhang-Hashes an VirusTotal übermitteln
# URLs an URLhaus oder PhishTank zur Reputationsprüfung übermitteln
Wichtige Konzepte
| Konzept | Beschreibung |
|---|---|
| SPF (Sender Policy Framework) | DNS-Eintrag, der autorisierte Mail-Server für eine Domäne festlegt |
| DKIM (DomainKeys Identified Mail) | Kryptografische Signatur, die die Integrität des E-Mail-Inhalts überprüft |
| DMARC | Richtlinien-Framework, das SPF und DKIM zur Absenderauthentifizierung kombiniert |
| Received-Header | Vom Server hinzugefügte Header, die jeden Hop in der Zustellungskette anzeigen (von unten nach oben lesen) |
| Return-Path | Umschlag-Absenderadresse für Bounce-Nachrichten; kann von From abweichen |
| Message-ID | Eindeutige Kennung, die vom sendenden Mail-Server vergeben wird |
| X-Originating-IP | Ursprüngliche Absender-IP-Adresse (von einigen Mail-Diensten hinzugefügt) |
| Header-Fälschung | Angreifer können From-, Reply-To- und andere Header fälschen, nicht jedoch Received-Ketten |
Tools und Systeme
| Tool | Zweck |
|---|---|
| MXToolbox | Online-E-Mail-Header-Analyzer und DNS-Abfrage |
| dig/nslookup | DNS-Eintragsabfragen für SPF-, DKIM- und DMARC-Überprüfung |
| pyspf | Python-Bibliothek zur SPF-Eintragsvalidierung |
| dkimpy | Python-Bibliothek zur DKIM-Signaturverifikation |
| PhishTool | Spezialisierte Plattform zur Phishing-E-Mail-Analyse |
| VirusTotal | Dienst zur Reputationsprüfung von URLs und Dateien |
| AbuseIPDB | IP-Adress-Reputationsdatenbank |
| whois | Abfrage von Domain-Registrierungsinformationen |
Häufige Szenarien
Szenario 1: CEO-Betrug / Business E-Mail Compromise Die E-Mail gibt vor, vom CEO zu stammen, aber Reply-To zeigt auf eine Gmail-Adresse, SPF schlägt fehl, da die sendende IP nicht für die gefälschte Domäne autorisiert ist, DKIM fehlt, und die From-Domäne ist eine ähnlich aussehende (ceo-company.com vs. company.com).
Szenario 2: Phishing zur Anmeldedaten-Erfassung Die E-Mail enthält einen Link, der „login.microsoft.com“ anzeigt, dessen href jedoch auf eine ähnlich aussehende Domäne zeigt; der Anhang ist eine HTML-Datei mit einer gefälschten Login-Seite und JavaScript zum Diebstahl von Anmeldedaten; die sendende Domäne wurde vor 3 Tagen registriert.
Szenario 3: Schadsoftware-Verteilung per Anhang E-Mail mit einem Office-Dokument-Anhang, der Makros enthält; die Absender-Domäne besteht den SPF-Check, aber das Konto wurde kompromittiert; die DKIM-Signatur ist gültig (von legitimer Infrastruktur gesendet); der SHA-256-Hash des Anhangs entspricht bekannter Schadsoftware auf VirusTotal.
Szenario 4: Gezieltes Phishing (Spear Phishing) mit legitimen Dienstleister Der Angreifer verwendet einen legitimen E-Mail-Marketing-Dienst zum Versenden von Phishing; SPF und DKIM bestehen, da der Dienst autorisiert ist; der Phishing-Versuch liegt im Inhalt, nicht in der Infrastruktur; erfordert URL- und Inhaltsanalyse statt Header-Authentifizierungsprüfungen.
Ausgabeformat
E-Mail-Header-Analysebericht:
Betreff: "Dringend: Zahlungsaufforderung"
From: [email protected] (GEFÄLSCHT)
Reply-To: [email protected] (UNSTIMMIG)
Return-Path: <[email protected]>
Datum: 2024-01-15 09:23:45 UTC
Zustellungsweg (4 Hops):
Hop 1: mail-server.xyz [203.0.113.45] -> relay1.isp.com
Hop 2: relay1.isp.com -> mx.target-company.com
Hop 3: mx.target-company.com -> internal-filter.target.com
Hop 4: internal-filter.target.com -> mailbox
Authentifizierung:
SPF: FEHLGESCHLAGEN (203.0.113.45 nicht autorisiert für examp1e-corp.com)
DKIM: KEINE (keine Signatur vorhanden)
DMARC: FEHLGESCHLAGEN (p=none, keine Durchsetzung)
Phishing-Indikatoren:
- Ähnlich aussehende Domäne (examp1e-corp.com vs. example-corp.com, 96% ähnlich)
- From/Reply-To-Unstimmigkeit
- Domäne 2 Tage vor E-Mail-Versand registriert
- URL im Textkörper zeigt auf Seite zur Anmeldedaten-Erfassung
- Anhang: invoice.xlsm (SHA-256: a3f2...) - Bekannte Schadsoftware auf VT
Risikostufe: HOCH