In this Sherlock challenge, players will conduct PDF analysis to identify malicious scripts and embedded files within provided documents. They will also perform malware analysis on a Windows PE executable extracted from the PDF, examining its behavior and persistence mechanisms.
A client received a phishing email with a PDF attachment posing as a construction project plan. The PDF hid a Windows executable as an embedded file, whose debug path exposes the author’s project name. Once run, the malware copied itself to the public profile folder, set a Run key for persistence and targeted a standard Windows process for injection. The collected event logs show the attacker escalating to SYSTEM through a service-installation GetSystem technique within minutes of the email arriving, then installing a lasting service that launches a renamed copy of the payload. The victim ran Windows 7 with Adobe Reader 9 installed.
.eml message → read the headers in a text editor and extract the attachment with Python’s email moduleexiftool for metadata, grep and Python zlib for objects and streamsstrings, plus PE header fields read with PythonEvtxECmd for System.evtx and Security.evtx, RECmd for the software hive; the KAPE console log records the OSTimestamp note: All answers use
YYYY-MM-DD hh:mm:ssin UTC. The emailReceived:header carries a+0000offset, so it needs no conversion. The PDFCreationDateis written asD:YYYYMMDDhhmmss.
Open the .eml and read the Received: headers. The topmost one carries the delivery time with an explicit +0000 offset, so the UTC value can be copied straight across.
grep -i "^Received:" message.eml
Pull the PDF out of the email by decoding the MIME attachment, then read its metadata. The /CreationDate entry is D:20240918135704, which reformats to the answer. This is the PDF author’s build time, a day before the email was delivered.
python3 -I -c "import email,sys; m=email.message_from_file(open(sys.argv[1])); [open('work/pdf/'+p.get_filename(),'wb').write(p.get_payload(decode=True)) for p in m.walk() if p.get_filename()]" message.eml
exiftool work/pdf/*.pdf
Search the PDF for an /EmbeddedFiles name tree. The Filespec object gives the file name in its /UF entry, and its /EF entry points at object 14, whose Flate stream is the payload. Decompress it with zlib to get the PE used in the next questions.
grep -a -E "EmbeddedFiles|/Filespec|/UF" work/pdf/*.pdf
python3 -I -c "import re,zlib,sys; d=open(sys.argv[1],'rb').read(); m=re.search(rb'14 0 obj.*?stream\r?\n(.*?)endstream',d,re.S); open('work/embedded.bin','wb').write(zlib.decompress(m.group(1).strip()))" work/pdf/*.pdf
Tip: Without
pdfidorpdf-parser,grepplus azlibdecompress of the stream gets the same result.
The KAPE collection logs the target’s OS in its console log, as an OS: line. No registry parsing is needed for this one.
grep -i "OS:" kape_console.log
Run RECmd over the collected software hive and review the installed-software output. The Adobe entry gives the full product name and version, and an old Reader on Windows 7 fits a PDF-borne attack.
RECmd.exe -d <kape_collection>\Registry --bn BatchExamples\InstalledSoftware.reb --csv work/recmd
grep -i adobe work/recmd/*.csv
Read the COFF TimeDateStamp from the carved PE and convert it as UTC. It lands about seven hours after the PDF’s creation time from Q2, on the same day.
python3 -I -c "import pefile,sys,datetime as d; p=pefile.PE(sys.argv[1]); print(d.datetime.utcfromtimestamp(p.FILE_HEADER.TimeDateStamp))" work/embedded.bin
Run strings on the PE and look for a .pdb path. The debug directory keeps the build path ...\Projects\exit\x64\Release\exit.pdb, so the project folder name is the answer.
strings -a work/embedded.bin | grep -i "\.pdb"
The same strings output has a hardcoded drop path in the public profile. This is the file the Run key from Q7 points at.
strings -a work/embedded.bin | grep -i -E "^[A-Z]:\\"
Look in the strings near the Run key path (Software\Microsoft\Windows\CurrentVersion\Run). The value name sits next to it and imitates a Windows component. The same name shows up again in Q12 as a service name.
strings -a work/embedded.bin | grep -i -E "CurrentVersion\\Run|Pooler"
Among the strings, a single Windows process name stands out as the injection target.
strings -a work/embedded.bin | grep -i "\.exe"
Parse System.evtx with EvtxECmd and filter on Event ID 7045 (service installed). The GetSystem pattern shows as a service whose image path is cmd.exe /c echo <random> > \\.\pipe\<random>, a named-pipe impersonation trick. The event is about four minutes after the email was delivered in Q1.
EvtxECmd.exe -d <kape_collection>\Windows\System32\winevt\logs --csv work/evtx
grep ",7045," work/evtx/*System*.csv
In the same 7045 results, a later service points at C:\Windows\WindowsPooler.exe with a random argument. The name matches the Run value from Q7. The earlier event is the temporary GetSystem service, and this one is the lasting foothold.
grep -i "WindowsPooler" work/evtx/*System*.csv
| Phase | Action |
|---|---|
| Initial Access | Phishing email delivers a PDF disguised as a construction project plan |
| Execution | PDF carries an embedded Windows PE that the victim runs |
| Persistence | Malware copies itself to the public profile and sets a Run value imitating a Windows component |
| Defense Evasion | Payload targets a standard Windows process for injection |
| Privilege Escalation | Temporary service with a named-pipe command line gives SYSTEM |
| Persistence | Lasting service installed that runs the renamed payload from the Windows directory |
| Timestamp (UTC) | Event |
|---|---|
| 2024-09-18 13:57:04 | Malicious PDF created |
| 2024-09-18 21:19:18 | Embedded PE compiled |
| 2024-09-19 17:44:11 | Email received by the client |
| 2024-09-19 17:48:31 | GetSystem service installed (7045) |
| 2024-09-19 17:50:17 | WindowsPooler service installed (7045) |
| Type | Value |
|---|---|
| Embedded file | downtown_construction_project_plan.pdf |
| PDB project | exit (...\Projects\exit\x64\Release\exit.pdb) |
| Drop path | C:\Users\Public\test.exe |
| Run value / service name | WindowsPooler |
| Service image | C:\Windows\WindowsPooler.exe |
| Injection target | explorer.exe |
| Technique | ID | Description |
|---|---|---|
| Phishing: Spearphishing Attachment | T1566.001 | PDF delivered by email |
| User Execution: Malicious File | T1204.002 | Victim opened the PDF and ran the embedded payload |
| Boot or Logon Autostart: Registry Run Keys | T1547.001 | WindowsPooler Run value pointing at the dropped copy |
| Process Injection | T1055 | Payload targets explorer.exe |
| Create or Modify System Process: Windows Service | T1543.003 | GetSystem service and the WindowsPooler service |
An email-borne PDF with an embedded executable should be blocked at the gateway. The PDF held an /EmbeddedFiles entry whose payload was a PE. Mail filtering that inspects PDF attachments for embedded executables stops this before a user opens it.
Unpatched Adobe Reader 9 on Windows 7 makes the PDF path viable. The host ran an old Reader on an unsupported OS. Patching or retiring both removes the exploit surface the lure relied on.
Service installs from cmd.exe with a named pipe are a SYSTEM escalation signal. Event ID 7045 with an image path of cmd.exe /c echo ... > \\.\pipe\... is the signature of GetSystem-style impersonation. Alert on it, and on 7045 events whose image sits in C:\Windows with an unfamiliar executable.
Lookalike names hide persistence. WindowsPooler was used as both the Run value and the service name. Hunt for Run values that point into C:\Users\Public and for services whose names resemble Windows components but are not Microsoft-signed.
A single phishing PDF gave the attacker code execution and, within minutes, SYSTEM and a durable service on an outdated Windows 7 host. The malware’s own strings and the System log’s 7045 events told the whole story.