reverse-skills-max: initial public release (restored, redacted, hardened)

This commit is contained in:
baradok609hecl1pq6qi
2026-10-20 02:17:15 +03:00
commit da24c2bd20
2227 changed files with 443931 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
Apache License 2.0 — see the repository root LICENSE file for the full text.
Copyright the AnalystAIPack contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0

View File

@@ -0,0 +1,91 @@
---
name: analyzing-malicious-pdfs
description: '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 document in a reader. Activates for requests to analyze a malicious
PDF, inspect PDF JavaScript, or extract embedded payloads from a PDF.'
domain: cybersecurity
subdomain: malware-analysis
tags:
- malware-analysis
- pdf
- document-malware
- javascript
- static-analysis
version: 1.0.0
author: analyst-ai-pack
license: Apache-2.0
mitre_attack:
- T1204.002
- T1059.007
- T1027
d3fend:
- D3-FCR
- D3-DA
references:
- 'PDF 32000-1:2008 (ISO PDF specification) — https://www.pdfa.org/resource/iso-32000-pdf/'
- 'Didier Stevens PDF tools (pdfid, pdf-parser) — https://blog.didierstevens.com/programs/pdf-tools/'
---
# 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.
```bash
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
- See [`references/api-reference.md`](references/api-reference.md) for the PDF triage parser.
- ISO 32000 and Didier Stevens' PDF tools (linked in frontmatter).

View File

@@ -0,0 +1,39 @@
# API Reference: Analyzing Malicious PDFs
## Overview
`scripts/analyst.py` scans raw PDF bytes for weaponization keywords (/JavaScript, /OpenAction,
/Launch, /EmbeddedFile, /URI, /ObjStm, etc.), counts objects/streams, extracts and defangs URIs,
and flags likely weaponization. It parses statically and never opens the document.
## Dependencies
| Package | Version | Purpose |
|---------|---------|---------|
| (stdlib) | — | regex, JSON, file IO |
## External tools
| Tool | Purpose |
|------|---------|
| pdfid / pdf-parser (Didier Stevens) | Object inventory and stream extraction with filters |
| peepdf | Interactive PDF analysis and JS extraction |
## Core functions
### `triage(path)`
Returns object/stream counts, risk-keyword counts, auto-action list, defanged URIs, and a
weaponization flag.
## Usage
```bash
python scripts/analyst.py triage sample.pdf
```
## Sources
- PDF 32000-1:2008 (ISO PDF specification) — https://www.pdfa.org/resource/iso-32000-pdf/
- Didier Stevens PDF tools (pdfid, pdf-parser) —
https://blog.didierstevens.com/programs/pdf-tools/
- /OpenAction, /AA, /Launch auto-execution and /ObjStm hiding, established PDF-analysis practice

View File

@@ -0,0 +1,62 @@
#!/usr/bin/env python3
"""Triage a PDF's object structure for weaponization indicators.
Scans the raw PDF bytes for high-risk keywords (/JavaScript, /OpenAction, /Launch, /EmbeddedFile,
/URI, etc.), counts indirect objects and streams, and extracts URIs. It parses bytes statically
and never opens the document in a reader, so auto-actions cannot fire.
"""
from __future__ import annotations
import argparse
import json
import re
import sys
from pathlib import Path
KEYWORDS = ["/JavaScript", "/JS", "/OpenAction", "/AA", "/Launch", "/EmbeddedFile",
"/URI", "/RichMedia", "/SubmitForm", "/GoToR", "/ObjStm", "/AcroForm",
"/XFA", "/JBIG2Decode"]
AUTO_ACTION = {"/OpenAction", "/AA", "/Launch"}
RE_URI = re.compile(rb"/URI\s*\(([^)]*)\)")
RE_OBJ = re.compile(rb"\d+\s+\d+\s+obj")
RE_STREAM = re.compile(rb"\bstream\b")
def _defang(url: str) -> str:
return url.replace("http", "hxxp").replace(".", "[.]")
def triage(path: str) -> dict:
data = Path(path).read_bytes()
if not data.lstrip().startswith(b"%PDF"):
return {"error": "not a PDF (no %PDF header)"}
counts = {kw: len(re.findall(re.escape(kw.encode()), data)) for kw in KEYWORDS}
counts = {k: v for k, v in counts.items() if v}
uris = sorted({m.decode("latin-1", "replace") for m in RE_URI.findall(data)})
auto = [kw for kw in AUTO_ACTION if counts.get(kw)]
has_js = bool(counts.get("/JavaScript") or counts.get("/JS"))
return {
"objects": len(RE_OBJ.findall(data)),
"streams": len(RE_STREAM.findall(data)),
"risk_keywords": counts,
"auto_actions": auto,
"has_javascript": has_js,
"uris": [_defang(u) for u in uris],
"weaponized_likely": bool(auto and has_js) or bool(counts.get("/Launch")),
}
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(description="Triage a malicious PDF")
sub = parser.add_subparsers(dest="cmd", required=True)
p = sub.add_parser("triage")
p.add_argument("file")
args = parser.parse_args(argv)
print(json.dumps(triage(args.file), indent=2))
return 0
if __name__ == "__main__":
sys.exit(main())