Análise de Cabeçalhos de E-mail para Investigação de Phishing
Quando Usar
- Ao investigar um e-mail suspeito de phishing para determinar sua verdadeira origem
- Para verificar a autenticidade do remetente e detectar falsificação de e-mail (spoofing)
- Durante a resposta a incidentes quando um usuário clicou em um link de phishing
- Ao rastrear o caminho de entrega e os servidores de retransmissão de um e-mail suspeito
- Para validar o alinhamento SPF, DKIM e DMARC e identificar falsificações
Pré-requisitos
- Cabeçalhos de e-mail brutos da mensagem suspeita (formato EML ou MSG)
- Compreensão do protocolo SMTP e dos campos de cabeçalho de e-mail
- Acesso a ferramentas de consulta DNS (dig, nslookup) para verificação SPF/DKIM/DMARC
- Ferramentas de análise de cabeçalhos de e-mail (conceitos de MHA, emailheaders.net)
- Python com bibliotecas de análise de e-mail para automação
- Acesso a plataformas de inteligência de ameaças para reputação de IP/domínio
Fluxo de Trabalho
Etapa 1: Extrair Cabeçalhos de E-mail Brutos
# Exportar do Outlook: Abrir e-mail > Arquivo > Propriedades > Cabeçalhos da Internet
# Exportar do Gmail: Abrir e-mail > Três pontos > Mostrar original
# Exportar do Thunderbird: Exibir > Código-fonte da mensagem
# Se estiver trabalhando com arquivo EML de imagem forense
cp /mnt/evidence/Users/suspect/AppData/Local/Microsoft/Outlook/phishing_email.eml \
/cases/case-2024-001/email/
# Se estiver trabalhando com arquivo PST, extraia mensagens individuais
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
Etapa 2: Analisar a Cadeia de Cabeçalhos do E-mail
# Analisar cabeçalhos usando a biblioteca email do Python
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("=== CAMPOS DE CABEÇALHO PRINCIPAIS ===")
print(f"De: {msg['From']}")
print(f"Para: {msg['To']}")
print(f"Assunto: {msg['Subject']}")
print(f"Data: {msg['Date']}")
print(f"Message-ID: {msg['Message-ID']}")
print(f"Responder-Para: {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=== CABEÇALHOS RECEIVED (de baixo para cima = ordem cronológica) ===")
received_headers = msg.get_all('Received')
if received_headers:
for i, header in enumerate(reversed(received_headers)):
print(f"\nSalto {i+1}: {header.strip()}")
print("\n=== RESULTADOS DE AUTENTICAÇÃO ===")
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', 'Não presente')}")
print(f"Received-SPF: {msg.get('Received-SPF', 'Não presente')}")
print(f"DKIM-Signature: {msg.get('DKIM-Signature', 'Não presente')}")
PYEOF
Etapa 3: Validar Registros SPF, DKIM e DMARC
# Extrair o domínio do envelope do remetente
SENDER_DOMAIN="example-corp.com"
# Verificar registro SPF
dig TXT $SENDER_DOMAIN +short | grep "v=spf1"
# Exemplo: "v=spf1 include:_spf.google.com include:sendgrid.net ~all"
# Verificar registro DKIM (seletor do cabeçalho DKIM-Signature, ex: "s=selector1")
DKIM_SELECTOR="selector1"
dig TXT ${DKIM_SELECTOR}._domainkey.${SENDER_DOMAIN} +short
# Verificar registro DMARC
dig TXT _dmarc.${SENDER_DOMAIN} +short
# Exemplo: "v=DMARC1; p=reject; rua=mailto:[email protected]; pct=100"
# Verificar o IP de envio contra o SPF
# Extrair IP do primeiro cabeçalho Received
SENDING_IP="203.0.113.45"
# Verificação manual de SPF usando 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"Resultado SPF: {result}")
print(f"Explicação: {explanation}")
# Resultados: pass, fail, softfail, neutral, none, temperror, permerror
PYEOF
# Verificar se o IP de envio está em listas de IPs maliciosos conhecidos
# Consultar AbuseIPDB ou VirusTotal
curl -s "https://api.abuseipdb.com/api/v2/check?ipAddress=${SENDING_IP}" \
-H "Key: SUA_CHAVE_API" -H "Accept: application/json" | python3 -m json.tool
Etapa 4: Analisar o Domínio do Remetente e a Infraestrutura
# Consulta WHOIS no domínio do remetente
whois $SENDER_DOMAIN | grep -iE '(registrar|creation|expiration|registrant|nameserver)'
# Verificar idade do domínio (domínios registrados recentemente são suspeitos)
# Investigação de registros DNS
dig A $SENDER_DOMAIN +short
dig MX $SENDER_DOMAIN +short
dig NS $SENDER_DOMAIN +short
# DNS reverso no IP de envio
dig -x $SENDING_IP +short
# Verificar domínios de aparência semelhante (typosquatting)
# Comparar com domínio legítimo usando similaridade visual
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"Distância de edição: {distance}")
print(f"Taxa de similaridade: {ratio:.2%}")
if ratio > 0.8:
print("AVISO: Provável domínio typosquatting/de aparência semelhante!")
PYEOF
# Verificar reputação do domínio no VirusTotal
curl -s "https://www.virustotal.com/api/v3/domains/${SENDER_DOMAIN}" \
-H "x-apikey: SUA_CHAVE_API_VT" | python3 -m json.tool
# Verificar se o Reply-To difere do From (indicador comum de phishing)
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'AVISO: From ({from_addr}) != Reply-To ({reply_to})')
else:
print('From e Reply-To coincidem')
"
Etapa 5: Examinar o Corpo do E-mail e Anexos
# Extrair URLs do corpo do e-mail
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("=== URLs ENCONTRADAS NO CORPO DO E-MAIL ===")
for url in set(urls):
print(f" {url}")
# Verificar ofuscação de URL (texto exibido != href)
href_pattern = re.findall(r'<a[^>]*href=[\"\']([^\"\']+)[\"\'][^>]*>(.*?)</a>', content, re.DOTALL)
print("\n=== ANÁLISE DE HYPERLINKS ===")
for href, text in href_pattern:
display_url = re.findall(r'https?://[^\s<]+', text)
if display_url and display_url[0] != href:
print(f" INCONSISTÊNCIA: Exibido='{display_url[0]}' -> Real='{href}'")
# Extrair e hashear anexos
print("\n=== ANEXOS ===")
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" Arquivo: {filename}, Tamanho: {len(content)}, SHA-256: {sha256}")
with open(f'/cases/case-2024-001/email/attachments/{filename}', 'wb') as af:
af.write(content)
PYEOF
# Enviar hashes de anexos ao VirusTotal
# Enviar URLs ao URLhaus ou PhishTank para verificação de reputação
Conceitos-chave
| Conceito | Descrição |
|---|---|
| SPF (Sender Policy Framework) | Registro DNS que especifica servidores de e-mail autorizados para um domínio |
| DKIM (DomainKeys Identified Mail) | Assinatura criptográfica que verifica a integridade do conteúdo do e-mail |
| DMARC | Política que combina SPF e DKIM para autenticação do remetente |
| Cabeçalhos Received | Cabeçalhos adicionados por servidores mostrando cada salto na cadeia de entrega (leia de baixo para cima) |
| Return-Path | Endereço do remetente do envelope usado para mensagens de bounce; pode diferir do From |
| Message-ID | Identificador único atribuído pelo servidor de e-mail de origem |
| X-Originating-IP | Endereço IP original do remetente (adicionado por alguns serviços de e-mail) |
| Falsificação de cabeçalho | Atacantes podem forjar cabeçalhos From, Reply-To e outros, mas não as cadeias Received |
Ferramentas e Sistemas
| Ferramenta | Finalidade |
|---|---|
| MXToolbox | Analisador de cabeçalhos de e-mail online e consulta DNS |
| dig/nslookup | Consultas de registros DNS para verificação SPF, DKIM, DMARC |
| pyspf | Biblioteca Python para validação de registro SPF |
| dkimpy | Biblioteca Python para verificação de assinatura DKIM |
| PhishTool | Plataforma especializada em análise de e-mails de phishing |
| VirusTotal | Serviço de verificação de reputação de URLs e arquivos |
| AbuseIPDB | Banco de dados de reputação de endereços IP |
| whois | Consulta de informações de registro de domínio |
Cenários Comuns
Cenário 1: Fraude de CEO / Business Email Compromise O e-mail alega ser do CEO, mas o Reply-To aponta para um endereço do Gmail; o SPF falha porque o IP de envio não é autorizado para o domínio falsificado; o DKIM está ausente; o domínio From é de aparência semelhante (ceo-company.com vs company.com).
Cenário 2: Phishing para Roubo de Credenciais O e-mail contém um link que exibe "login.microsoft.com" mas o href aponta para um domínio de aparência semelhante; o anexo é um arquivo HTML contendo uma página de login falsa com JavaScript para exfiltração de credenciais; o domínio de envio foi registrado há 3 dias.
Cenário 3: Distribuição de Malware via Anexo E-mail com anexo de documento Office contendo macros; o domínio do remetente passa no SPF, mas a conta foi comprometida; a assinatura DKIM é válida (enviada de infraestrutura legítima); o SHA-256 do anexo corresponde a malware conhecido no VirusTotal.
Cenário 4: Spear Phishing com Serviço Legítimo O atacante usa um serviço de marketing por e-mail legítimo para enviar phishing; SPF e DKIM passam porque o serviço é autorizado; o phishing está no conteúdo, não na infraestrutura; requer análise de URL e conteúdo, em vez de verificações de autenticação de cabeçalho.
Formato de Saída
Relatório de Análise de Cabeçalhos de E-mail:
Assunto: "Urgente: Pagamento de Fatura Necessário"
De: [email protected] (FALSIFICADO)
Responder-Para: [email protected] (INCONSISTÊNCIA)
Return-Path: <[email protected]>
Data: 2024-01-15 09:23:45 UTC
Caminho de Entrega (4 saltos):
Salto 1: mail-server.xyz [203.0.113.45] -> relay1.isp.com
Salto 2: relay1.isp.com -> mx.target-company.com
Salto 3: mx.target-company.com -> internal-filter.target.com
Salto 4: internal-filter.target.com -> mailbox
Autenticação:
SPF: FALHA (203.0.113.45 não autorizado para examp1e-corp.com)
DKIM: NENHUM (nenhuma assinatura presente)
DMARC: FALHA (p=none, sem imposição)
Indicadores de Phishing:
- Domínio de aparência semelhante (examp1e-corp.com vs example-corp.com, 96% similar)
- Inconsistência From/Reply-To
- Domínio registrado 2 dias antes do envio do e-mail
- URL no corpo aponta para página de roubo de credenciais
- Anexo: invoice.xlsm (SHA-256: a3f2...) - Malware conhecido no VT
Nível de Risco: ALTO