Met professionele tools kun je verdachte documenten analyseren voordat je ze opent en/of de bron van infecties met schadelijke code opsporen. Vaak gaat het om ogenschijnlijk onschuldige Office- of PDF-bestanden die in een mailbox op de loer liggen.
Zo onderzoek je documentgebaseerde malware
Tools zoals QPDF, pdf-parser en de oletools-verzameling helpen je om te begrijpen hoe documentgebaseerde malware- en phishing-aanvallen werken. Hoe je deze en andere handige hulpmiddelen voor documentanalyse gebruikt, wordt in dit artikel uitgelegd aan de hand van twee praktische voorbeelden. Je kunt deze downloaden en zelf uitproberen (ziede link) maar we raden aan de stappen in dit artikel niet op een productie-pc uit te voeren.
De tools zijn in de eerste plaats bedoeld voor gebruikers met expertise in malware-analyse die mogelijke infectiebronnen willen onderzoeken. Maar ook geïnteresseerde leken kunnen ermee experimenteren, want in tegenstelling tot sommige andere professionele tools zoals de Windows-register-editor FRED, kun je hiermee geen schade aan het systeem aanrichten.
Voorzichtig met voorbeelden
Het eerste voorbeeld (voorbeeld1.pdf) gebruikt data uit een echte phishingcampagne en moet je daarom met de nodige voorzichtigheid ontleden – ondanks dat de phishinglink niet meer actief is. Sowieso raden we aan de analyse niet op je dagelijkse pc uit te voeren, maar een VM of aparte pc met bijvoorbeeld Kali te gebruiken. Een groot aantal van de genoemde tools zijn hierin al standaard geïnstalleerd.
Het tweede voorbeeld (voorbeeld2.doc), een Word-document met ingebedde zelfgeschreven macro-code, is daarentegen volkomen onschadelijk. Toch is het slim altijd zorgvuldig met dit soort situaties om te gaan en professionele tools en schadelijke code altijd met de nodige behoedzaamheid te behandelen.
Gereedschapskist op commandline
Het wachtwoord voor het archief met de voorbeeldbestanden is ‘infected’. Pak het archief uit in een speciaal daarvoor aangemaakte map. Alle tools die worden ingezet zijn via de commandline te starten en bedienen.
Om een eerste overzicht te krijgen van de eigenschappen van het document, is vooral het Python-script pdfid van beveiligingsonderzoeker Didier Stevens geschikt: het doorzoekt PDF-bestanden op specifieke strings die informatie geven over belangrijke documenteigenschappen, zoals het aantal pagina’s (/Page), maar ook over mogelijk schadelijke inhoud zoals uitvoerbare JavaScript-code (/JavaScript) of ingesloten bestanden (/EmbeddedFile).
De gevonden strings worden samen met hun aantal in de terminal weergegeven. Als je meer wilt weten over de betekenis van alle gevonden strings, kun je de PDF-documentspecificaties raadplegen (zie de link). Het commando om het programma te starten is:
pdfid voorbeeld1.pdf
De tool vindt onder andere de string /Encrypt 1, wat aangeeft dat het document met een wachtwoord is versleuteld. Dit soort versleuteling wordt soms door aanvallers gebruikt bij phishing-campagnes om te voorkomen dat schadelijke PDF-bijlagen in e-mails door beveiligingsprogramma’s worden herkend en tegengehouden.
Het bijbehorende wachtwoord voegen de criminelen vaak onder het mom van vertrouwelijke inhoud als afbeelding in het bericht in: leesbaar voor mensen, maar niet zomaar voor automatische detectiemechanismen.

pdfid geeft met strings de pdf-documenteigenschappen aan: /Encrypt 1 geeft aan dat het bestand is versleuteld met een wachtwoord: een bekende truc om beveiligingsprogramma’s te ontwijken.Wachtwoord verwijderen met QPDF
Tools voor handmatige analyse van schadelijke code worden door versleutelde PDF’s flink op de proef gesteld: ze spuwen wartaal uit of geven het zelfs helemaal op. Daarom moet in de volgende stap eerst het wachtwoord (en daarmee ook de versleuteling) worden verwijderd. Voor dit doel gebruiken we QPDF.
De tool biedt allerlei functies voor het bewerken van PDF-bestanden; in de context van documentanalyse is echter vooral de decodeerfunctie relevant. Om die te gebruiken (sudo apt install qpdf), voer je de volgende opdracht in:
qpdf --decrypt voorbeeld1.pdf voorbeeld1-decrypted.pdf --password=1234
QPDF slaat het gedecodeerde bestand op onder de naam voorbeeld1-decrypted.pdf in dezelfde map. Met qpdf --check voorbeeld1-decrypted.pdf kun je controleren of het decoderen gelukt is: als de uitvoer ‘file is not encrypted’ is, is alles gelukt.

qpdf het decoderen en controleren of het decoderen goed is gegaan.In ons voorbeeld is het wachtwoord voor het gemak simpelweg 1234. Helaas werkt het ontsleutelen met QPDF in principe alleen als je het wachtwoord kent. Anders kun je het document alleen kraken met bijvoorbeeld een tool als het gratis pdfrip, waarmee je automatisch wachtwoorden kunt uitproberen (brute force).
Dieper graven
Ook het gebruik van pdfid op voorbeeld1-decrypted.pdf bevestigt dat het ontcijferen gelukt is: de tool meldt ‘/Encrypt 0’. Nu is het tijd om de overige gevonden strings te bekijken. Interessant is onder andere de regel ‘/ObjStm 1’, die wijst op een Object Stream in de PDF. Dergelijke datastromen bundelen meerdere objecten in gecomprimeerde vorm.
Het idee hierachter is om de grootte van de PDF te verkleinen, maar aanvallers kunnen deze functie ook misbruiken om schadelijke inhoud te verbergen voor nieuwsgierige blikken. Ook verdacht: de vermelding ‘/Open-Action 1’ verraadt dat er bij het openen van de PDF een geautomatiseerde actie wordt uitgevoerd, die je in ieder geval moet onderzoeken.
Om nog meer PDF-geheimen aan het licht te brengen, moet je in de volgende stap de datastromen analyseren. Daarbij helpt pdf-parser, nog een tool van Didier Stevens, met het commando:
pdf-parser -a -O voorbeeld1-decrypted.pdf
De vlag -O parset de aanwezige streams, terwijl -a net als in pdfid, gevonden trefwoorden en genummerde verwijzingen naar concrete objecten weergeeft. Deze objectnummers wijst pdf-parser niet zelf toe, maar haalt ze rechtstreeks uit de documentstructuur. Daar hebben ze de functie om direct naar objecten te kunnen verwijzen, oftewel ze via het nummer aan te spreken.

Bijzonder interessant in ons concrete voorbeeld zijn de volgende termen die door pdf-parser zijn gevonden:
- /XObject verwijst naar twee grafische objecten in de PDF.
- /JavaScript vertelt ons dat een van de gevonden objecten een verborgen script is.
- /OpenAction koppelt de actie bij het openen, die al door
pdfidwerd herkend, aan een concreet objectnummer. Zoals je zult zien als je het in de terminal uitprobeert, is dat in ons voorbeeld de 1. - /URI verwijst naar een bron op het web.
Om de afzonderlijke objecten in detail te bekijken, moet je ze laten het schema pdf-parser -o [objectnummer] -O voorbeeld1-decrypted.pdf laten parsen, waarbij -o wordt gevolgd door het nummer dat aan het object is toegewezen; in het voorbeeldbestand bijvoorbeeld de 4 voor /JavaScript of de 8 voor /URI.

pdf-parser, krijgen we hier de phishinglink boven water.Uit de analyse van de eerder genoemde objecten blijkt het volgende:
- OpenAction verwijst naar het JavaScript (4) en roept dit dus op wanneer de gebruiker de PDF opent.
- Het script zelf geeft een pop-up met een Italiaanse melding weer, waarin staat dat de PDF-viewer niet compatibel is met het document en dat je het in plaats daarvan in de browser moet openen.
- In de PDF zijn bovendien een afbeelding (ingesloten in een extern grafisch object dat coördinaten aangeeft) en de eerder genoemde URI opgenomen.
- Die laatste lijkt te verwijzen naar online beschikbare factuurgegevens. Hij bevat de tekstreeksen account-bookings en booking.com: waarschijnlijk om de indruk te wekken dat het om een hotelboeking gaat.
Het totaalplaatje
Om tot slot ook nog de afbeelding uit de PDF te halen en te bekijken, gebruik je het beste Detect it Easy (DiE). Deze alleskunner kan met allerlei bestandstypen overweg, deze statisch analyseren en de daarin opgenomen bronnen eruit halen.
Deze tool heeft een grafische interface maar in dit specifieke geval start je via de commandline: nadat je die voorbeeld-decrypted.pdf hebt ingevoerd, opent de GUI zich. Vink rechts op de grafische interface het vakje Advanced aan en klik vervolgens op de knop Extractor in het midden van de interface.
Selecteer daarna de regel met het JPEG-bestand dat DiE in de PDF heeft gevonden en klik op Dump all. Net als de JavaScript-pop-up die eerder met de pdfparser werd opgespoord, probeert de geëxtraheerde afbeelding je ertoe te brengen een dubieuze website te bezoeken bij het openen van de PDF: een zogenaamde foutmelding geeft aan dat er problemen zijn bij het weergeven van de PDF-inhoud, (‘Errore’). Een blauwe nepknop moet je ertoe aanzetten om erop te klikken. Er staat ‘Ricarica’ op, wat in het Italiaans ‘Opnieuw laden’ betekent.

In de context van de PDF leidt deze knop naar de zogenaamde boekingslink die je eerder met de PDF-parser hebt opgespoord. Blijkbaar was het de bedoeling je ertoe te verleiden in de PDF naar informatie over de zogenaamde (hotel-)factuur te zoeken en uiteindelijk op de link te klikken.
Office-documenten onder de loep
Een andere, al jarenlang onverminderd populaire toegangspoort voor aanvallers zijn Office-documenten met extensies als .doc, .docm of ook .xls/.xlsm, waarin uitvoerbare code in de vorm van macro’s op de loer kan liggen. Daarom is een verzameling tools voor het analyseren van zulke documenten in je digitale gereedschapskist onmisbaar.
Deze collectie heet oletools en bestaat momenteel uit twaalf afzonderlijke tools. De meeste tools doorzoeken bestanden in het oudere OLE2-formaat.
Sommige tools richten zich echter ook op het recentere Office Open XML-formaat (zoals .docx, .xlxs) en op het Rich Text Format (.rtf). Ons voorbeeld2.doc is perfect om vooral te experimenteren met de volgende tools uit de oletools-collectie:
- oleid analyseert OLE-bestanden op typische kenmerken van malware.
- mraptor (MacroRaptor) zoekt specifiek naar schadelijke VBA-macro’s.
- olevba gaat tot in diepe details: het onderzoekt macrocode en probeert verborgen functies en strings te ontcijferen.
De tools hebben (in eerste instantie) geen specifieke parameters nodig: je start ze simpelweg via [toolnaam] voorbeeld2.doc.
Macro-code ontleed
In de eerste stap geeft oleid informatie over bijvoorbeeld het bestandsformaat en de auteur van het document. Bovendien ontdekt het ook de VBA-macrocode die in het voorbeeld zit. Het vergelijkt die met potentieel verdachte trefwoorden, vindt er geen en classificeert het potentiële risico voorlopig voorzichtig als ‘medium’.
In de tweede stap vindt mraptor in de macro een zogenaamde auto-execution trigger. Wat dat precies betekent, kan olevba je vertellen: de tool toont de macro-code direct in de terminal, zonder dat je het potentieel gevaarlijke document hoeft te openen.
De methodenaam AutoOpen() zorgt ervoor dat de macro automatisch wordt uitgevoerd zodra je het document opent. De code die erin zit, opent een berichtvenster (MsgBox). De tekst daarvan is in olevba echter niet volledig leesbaar: een hex-string en enkele ASCII-tekens die met de Chr()-functie worden weergegeven, zijn in ons voorbeeld een poging om een aanval te verhullen.
Gelukkig herkent olevba dit soort standaardtrucs automatisch, geeft de betreffende passages weer in een tabel en markeert ze als verdacht. De extra switches --decode en --deobf maken de tekst (Alles ontsleuteld!!!) uiteindelijk leesbaar:
olevba --decode –deobf voorbeeld2.doc
Als je zin hebt, kun je aan de hand van ons voorbeeld nog meer oletools uitproberen. Zo haalt olemeta bijvoorbeeld alle metadata uit het document. Met olebrowse kun je via een GUI door de bestandsstructuur klikken en datastromen in hexadecimale weergave bekijken.
Wat helaas geen van de tools uit de verzameling kan, is de in het voorbeeld verborgen afbeelding extraheren. Gelukkig weet je nu al hoe je dit heel eenvoudig met DiE kunt doen.
Vele wegen naar Rome
Aan de hand van onze voorbeelden heb je vast een aardig beeld gekregen van de nodige handige analysetools, maar er zijn nog meer van dit soort handige analysetools te vinden. Zo biedt Qu1cksc0pe (zie de link), een tool met allerlei scanfuncties, met de switch --docs om Office-documenten en PDF-bestanden te doorzoeken.
De tool herkent zowel de AutoExec-functie in onze PDF als de macro-code in ons .doc-voorbeeld. Je kunt dit uitproberen met het commando
qu1cksc0pe --file (bestandsnaam) --docs
Daarnaast bevat Binary Refinery [2] meteen meerdere modules, zogenaamde ‘units’, die je met die twee bestanden kunt uitproberen. Daar vind je de pdfcrypt als alternatief voor QPDF om wachtwoorden te verwijderen.
Je past deze toe op de versleutelde voorbeeld-PDF door eerst de toolkit te starten door refinery-shell in de terminal in te voeren en vervolgens het volgende te typen:
emit voorbeeld1.pdf | pdfcrypt 1234 | dump voorbeeld1-decrypted.pdf
Het commando decodeert de PDF met behulp van het bekende wachtwoord en slaat de gedecodeerde kopie op in dezelfde map. Tijdens het uitproberen zul je vast nog meer manieren en mogelijkheden ontdekken om verdachte documenten hun geheimen te ontfutselen.
Olivia von Westernhagen en Alieke van Sommeren
Literatuur
[1] Olivia von Westernhagen en Noud van Kruysbergen, Potentieel gevaarlijke PDF-documenten ontsleutelen met QPDF, c’t 6/2025, p.124
[2] Olivia von Westernhagen en Noud van Kruysbergen, Malware-analyse met Binary Refinery, c’t 10/2026, p. 116
Links bij dit artikel
voorbeeldbestanden (pdf & doc)
Detect it easy
Didier Stevens: pdfid, pdf-parser
oletools
PDF-documentspecificaties
Pdfrip
QPDF
Qu1cksc0pe
Praat mee