Content
On March 8th 2026 the Security Researcher Haifei Li identified an interesting PDF malware sample in the wild, which contains an unknown exploit to a vulnerability in the Adobe Reader PDF viewer.
Haifei Li published initial findings in a blog article. We would like to expand on the analysis of the PDF in this article:
Extracting content from the PDF
Using pdf-parser.py by Didier Stevens we can extract indivudual objects from the file. The Javascript/JS, OpenAction and AcroForm objects are of primary interest to us.
Looking at the Optional Content Group object (ID 4) we can see that this PDF was likely programmatically created using the PyMuPDF library. Apart from this information, the file does not contain any relevant metadata on e.g. the Author, only the language setting en-US. The document lure itself contains Russian text, titled “Measures to be taken to organize interventions” (translated).
Up next, we will extract object 11, which holds the embedded Javascript payload. To obfuscate this snippet, the threat actors likely used https://jsfuck.com/, an esoteric obfuscator that uses a set of characters and Javascript type strings to reconstruct the script.
By evaluating the JSFuck expressions and removing backslashes from the string literal escapes of the PDF, the obfucation can be resolved.
The Javascript snippet references a Form field named btn1. From the code we can infer that it seems to extract a value from the stream, which is then decoded from Base64. To find “btn1” in the PDF file, we can use the –search function of pdf-parser.py.
We have to view object 9 in the –raw mode, otherwise the stream would not be visible in the output. As suspected, a rather large base64 encoded blob can be found here.
When decoding the Base64 blob, you may stumble upon decoding errors. This is due to two forward slashes (/) being URL-encoded as #2F. We suspect this to be a parser anomaly and/or anti-analysis trick, altough it may also be caused by a tooling error down the line. The decoded blob contains heavily obfuscated Javascript again, this time likely using the public obfuscatior.io implementation.
Unravelling this obfuscation is not as trivial as with JSFuck, as it uses a central string lookup table, which is continually shuffled until a checksum matches. With a bit of additional beautification and manual fixups, the code can be brought to a readable state.
Interestingly the script ships an open-source AES implementation in CTR Mode, as evidenced by the aes-js configuration and the S-Box values pictured below:
For the purposes of this PDF analysis showcase and due to the criticality of this vulnerability, we are not going to do a deep dive into the suspected exploit code yet, but stay tuned for a follow-up article, where we will investigate further!
After the exploit code was executed, all priviledged actions are wrapped in beginPriv() and endPriv() calls.
The Javascript contains extensive fingerprinting logic, commonly utilized by advanced threat actors to selectively target individual systems. It verifies which version of Adobe Reader is in use and whether it is a 64-bit binary, extracts the Windows product version string from ntdll.dll’s PE Header and searches for file system artifacts to verify the Windows major version.
The threat actors chose RSS Feeds as a Command & Control channel, which is not a very common find. The first feed is used to signal the victim fingerprint and to pull information for follow-up playload delivery. The second feed is used to download addtional payloads with the previosly retrieved information. Both feeds return Javascript code, which is evaluated in the script
With a polling rate of 500ms the payload checks for follow-up payloads very regularly, suggesting that the fingerprint is probably evaluated automatically rather than manually by a hands-on operator. Such high-frequency checks would likely stand out sooner or later in case payload delivery is delayed significantly.
The RSS feed delivers global.bird1 (the hex-encoded AES ciphertext) and global._Ke (the AES key bytes), which are decrypted using the supplied AES-CTR implementation and deflated from a ZIP archive.
The second stage payload “final_js” is then executed. Currently there is no follow-up payload available for analysis. Should this situation change, will be sure to provide an update.
While it is not referenced in the sample, the Command&Control server also had an associated subdomain “zx.ado-read-parser[.]com”. This domain was registered with Namesilo on 2025-02-06, suggesting that this campaign has been active for quite a while.
Indicators of Compromise
PDF File - 54077a5b15638e354fa02318623775b7a1cc0e8c21e59bcbab333035369e377f
Command & Control Server - 188.214.34[.]20:34123 / zx.ado-read-parser[.] 
