Communitygithub.com

이메일 헤더 분석을 통한 피싱 수사

피싱 이메일의 진위를 밝히기 위해 수신 체인, Return-Path, Message-ID 등 이메일 헤더를 파싱하고 분석합니다.

이메일 헤더 분석을 통한 피싱 수사란 무엇인가요?

이 스킬은 피싱 수사에서 이메일 헤더를 분석하여 발신자의 진위 여부와 이메일 스푸핑 여부를 확인하는 방법을 제공합니다. 사용자는 원시 이메일 헤더를 추출하고, SPF, DKIM, DMARC 레코드를 검증하며, 발신자 도메인과 인프라를 조사할 수 있습니다. 또한 GitHub Copilot, Claude Code, Cursor 등 다양한 AI 에이전트 플랫폼에서 활용 가능하며, 이메일 본문 및 첨부 파일에서 악성 URL과 파일을 탐지하는 방법도 포함됩니다. 이 스킬은 수동 분석과 Python 자동화 스크립트를 모두 지원하여 포렌식 이미지, PST 파일 등 다양한 형식의 이메일 데이터를 처리할 수 있습니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/mukul975/Anthropic-Cybersecurity-Skills/tree/main/skills/analyzing-email-headers-for-phishing-investigation

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

피싱 수사를 위한 이메일 헤더 분석

사용 시기

  • 피싱 의심 이메일을 조사하여 실제 발신자를 확인할 때
  • 발신자 진위 확인 및 이메일 스푸핑 탐지 시
  • 사용자가 피싱 링크를 클릭한 사고 대응 중
  • 의심스러운 이메일의 전달 경로 및 중계 서버 추적 시
  • SPF, DKIM, DMARC 정합성을 검증하여 위조 식별 시

전제 조건

  • 의심스러운 메시지의 원시 이메일 헤더 (EML 또는 MSG 형식)
  • SMTP 프로토콜 및 이메일 헤더 필드에 대한 이해
  • SPF/DKIM/DMARC 확인을 위한 DNS 조회 도구 (dig, nslookup) 접근 권한
  • 이메일 헤더 분석 도구 (MHA, emailheaders.net 개념)
  • 자동 분석을 위한 Python 이메일 파싱 라이브러리
  • IP/도메인 평판 조회를 위한 위협 인텔리전스 플랫폼 접근 권한

워크플로우

1단계: 원시 이메일 헤더 추출

# Outlook에서 내보내기: 이메일 열기 > 파일 > 속성 > 인터넷 헤더
# Gmail에서 내보내기: 이메일 열기 > 점 세 개 > 원본 보기
# Thunderbird에서 내보내기: 보기 > 메시지 소스

# 포렌식 이미지에서 EML 파일 사용 시
cp /mnt/evidence/Users/suspect/AppData/Local/Microsoft/Outlook/phishing_email.eml \
   /cases/case-2024-001/email/

# PST 파일 사용 시 개별 메시지 추출
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

2단계: 이메일 헤더 체인 파싱

# 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("=== 주요 헤더 필드 ===")
print(f"보낸 사람:     {msg['From']}")
print(f"받는 사람:     {msg['To']}")
print(f"제목:          {msg['Subject']}")
print(f"날짜:          {msg['Date']}")
print(f"메시지 ID:     {msg['Message-ID']}")
print(f"답장 주소:     {msg['Reply-To']}")
print(f"반송 경로:     {msg['Return-Path']}")
print(f"메일러:        {msg['X-Mailer']}")
print(f"원본 IP:       {msg['X-Originating-IP']}")

print("\n=== 수신 헤더 (아래에서 위로 = 시간 순서) ===")
received_headers = msg.get_all('Received')
if received_headers:
    for i, header in enumerate(reversed(received_headers)):
        print(f"\n홉 {i+1}: {header.strip()}")

print("\n=== 인증 결과 ===")
auth_results = msg.get_all('Authentication-Results')
if auth_results:
    for result in auth_results:
        print(result)

print(f"\nARC 인증 결과: {msg.get('ARC-Authentication-Results', '없음')}")
print(f"수신 SPF: {msg.get('Received-SPF', '없음')}")
print(f"DKIM 서명: {msg.get('DKIM-Signature', '없음')}")
PYEOF

3단계: SPF, DKIM, DMARC 레코드 검증

# 봉투 발신자 도메인 추출
SENDER_DOMAIN="example-corp.com"

# SPF 레코드 확인
dig TXT $SENDER_DOMAIN +short | grep "v=spf1"
# 예: "v=spf1 include:_spf.google.com include:sendgrid.net ~all"

# DKIM 레코드 확인 (DKIM-Signature 헤더에서 셀렉터 예: "s=selector1")
DKIM_SELECTOR="selector1"
dig TXT ${DKIM_SELECTOR}._domainkey.${SENDER_DOMAIN} +short

# DMARC 레코드 확인
dig TXT _dmarc.${SENDER_DOMAIN} +short
# 예: "v=DMARC1; p=reject; rua=mailto:[email protected]; pct=100"

# 발신 IP를 SPF에 대해 검증
# 첫 번째 수신 헤더에서 IP 추출
SENDING_IP="203.0.113.45"

# Python으로 SPF 수동 확인
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 결과: {result}")
print(f"설명: {explanation}")
# 결과: pass, fail, softfail, neutral, none, temperror, permerror
PYEOF

# 발신 IP가 알려진 악성 IP 목록에 있는지 확인
# AbuseIPDB 또는 VirusTotal 쿼리
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

4단계: 발신자 도메인 및 인프라 분석

# 발신자 도메인 WHOIS 조회
whois $SENDER_DOMAIN | grep -iE '(registrar|creation|expiration|registrant|nameserver)'

# 도메인 기간 확인 (최근 등록된 도메인은 의심스러움)
# DNS 레코드 조사
dig A $SENDER_DOMAIN +short
dig MX $SENDER_DOMAIN +short
dig NS $SENDER_DOMAIN +short

# 발신 IP의 역방향 DNS
dig -x $SENDING_IP +short

# 유사/오타 도메인 확인
# 시각적 유사성을 이용해 정식 도메인과 비교
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"편집 거리: {distance}")
print(f"유사도 비율: {ratio:.2%}")
if ratio > 0.8:
    print("경고: 오타 도메인/유사 도메인 가능성 높음!")
PYEOF

# VirusTotal에서 도메인 평판 확인
curl -s "https://www.virustotal.com/api/v3/domains/${SENDER_DOMAIN}" \
   -H "x-apikey: YOUR_VT_API_KEY" | python3 -m json.tool

# Reply-To가 From과 다른지 확인 (일반적인 피싱 지표)
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'경고: From ({from_addr}) != Reply-To ({reply_to})')
else:
    print('From과 Reply-To 일치')
"

5단계: 이메일 본문 및 첨부 파일 검사

# 이메일 본문에서 URL 추출
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("=== 이메일 본문에서 발견된 URL ===")
    for url in set(urls):
        print(f"  {url}")

    # URL 난독화 확인 (표시 텍스트 != href)
    href_pattern = re.findall(r'<a[^>]*href=[\"\']([^\"\']+)[\"\'][^>]*>(.*?)</a>', content, re.DOTALL)
    print("\n=== 하이퍼링크 분석 ===")
    for href, text in href_pattern:
        display_url = re.findall(r'https?://[^\s<]+', text)
        if display_url and display_url[0] != href:
            print(f"  불일치: 표시='{display_url[0]}' -> 실제='{href}'")

# 첨부 파일 추출 및 해시 계산
print("\n=== 첨부 파일 ===")
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"  파일: {filename}, 크기: {len(content)}, SHA-256: {sha256}")
        with open(f'/cases/case-2024-001/email/attachments/{filename}', 'wb') as af:
            af.write(content)
PYEOF

# 첨부 파일 해시를 VirusTotal에 제출
# URL을 URLhaus 또는 PhishTank에 제출하여 평판 확인

주요 개념

개념설명
SPF (Sender Policy Framework)도메인이 승인한 메일 서버를 지정하는 DNS 레코드
DKIM (DomainKeys Identified Mail)이메일 콘텐츠 무결성을 확인하는 암호화 서명
DMARCSPF와 DKIM을 결합한 발신자 인증 정책 프레임워크
수신 헤더전달 체인의 각 홉을 보여주는 서버 추가 헤더 (하단에서 상단 순서로 읽음)
Return-Path반송 메시지에 사용되는 봉투 발신자 주소; From과 다를 수 있음
Message-ID발신 메일 서버가 할당한 고유 식별자
X-Originating-IP원본 발신자 IP 주소 (일부 메일 서비스에서 추가)
헤더 위조공격자는 From, Reply-To 등 헤더를 위조할 수 있지만 수신 체인은 위조 불가

도구 및 시스템

도구목적
MXToolbox온라인 이메일 헤더 분석기 및 DNS 조회
dig/nslookupSPF, DKIM, DMARC 확인을 위한 DNS 레코드 쿼리
pyspfPython SPF 레코드 검증 라이브러리
dkimpyPython DKIM 서명 검증 라이브러리
PhishTool전문 피싱 이메일 분석 플랫폼
VirusTotalURL 및 파일 평판 검사 서비스
AbuseIPDBIP 주소 평판 데이터베이스
whois도메인 등록 정보 조회

일반적인 시나리오

시나리오 1: CEO 사기 / 기업 이메일 침해 이메일이 CEO로부터 온 것처럼 위장했지만 Reply-To가 Gmail 주소를 가리키고, SPF는 발신 IP가 스푸핑된 도메인에 대해 승인되지 않아 실패하며, DKIM이 누락되고, From 도메인이 유사 도메인(ceo-company.com vs company.com)인 경우.

시나리오 2: 자격 증명 탈취 피싱 이메일에 "login.microsoft.com"을 표시하지만 href는 유사 도메인을 가리키는 링크가 포함되어 있고, 첨부 파일이 가짜 로그인 페이지(자격 증명 유출 JavaScript 포함)인 HTML 파일이며, 발신 도메인이 3일 전에 등록된 경우.

시나리오 3: 첨부 파일을 통한 악성코드 전달 매크로가 포함된 Office 문서 첨부 파일이 포함된 이메일, 발신자 도메인이 SPF를 통과했지만 계정이 손상되었고, DKIM 서명이 유효하며(정식 인프라에서 전송됨), 첨부 파일 SHA-256이 VirusTotal에서 알려진 악성코드와 일치하는 경우.

시나리오 4: 정식 서비스를 이용한 표적 피싱 공격자가 합법적인 이메일 마케팅 서비스를 사용하여 피싱 이메일을 전송, SPF와 DKIM이 서비스 승인으로 통과하고, 피싱이 인프라가 아닌 콘텐츠에 존재하므로 헤더 인증 확인보다 URL 및 콘텐츠 분석이 필요한 경우.

출력 형식

이메일 헤더 분석 보고서:
  제목:     "긴급: 인보이스 결제 요망"
  보낸 사람: [email protected] (스푸핑됨)
  답장 주소: [email protected] (불일치)
  반송 경로: <[email protected]>
  날짜:     2024-01-15 09:23:45 UTC

  전달 경로 (4홉):
    홉 1: mail-server.xyz [203.0.113.45] -> relay1.isp.com
    홉 2: relay1.isp.com -> mx.target-company.com
    홉 3: mx.target-company.com -> internal-filter.target.com
    홉 4: internal-filter.target.com -> 메일함

  인증:
    SPF:    실패 (203.0.113.45가 examp1e-corp.com에 대해 승인되지 않음)
    DKIM:   없음 (서명 없음)
    DMARC:  실패 (p=none, 적용 없음)

  피싱 지표:
    - 유사 도메인 (examp1e-corp.com vs example-corp.com, 96% 유사)
    - From/Reply-To 불일치
    - 이메일 전송 2일 전 등록된 도메인
    - 본문 URL이 자격 증명 탈취 페이지를 가리킴
    - 첨부 파일: invoice.xlsm (SHA-256: a3f2...) - VT에서 알려진 악성코드

  위험 수준: 높음

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

abusing-dpapi-for-credential-access

Extract and decrypt Windows DPAPI-protected secrets (Credential Manager, browser logins/cookies, Wi-Fi credentials, KeePass keys) online or offline using SharpDPAPI, SharpChrome, Mimikatz, or Impacket

abusing-shadow-credentials-for-privesc

Take over Active Directory accounts by writing attacker-controlled public keys to msDS-KeyCredentialLink (Shadow Credentials) with pyWhisker, Whisker, or Certipy, then authenticate via PKINIT to recover the target

achieving-cmmc-level-2-compliance

>-

acquiring-disk-image-with-dd-and-dcfldd

Create forensically sound bit-for-bit disk images with dd or dcfldd on a Linux forensic workstation, preserving evidence integrity through hash verification (MD5/SHA) during acquisition. Use when imaging a suspect drive, USB device, or memory card for investigation, preserving volatile disk evidence during incident response, or producing a verified copy for legal or law-enforcement proceedings before any destructive analysis.

analyzing-active-directory-acl-abuse

Detect dangerous ACL misconfigurations in Active Directory using ldap3

analyzing-android-malware-with-apktool

Perform static analysis of Android APK malware using apktool for resource decompilation, jadx for Java source recovery, and androguard for manifest inspection, dangerous permission-combination detection, and identification of obfuscated code, dynamic code loading, and reflection-based API calls. Use to statically triage a suspicious APK without executing it or to build mobile malware detection rules.

analyzing-api-gateway-access-logs

Parses API Gateway access logs (AWS API Gateway, Kong, Nginx) to detect

analyzing-apt-group-with-mitre-navigator

Query ATT&CK data with attackcti, mitreattack-python, and stix2, then build MITRE ATT&CK Navigator layers and multi-layer heatmap overlays mapping one or more APT groups

analyzing-azure-activity-logs-for-threats

Queries Azure Monitor activity logs and sign-in logs via azure-monitor-query

analyzing-bootkit-and-rootkit-samples

Analyzes bootkit and advanced rootkit malware infecting the Master

analyzing-browser-forensics-with-hindsight

Parse Chromium-based browser databases with Hindsight to extract and correlate browsing history, downloads, cookies, cached content, autofill data, saved passwords, and extensions from Chrome, Edge, Brave, Opera, and Vivaldi into a unified timeline (XLSX, JSON, or SQLite output). Use during incident response, insider-threat investigations, or criminal cases when you need to reconstruct a user

analyzing-campaign-attribution-evidence

Systematically evaluate cyber-campaign evidence to attribute an operation to a threat actor, using the Diamond Model and Analysis of Competing Hypotheses (ACH) to weigh infrastructure overlaps, TTP consistency, malware code similarity, and timing/language artifacts into confidence-weighted attribution assessments. Use when an incident investigation needs a defensible attribution confidence level.

analyzing-certificate-transparency-for-phishing

Monitor Certificate Transparency logs using crt.sh and Certstream to

analyzing-cloud-storage-access-patterns

Detect abnormal access in AWS S3, GCS, and Azure Blob Storage by analyzing CloudTrail Data Events, GCS audit logs, and Azure Storage Analytics for after-hours bulk downloads, new-IP access, and API-call spikes (e.g. GetObject) via statistical baselines and time-series anomaly detection. Use when investigating suspected cloud data exfiltration or building related detection rules.

analyzing-cobalt-strike-beacon-configuration

Extract and analyze Cobalt Strike beacon configuration from PE files

analyzing-cobaltstrike-malleable-c2-profiles

Parse and analyze Cobalt Strike Malleable C2 profiles with dissect.cobaltstrike (profiles and beacon-payload configs) and pyMalleableC2 (AST parsing) to extract HTTP/DNS transforms, URIs, headers, sleep/jitter, and injection behavior, then generate network detection signatures. Use when reverse-engineering a captured malleable profile or building detections against Cobalt Strike Beacon traffic.

analyzing-command-and-control-communication

Analyzes malware C2 communication over HTTP, HTTPS, DNS, and custom

analyzing-cyber-kill-chain

Analyzes intrusion activity against the Lockheed Martin Cyber Kill Chain

analyzing-disk-image-with-autopsy

Perform comprehensive forensic analysis of raw (dd), E01, or AFF disk images with Autopsy and The Sleuth Kit, recovering deleted files, examining metadata and embedded artifacts, keyword searching, and building investigation timelines with visual reports. Use for structured analysis of a forensic disk image or when stakeholders need visual reports from evidence.

analyzing-dns-logs-for-exfiltration

Analyzes DNS query logs to detect data exfiltration via DNS tunneling,

관련 스킬