analyzing-malicious-pdfs

Analyzes malicious PDF documents: parsing the object structure for JavaScript, OpenAction/launch triggers, embedded files, and URIs, then extracting and decoding suspicious streams without opening the

SKILL.md

GitHub

Analyzing Malicious PDFs

When to Use

  • You have a suspicious PDF (often from phishing) and must determine if it is weaponized.
  • You need to find auto-executing actions, embedded JavaScript, launch actions, or embedded files.
  • You want to extract and decode suspicious streams safely.

Do not use a PDF reader to "just look" — opening in a viewer can trigger the very actions you are investigating. Parse the structure statically.

Prerequisites

  • A PDF object parser (Python, or pdfid/pdf-parser/peepdf); the sample handled inertly.

Safety & Handling

  • Never open the PDF in a graphical reader; parse the raw object structure only.
  • Defang any extracted URLs and store embedded payloads password-protected.

Workflow

Step 1: Triage the object inventory

Count high-risk keywords: /JavaScript, /JS, /OpenAction, /AA, /Launch, /EmbeddedFile, /URI, /RichMedia. Their presence (especially auto-actions) flags weaponization.

python scripts/analyst.py triage sample.pdf

Step 2: Locate auto-execution triggers

Resolve /OpenAction and /AA (additional actions) to see what runs on open, and any /Launch actions that spawn external programs.

Step 3: Extract and decode streams

Pull JavaScript and suspicious streams, applying filters (/FlateDecode, /ASCIIHexDecode) to get the cleartext; deobfuscate layered JS as needed.

Step 4: Recover payloads and IOCs

Extract embedded files and URIs; hash payloads, defang URLs, and route extracted executables to PE analysis.

Validation

  • Auto-execution triggers (/OpenAction, /AA, /Launch) are resolved to concrete actions.
  • JavaScript/streams are decoded through their filters, not left encoded.
  • Embedded payloads and URIs are extracted, hashed, and defanged.

Pitfalls

  • Opening the PDF in a reader and triggering the payload.
  • Missing object-stream (/ObjStm) compressed objects that hide the malicious content.
  • Stopping at the first JS layer when it is multiply obfuscated.

References