About this post: Thanks to zhujiabao050624 for flagging this sample. This analysis and write-up were produced by Claude (Opus 5.5), working as an agent in Claude Code on a REMnux analysis VM. Tools used: Malcat, ILSpy (ilspycmd), capa, osslsigncode, tshark, Recorded Future Triage, ANY.RUN, Censys and VirusTotal.
TL;DR
This sample arrived as a ZIP named like a policy paper: Integrated_Assessment_Indo-Pacific_Economic_and_Security.zip. Inside is a "document" that is a validly signed PDF editor "PDFgear" and a hidden CommonLib.dll that the program loads automatically. The attackers rewrote that DLL from scratch. Every PDFgear function in it is an empty shell, except the one function the program calls first, which starts a small backdoor that calls itself BeCtrl.
- It moves in quietly: both files are copied to
C:\ProgramData\Microsoft\DeviceSync\, an old "Load" registry value starts them at logon, and the restart is disguised as a child of Explorer. - It phones home over port 53: it talks to
31[.]59[.]184[.]185and103[.]175[.]50[.]32, first over UDP port 53 (the DNS port, but not DNS), then over encrypted WebSockets on six other ports. - It does two things, and both are dangerous: the operator can run any program or command and push any file (up to 10 MiB) to any path.
- The C2 was live: in two public Triage runs the server accepted the login and kept the session alive with heartbeats. No commands arrived while we watched.

A real program with a fake library
Most programs don’t do all their work alone; they lean on libraries, DLL files that sit next to them and provide shared functions. PDFgear’s small helper RegExt.exe (it registers PDFgear as the PDF handler) relies on a library called CommonLib.dll. Windows, or in this case the .NET runtime, looks for that library in the program’s own folder first.
That lookup order is what the attackers exploit. If you put your own CommonLib.dll next to the real program, the real program will happily load it. This trick is usually called DLL sideloading.
Here the swap is unusually thorough. The fake DLL carries PDFgear’s name, version (2.1.18.0) and description, and it provides every function RegExt.exe expects, from AppIdHelper.IsAdmin to ShellHelper.UpdateFilePinState. All of them are empty and return nothing useful, except SqliteUtils.InitializeDatabase(), which is the very first thing RegExt.exe calls when it starts. That one function starts the backdoor.
Moving in
The first time the backdoor runs, it checks whether it is already in its preferred directory. If not, it:
- creates
C:\ProgramData\Microsoft\DeviceSync\(a folder name chosen to blend in with real Windows folders); - copies the running program there as
RegExt.exeand the DLL asCommonLib.dll; - adds an autostart entry. For a normal user that is the old
Loadvalue underHKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows, a legacy autostart spot that many people never check. When it runs as SYSTEM it uses the familiarRunkey with the name PDFgear DeviceSync; - restarts the copy and exits.
The restart uses a trick called parent PID spoofing. Every Windows process records which process started it, and security tools use that "family tree" to spot odd behaviour. BeCtrl asks Windows to record Explorer as the parent instead of itself, so the new process looks like something the user opened from the desktop. Triage flagged exactly this ("Suspicious use of NtCreateUserProcessOtherParentProcess").

This relaunch only happens once. At the next logon, the autostart entry starts the DeviceSync copy directly; the backdoor sees that it is already in its directory, skips the install and goes straight to its server, so there is nothing to disguise. The spoofing comes back for every program the operator runs later: those are also launched with Explorer as their recorded parent instead of RegExt.exe.
A side effect is a useful clue for defenders. When the relocated RegExt.exe runs, the real PDFgear code inside it does its normal job and registers PDFgear as a PDF handler, pointing at C:\ProgramData\Microsoft\DeviceSync\PDFLauncher.exe. That file doesn’t exist. A PdfGear.App.1 registration pointing into DeviceSync is therefore a strong sign of this infection.
Phoning home: port 53 that isn’t DNS
The backdoor’s settings are stored lightly scrambled (each character XORed with the value 0x55), and decode to two server IPs plus a list of ports. It tries them in this order for each server:
- UDP port 53 first. That is the DNS port, which many networks let through without a second look, but the data is not DNS. Every packet starts with the four letters PRO1, the backdoor’s own protocol marker.
- then WebSocket over TLS (a long-lived, two-way connection that looks like web traffic) on ports 443, 80, 22, 21, 8080 and 1080. It accepts any certificate the server presents.
It stops at the first port where the login succeeds. If nothing answers on either server, it waits a little longer each time (1, 3, 5, 10, then 30 seconds) and starts again from the first server.

The first message is a login. The backdoor generates a fresh random key for the session and locks it with an RSA public key embedded in the DLL. Only the operator, who holds the matching private key, can unlock it; everything after that is encrypted with that session key (AES-256-GCM). The login carries the computer name, the Windows version, and a fingerprint built from the network card’s MAC address and the C: drive’s serial number.
Once logged in, the operator has just two features:
- Run a command: by default BeCtrl runs
cmd.exe /c <command>, but the operator can name a different program to start. The output goes to a randomly named.tmp,.dator.logfile in the Temp folder, is sent back in chunks, and the file is deleted. - Push a file: the operator can write any file of up to 10 MiB to any full path on the disk, with options to refuse, overwrite or rename if a file is already there.
That sounds minimal, but a remote command prompt plus a way to upload tools is all an intruder needs to look around, steal documents and bring in more capable malware.
What the sandboxes saw
Two public Triage runs (Windows 10 and Windows 11) reached the live server at 31[.]59[.]184[.]185 over UDP port 53. The packet headers of this protocol are not encrypted, so we can see each conversation’s shape even without the key: one login, one "login OK" with a session number, then a steady stream of heartbeats for the rest of the run. In neither session did the operator send a command or a file.
The ANY.RUN runs were less useful for traffic. An earlier public run shows the full install and the backdoor trying every server and port, but that run used simulated internet, so none of the requests reached the real servers. ANY.RUN does have a dedicated network rule for this backdoor ("BeCtrl PRO1 CnC handshake over UDP"), which fires on the login packet.
A wider campaign
Every copy of BeCtrl carries the operator’s RSA public key, the one that locks each session key. That key is a hard fingerprint: only someone holding the matching private key can use it. Searching VirusTotal for it found ten BeCtrl DLLs, including ours. All of them carry the same key and the same protocol code, so they belong to one operator.
They were not all hidden behind PDFgear. The operator used three different genuine, signed programs as hosts:
- PDFgear’s
RegExt.exe, version 2.1.16 in the earliest builds and 2.1.18 in later ones, with a fakeCommonLib.dll; - Greenshot (a free screenshot tool), with a fake
Greenshot.Base.dll; - Snoop (a free developer tool for inspecting Windows apps), with a fake
Snoop.Core.dll.
The Greenshot and Snoop builds don’t wait for a particular function to be called. They use a .NET feature (a "module initializer") that runs their code the moment the DLL is loaded. Each build also uses its own folder, scheduled task or registry value to survive a reboot, so defenders should not rely on the DeviceSync path alone.
The original lure names are what tie the campaign together. Each one reads like a government or think-tank document from South or Southeast Asia. The table is sorted by the date each DLL was first uploaded to VirusTotal. An upload date only tells us the file existed by then, not when it was built or sent: the last PDFgear 2.1.16 build in the table, for example, uses the same servers as the July builds but was not uploaded until November.
| First uploaded to VirusTotal | Host program | Original lure name and BeCtrl DLL (SHA-256) | C2 |
|---|---|---|---|
| 2026-07-16 | PDFgear 2.1.16 | IPRD-2026_Invitation_Letterd429ad9e8710bc1d5fd4f9354812784df3dadc81258f27847a218dce7277d422 |
139[.]84[.]169[.]184 103[.]175[.]50[.]32 |
| 2026-08-04 | PDFgear 2.1.16 | MOU USI-INDSR, TAIWANe026f584df835d58d73f8a05566213b157edb6db8858d067d1076ab457b1c4f2 |
139[.]84[.]169[.]184 103[.]175[.]50[.]32 |
| 2026-08-06 | PDFgear 2.1.16 | Nepal-India_Hydropower_Projects (program named Nepal-India_Hydropower_Cooperation_Proposal_2026.exe)692e93fd1fc9922bfea801f8ece908e40c0e299f51e907b39114461dbd3ab66d |
139[.]84[.]169[.]184 103[.]175[.]50[.]32 |
| 2026-09-16 | PDFgear 2.1.18 | MoU_USI_India_and_INDSR_Taiwan486119e45dadf2b3bafd974e0ea5e1e8e8bc35be320649bfb03ceb12406e7dcd |
139[.]84[.]169[.]184 103[.]175[.]50[.]32 |
| 2026-09-23 | Snoop | Internal_Protocol_Revised_Sept2026 (program named Internal_Protocol_Revised_Sept2026.docx.exe)cdc31b7b51538f9eb766ee21ae25fd4de7197556ac0b8b49ad39aaaa62f5c7a8 |
5[.]253[.]28[.]160 |
| 2026-09-24 | PDFgear 2.1.18 | Thai Talking Points(PM) 14 00hrs(Final version) – PWaa424e71f1c25d2455e14dadae35b380950dd4c73988183e7df88e1ed67e4d27 |
139[.]84[.]169[.]184 103[.]175[.]50[.]32 |
| 2026-10-12 | PDFgear 2.1.18 | Integrated_Assessment_Indo-Pacific_Economic_and_Security (this post’s sample)4748571d98c6af34f4967a3886f73b4421239a1203f048140d3bfdaf8aa78937 |
31[.]59[.]184[.]185 103[.]175[.]50[.]32 |
| 2026-10-17 | Greenshot | MM_Gov_Secure_Portal_Ref_992_2026e650a935e00bb51e2bcbf975a7bdfc0f03d18e9079e4bceaeff2c915d194231b |
5[.]253[.]28[.]160 |
| 2026-11-03 | Snoop | unknown (DLL seen on its own)04c729b5fd540e15952d8d9b954ea5616e9670821b914d0c063b453aface5386 |
5[.]253[.]28[.]160 |
| 2026-11-05 | PDFgear 2.1.16 | unknown (DLL seen on its own)45095e850d54f5ccf0ca20527ec6f8aed6d5d8eaa3a002255cea06c87627dd48 |
139[.]84[.]169[.]184 103[.]175[.]50[.]32 |
"MM" in the Greenshot lure is the country code for Myanmar, which fits the UTC+06:30 timestamps in our ZIP. USI (the United Service Institution of India) and INDSR (Taiwan’s Institute for National Defense and Security Research) are real defence think tanks whose names the lures borrow.
![Each BeCtrl build placed on the date it was first uploaded to VirusTotal, one row per host program. The marker shows which servers the build contacts: the switch to 31[.]59[.]184[.]185 appears only in October.](https://rogueauthority.org/wp-content/uploads/2026/11/bectrl_timeline_centered.png)
Timeline. The upload dates run from mid-July to early November 2026. PDFgear lures appear throughout; the Greenshot and Snoop builds appear from late September.
Server changes.
- The earliest PDFgear builds use
139[.]84[.]169[.]184and103[.]175[.]50[.]32. - Our October build replaces
139[.]84[.]169[.]184with31[.]59[.]184[.]185and keeps103[.]175[.]50[.]32. - The Greenshot and Snoop builds use a different server,
5[.]253[.]28[.]160.
Sandbox runs. Public Triage runs of the older PDFgear builds and of the Greenshot build reached their servers and logged in. Each session shows the same pattern: a login, a "login OK", then heartbeats. As with our sample, no session contained a command or a file.
The servers behind it
Both servers in our sample are rented Windows machines, one in India and one in Malaysia. Besides the UDP channel, they run the backdoor’s WebSocket listener on TCP port 21 (and 443 on the second server). The listener uses a self-made TLS certificate with the unusual name QFC-Server.
We searched Censys for other servers presenting a QFC-Server certificate and found three more. Together with the server from the earliest builds, that makes six:
| Server | Hosting (location) | How we linked it | Status (mid-November 2026) |
|---|---|---|---|
31[.]59[.]184[.]185 |
Ultahost (India) | C2 in this sample | online |
103[.]175[.]50[.]32 |
GB Network (Malaysia) | C2 in this sample and in the older PDFgear builds | online |
139[.]84[.]169[.]184 |
Vultr (India) | C2 in the earliest PDFgear builds | offline since late October 2026 (replaced by 31[.]59[.]184[.]185) |
5[.]253[.]28[.]160 |
Netranex (India) | Censys search; C2 in the Greenshot and Snoop builds | online, listening on all six of the backdoor’s ports |
135[.]136[.]8[.]254 |
M247 (Singapore) | Censys search; same certificate as 5[.]253[.]28[.]160 |
online, lead only |
103[.]215[.]216[.]157 |
G-Core (India) | Censys search | online, lead only |
No sample we have connects to the last two servers, so we list them as leads, not as IOCs.
The certificates also show how the servers were set up:
- July and August 2026: the first two certificates list private network addresses, such as
192.168.0.210, instead of a public server address. They were probably created on another machine and copied to the servers. One of them is installed on both5[.]253[.]28[.]160and135[.]136[.]8[.]254, which is what links those two servers. - From September 2026: each new certificate lists the public IP address of the server it is installed on, so it was created on that server. The certificate on
103[.]215[.]216[.]157follows the same pattern as the confirmed C2 servers.
Who is behind it?
We don’t know. The lures, documents about Indo-Pacific security, Myanmar government business, regional think tanks and Thai and Nepali policy, fit espionage-style targeting, and the ZIP’s timestamps were written on a computer set to UTC+06:30, Myanmar’s time zone. ANY.RUN labels the activity with a well-known China-nexus actor name, but its reasoning isn’t public. Nothing in the sample itself (servers, keys, code or build artefacts) connects it to previously documented activity we could verify, so we are not making that attribution. Code-similarity search (KesaKode) found no meaningful match to known families either.
What we couldn’t see
- Commands: the sessions we could observe carried no tasking, so we don’t know what the operator does after a successful login.
- Traffic contents: the session key is locked with the operator’s RSA key, so captured traffic can’t be decrypted. Only the unencrypted packet headers can be read.
- Delivery: we don’t know how the ZIP reached its targets (email attachment, link, or something else).
Advice
For everyone: a "report" or "assessment" that turns out to be an .exe is never a document. If an archive opens to a program with a long, official-sounding name, stop there, even if Windows shows a valid signature.
For defenders:
- Look for
C:\ProgramData\Microsoft\DeviceSync\RegExt.exe/CommonLib.dll, aLoadvalue underHKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows, or aPDFgear DeviceSyncRun value. - Hunt for a
PdfGear.App.1file association pointing intoProgramData\Microsoft\DeviceSync. - On the network, UDP port 53 to an IP that is not your resolver, with payloads starting
PRO1, is this backdoor. A TLS server certificate namedQFC-Serveris its server side. - A signed vendor EXE running from a user folder or ProgramData, next to an unsigned DLL with the same company name, deserves a closer look.
IOCs
| Type | Indicator | Notes |
|---|---|---|
| IP | 31[.]59[.]184[.]185 | C2 #1, UDP/53 "PRO1" and WSS 443/80/22/21/8080/1080 |
| IP | 103[.]175[.]50[.]32 | C2 #2, same ports |
| TLS cert (SHA-256) | 080cd3b79fa1eb7e523dab3d4edf4e703a33e8530233d99234a3b79d5cbc81aa | CN=QFC-Server on C2 #1 |
| TLS cert (SHA-256) | 6e802cd13ece669a0467ad828b40076af760ee730636a973245722948cf6807e | CN=QFC-Server on C2 #2 |
| SHA256 | 4748571d98c6af34f4967a3886f73b4421239a1203f048140d3bfdaf8aa78937 | CommonLib.dll (BeCtrl backdoor) |
| SHA256 | d74fee10090cae17655d137e060398ce6fe52eb811ebc67a439ef37297e5014f | Integrated_Assessment_Indo-Pacific_Economic_and_Security.zip |
| File name | Integrated_Assessment_Indo-Pacific_Economic_and_Security.exe | lure name for the genuine signed PDFgear RegExt.exe (no hash: legitimate file) |
| Path | C:\ProgramData\Microsoft\DeviceSync\CommonLib.dll | persisted backdoor |
| Path | C:\ProgramData\Microsoft\DeviceSync\RegExt.exe | persisted host (genuine PDFgear file) |
| Registry | HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\Load | autostart (user) |
| Registry | HKLM\Software\Microsoft\Windows\CurrentVersion\Run\PDFgear DeviceSync | autostart (SYSTEM) |
| Mutex | Local\PDFgear_DeviceSync_Mutex, Global\PDFgear_DeviceSync_Mutex | single instance |
| Network pattern | UDP payload starting 50 52 4F 31 01 ("PRO1") |
BeCtrl frame header |
| IP | 139[.]84[.]169[.]184 | C2, earlier PDFgear builds |
| IP | 5[.]253[.]28[.]160 | C2, Greenshot and Snoop builds |
| SHA256 | d429ad9e8710bc1d5fd4f9354812784df3dadc81258f27847a218dce7277d422 | CommonLib.dll (PDFgear 2.1.16 build) |
| SHA256 | e026f584df835d58d73f8a05566213b157edb6db8858d067d1076ab457b1c4f2 | CommonLib.dll (PDFgear 2.1.16 build) |
| SHA256 | 692e93fd1fc9922bfea801f8ece908e40c0e299f51e907b39114461dbd3ab66d | CommonLib.dll (PDFgear 2.1.16 build) |
| SHA256 | 45095e850d54f5ccf0ca20527ec6f8aed6d5d8eaa3a002255cea06c87627dd48 | CommonLib.dll (PDFgear 2.1.16 build) |
| SHA256 | 486119e45dadf2b3bafd974e0ea5e1e8e8bc35be320649bfb03ceb12406e7dcd | CommonLib.dll (PDFgear 2.1.18 build) |
| SHA256 | aa424e71f1c25d2455e14dadae35b380950dd4c73988183e7df88e1ed67e4d27 | CommonLib.dll (PDFgear 2.1.18 build) |
| SHA256 | e650a935e00bb51e2bcbf975a7bdfc0f03d18e9079e4bceaeff2c915d194231b | Greenshot.Base.dll (BeCtrl) |
| SHA256 | cdc31b7b51538f9eb766ee21ae25fd4de7197556ac0b8b49ad39aaaa62f5c7a8 | Snoop.Core.dll (BeCtrl) |
| SHA256 | 04c729b5fd540e15952d8d9b954ea5616e9670821b914d0c063b453aface5386 | Snoop.Core.dll (BeCtrl) |
| SHA256 | a2b65ea2e827637890d55cf681705ea4639f75fae1a185b05b8425ae6d05a617 | IPRD-2026_Invitation_Letter archive |
| SHA256 | 7ecac9d9d59a43e710a67f8377f40d5c1f50e113dc302db0f0fe377fd0558a52 | MOU USI-INDSR, TAIWAN archive |
| SHA256 | 11908bbfdea5e8d9f87fbe045816fff927d17f32b6e89e17ad2be27a57579ff8 | Nepal-India_Hydropower_Projects archive |
| SHA256 | 8507d593880dfeb8b56ca8caceb72887bcb8cd7455891e89be3860bf4d2d5e16 | MoU_USI_India_and_INDSR_Taiwan archive |
| SHA256 | b542e171c8da17958538d5e5a2b10d2fdc0e2c049d12f7f339d5e723b1238949 | Thai Talking Points(PM) 14 00hrs(Final version) – PW archive |
| SHA256 | 94275fed254303780d9034c0e6a380db59221b6f13a897bf2a9e49e0fa3b0e64 | second archive carrying this post’s CommonLib.dll |
| SHA256 | 6ed06f2e552f1e42643acf2014dcca678638a3c665d75891c70770f6f4278563 | MM_Gov_Secure_Portal_Ref_992_2026 archive |
| SHA256 | e3b3599d9efcaea3fd2c4835c31144b883b4858a9d17d8c1b3bd9a65e31181c5 | MM_Gov_Secure_Portal_Ref_992_2026.rar |
| SHA256 | d02492ac26c886235ecc6792b630787559f09116e19373edb3021687d5be012e | Internal_Protocol_Revised_Sept2026 archive |
| Path | %LOCALAPPDATA%\RegExt\, %LOCALAPPDATA%\PDFgear\Services\ |
older PDFgear builds |
| Path | %LOCALAPPDATA%\GreenshotTileCache\, %LOCALAPPDATA%\WpfVisualTreeHelper\ |
Greenshot / Snoop builds |
| Scheduled task | RegExtRegistrationTask, GreenshotTileCacheTask, SnoopVisualTreeTask | persistence, sibling builds |
| Registry | HKCU\Software\Microsoft\Windows\CurrentVersion\Run\PDFgear FileSync | autostart, PDFgear 2.1.18 build |
| Mutex | Local\PDFgear_ConfigSync_Instance, Global\{2ad2e55f-3b2b-4223-ae1a-4e552ceeb7c9}, Global\{e9d1bf88-8b81-4486-a69d-517edd7b795e} |
single instance, sibling builds |
| Public key | RSA SPKI SHA-256 544babf3c6485418c35f8db11f1110e70e06af78f690d556beec1d6008eb1df6 | operator key embedded in every BeCtrl build |
Closing
BeCtrl itself is small: it can run commands and upload files, and nothing more. What makes it work is the delivery. A familiar program loads a fake library from its own folder, and each lure is named for the people expected to open it. Across ten builds and at least four months, the operator changed host programs, folders and servers, but kept the same RSA key and the same PRO1 protocol. Those two things are the most reliable way to find new builds. If you have seen BeCtrl or the PRO1 protocol elsewhere, we would love to compare notes.
Sandbox runs: Triage 261111-sdc5fsg15r · ANY.RUN b4c1b80f