IntroductionOn March 1, 2026, ThreatLabz observed new activity from a China-nexus threat actor targeting countries in the Persian Gulf region. The activity took place within the first 24 hours of the renewed conflict in the Middle East. The threat actor quickly weaponized the theme of the conflict, using an Arabic-language document lure depicting missile attacks for social engineering.The campaign used a multi-stage attack chain that ultimately deployed a PlugX backdoor variant. Based on the tools, techniques, and procedures (TTPs) observed, ThreatLabz attributes this activity to a China-nexus threat actor with high confidence, and assesses with medium confidence that it may be linked to Mustang Panda.In this blog post, ThreatLabz examines the end-to-end attack chain in depth, including Windows shortcut (LNK) and CHM-based droppers, a loader with highly obfuscated shellcode, and a PlugX backdoor.Key TakeawaysIn March 2026, ThreatLabz observed activity by a China-nexus threat actor targeting countries in the Persian Gulf region.The campaign used a multi-stage attack chain to deploy a PlugX backdoor variant on infected systems.The shellcode and PlugX backdoor used obfuscation techniques such as control flow flattening (CFF) and mixed boolean arithmetic (MBA) to hinder reverse engineering.The PlugX variant in this campaign supports HTTPS for command-and-control (C2) communication and DNS-over-HTTPS (DOH) for domain resolution. Technical AnalysisAttack chainOn March 1, 2026, ThreatLabz identified an attack chain themed around the ongoing Middle East conflict that delivered its payloads via a ZIP archive. The archive included a Windows shortcut (LNK) file that, when opened, downloaded a malicious Windows Compiled HTML Help (CHM) file from a threat actor-controlled server. The CHM content was then leveraged to deploy a multi-stage payload, progressing from a shellcode loader to heavily obfuscated shellcode, and ultimately to the installation of a PlugX backdoor variant. The attack chain is shown in the figure below.Figure 1: Attack chain leading to deployment of PlugX.As part of the lure, the attack dropped a decoy PDF containing images of missile strikes. The Arabic text in the PDF translates to “Iranian missile strikes against US base in Bahrain”. The figure below shows the decoy PDF file used in this attack.Figure 2: PDF lure referencing Iranian missile strikes against a US base in Bahrain.The following sections summarize the observed attack flow and the files involved.Stage 1 (ZIP, CHM, and LNK)The ZIP archive contains an LNK file named photo_2026-03-01_01-20-48.pdf.lnk. The LNK’s target command line uses cURL to download a malicious CHM file from hxxps://www.360printsol[.]com/2026/alfadhalah/thumbnail?img=index.png. The LNK file then uses the legitimate Windows HTML Help executable (hh.exe) with the -decompile option to extract the CHM contents. The below table summarizes the files extracted from the CHM.FilenameDescription 0.lnkStage 2 Windows shortcut.3Decoy PDF used as a lure.4TAR archive containing malicious components.Table 1: Files extracted from the CHMThe Stage 1 LNK launches the Stage 2 shortcut (0.lnk).Stage 2 (Second LNK, decoy PDF, and TAR extraction)The Stage 2 LNK performs the following actions:Moves the decoy PDF from the file named 3 to photo_2026-03-01_01-20-48.pdf (in the same directory).Treats file 4 as a TAR archive and extracts its contents into %AppData%.Executes %AppData%\BaiduNetdisk\ShellFolder.exe with the argument: –path a.The figure below shows the directory structure of the files extracted from the TAR archive.Figure 3: Directory structure of the TAR archive.Next, ShellFolder.exe uses DLL sideloading to load a malicious DLL named ShellFolderDepend.dll.ShellFolderDepend.dll analysis (shellcode loader)ShellFolderDepend.dll is a 32-bit DLL that establishes persistence, and then decrypts and executes an encrypted shellcode payload stored in Shelter.ex.The shellcode loader stores its strings in encrypted form and decrypts them at runtime using a custom index-based XOR algorithm that incorporates an additive constant, as shown below. KEY_BASE = 0x34
decrypted = []
for i, byte in enumerate(encrypted_bytes):
key = (i + KEY_BASE) & 0xFF
decrypted.append(chr(byte ^ key))
return “”.join(decrypted)To establish persistence, the DLL enumerates running processes to determine whether bdagent.exe (Bitdefender Agent) is present. Based on the result, the DLL uses one of two persistence methods:If bdagent.exe is running, the DLL uses reg.exe to set a Run entry pointing to the host binary (ShellFolder.exe) to start the malware when a user logs in: C:\Windows\System32\reg.exe ADD HKCU\Software\Microsoft\Windows\CurrentVersion\Run /reg:64 /v BaiNetdisk /t REG_SZ /d “\”%s\” –path a” /f.If bdagent.exe is not running, the DLL sets the same Run entry directly using RegSetValueExA.Before decrypting and loading the shellcode, the shellcode loader installs two inline API hooks:A 6-byte inline API hook (push hook_handler; retn) is placed on GetCommandLineW to spoof the return value as the wide-character string ShellFolder.exe 701 0, making the caller believe ShellFolder.exe was launched with the command-line arguments 701 0.A second 6-byte inline API hook (push hook_handler; retn) is placed on CreateProcessAsUserW.The hook handler first restores the original bytes at the API entry point, then calls Sleep to pause execution indefinitely, effectively preventing any child process from being created.The DLL calls the Windows Native API SystemFunction033 (RC4) to decrypt shellcode stored in Shelter.ex (located alongside the DLL) using the key 20260301@@@. The DLL then:Allocates executable memory with VirtualAlloc.Copies the decrypted shellcode into memory.Transfers execution to the decrypted shellcode.PlugX shellcode loader analysisThis stage is a 32-bit, position-independent shellcode that is heavily obfuscated with control flow flattening (CFF). The next-stage backdoor is stored, encrypted, and compressed inside this shellcode, then decrypted and decompressed at runtime. The backdoor is loaded and executed to continue the next stage of the attack.The CFF technique used in the shellcode leverages a state machine, where a state variable determines the address of the next execution block. Each basic block updates the state variable after execution and returns control to a dispatcher, which routes execution to the next block. This is a simple yet effective implementation of CFF to make reverse engineering more time consuming.All API names are stored encrypted in the shellcode and are decrypted at runtime using an index-based XOR decryption algorithm similar to the one used in the shellcode loader. The only change is the additive constant, which is 0x36 instead of 0x34.In addition, the XOR operations are obfuscated using mixed boolean arithmetic (MBA), typically using the pattern (~x & K) – (x & ~K), which is equivalent to x ^ K.The embedded payload is decrypted using the following steps:Initializes a PRNG with a 4-byte seed (0xc56dd7ea).Uses a custom PRNG to generate a key stream.The generated keystream is used to decrypt the embedded payload. The decryption algorithm can be represented as follows:seed = 0xc56dd7ea
def prng_decrypt(encrypted_data, seed):
state = seed
decrypted_blob = bytearray(len(encrypted_data))
for i in range(len(encrypted_data)):
state = (state + (state >> 3) + 0x13233366) & 0xFFFFFFFF
decrypted_blob[i] = encrypted_data[i] ^ (state & 0xFF)
return decrypted_blobThe decrypted blob begins with a 16-byte header followed by a payload compressed using LZNT1 algorithm. Below is the structure of the decrypted blob.typedef struct {
uint32_t magic; // 4 bytes: Magic header
uint32_t seed; // 4 bytes: Seed
uint32_t decompressed_size; // 4 bytes: Decompressed size
uint32_t compressed_size; // 4 bytes: Compressed size
uint8_t payload[]; // Variable length: LZNT1 compressed payload
} DecryptedBlob;The loader uses the Windows API RtlDecompressBuffer to decompress the LZNT1 compressed payload.The decompressed payload contains a corrupted MZ/PE header. The IMAGE_DOS_HEADER, DOS stub, and PE signature are corrupted with randomly generated ASCII data as an anti-forensics mechanism to evade memory forensics solutions. The figure below shows the corrupted MZ/PE headers.Figure 4: Corrupted MZ/PE headers in the decrypted PlugX backdoor.The table below summarizes which fields are corrupted in the header and which fields are left intact.OffsetExpected structure and bytesActual bytes presentDescription0x00 – 0x3BIMAGE_DOS_HEADER (4D 5A 90 00…)ASCII: XseAJbaL…Overwritten (60 bytes)0x3C – 0x3Fe_lfanew pointer78 00 00 00Intact (4 bytes)0x40 – 0x77DOS Stub (“… This program cannot be run in DOS mode…”)ASCII: FSlznpPq…Overwritten (56 bytes)0x78 – 0x7BPE Signature (50 45 00 00)19 31 00 00Overwritten (4 bytes)0x7C – 0x8FCOFF File Header4C 01 06 00 A4 5A…Intact (20 bytes)Table 2: Summary of the various fields in the corrupted PlugX MZ/PE headers.Reflective DLL injectionThe decrypted and decompressed payload is reflectively loaded by mapping all the sections to memory allocated using VirtualAlloc, performing relocations, resolving imports, and marking the memory region as executable. The first 0x20 bytes of the image base are repurposed and used as a context structure that is passed to DllMain of the reflectively loaded DLL. The PlugX encrypted configuration is present inside the shellcode and a pointer to it is stored at offset 0x14 in the context structure. The structure is defined as follows:typedef struct {
uint8_t Reserved[0x14];
uint32_t EncryptedConfigPtr; // image_base + 0x14 – Pointer to encrypted config
uint32_t EncryptedConfigSize; // image_base + 0x18 – Size of encrypted config
uint8_t Reserved[0x4];
} _CONTEXTIn this instance, the PlugX image headers serve a dual purpose. They are overwritten with junk data to evade memory forensics, and they are also reused as a context structure passed to the reflectively loaded DLL for PlugX configuration decryption.PlugX backdoor analysisThe PlugX backdoor reflectively loaded by the shellcode is also similarly obfuscated with CFF and MBA. API strings are also encrypted using an algorithm similar to the one observed in the shellcode loader and the shellcode.After receiving the encrypted PlugX configuration details via the context structure passed to DllMain by the shellcode, the configuration is decrypted in two stages.Stage 1First, the entire encrypted blob is decrypted using a custom algorithm (implemented in Python below):import struct
from ctypes import c_uint32, c_int32
def decrypt_config(data: bytes) -> bytes:
if len(data) > 3) – 0x69696969
part3.value = (old_part3 >> 5) + old_part3 + 0x66666667
part2.value = -127 * c_int32(old_part2).value + 0x65656565
part1.value = -511 * c_int32(old_part1).value + 0x33333333
key_byte = (old_part1 + 51 + part2.value + part3.value + part4.value) & 0xFF
output[i] = data[i] ^ key_byte
return bytes(output)Stage 2 (PlugX configuration decryption)The individual fields within the decrypted configuration are further decrypted using RC4 with the key qwedfgx202211. The table below summarizes the decrypted configuration used for this PlugX sample.OffsetFieldDecrypted Value+0x10Extensions*.doc*-*.pdf-*.xls*-*.ppt*-*.mp3-*.wav+0x810Date filterLast 30 days.+0x828C2 IP / Porthttps://91.193.17[.]117:443+0x0d58Persistence Path%ProgramFiles%\Microsoft\Display Broker+0x0f58Registry NameDesktopDialogBroker+0x1158Service Display NameMicrosoft Desktop Dialog Broker+0x1358Service DescriptionManages the connection and configuration of local and remote displays dialog.+0x1558C2 Traffic RC4 KeyVD*1^N1OCLtAGM$UTable 3: The decrypted configuration used for this PlugX sample.This PlugX sample supports the following C2 channels:TCPHTTPSDOH for domain resolution using dns.google/dns-queryUDPThis PlugX sample supports the following C2 commands. These are largely similar to prior PlugX analysis, and a detailed description is available here.Command IDDescription0NOP1Collect and send system information.2Request another command.3Trigger plugins.4Disconnect5Exit6Get configuration.7Update configuration.8Information about processes with injections (userinit.exe).9Get results of LAN scanning.10Proxy to other PlugX instances.Table 4: C2 commands supported by this sample of PlugX.This sample uses the following plugins:Magic (hex)Plugin Name0x20120325Disk0x20120204Process0x20120117Service0x20120315RegEdit0x20120215Netstat0x20120213Nethood0x20120128Option0x20120325PortMap0x20120160Screen0x20120305Shell0x20120225Telnet0x20120323SQL0x20120324KeylogTable 5: Plugins used by this sample of PlugX.
Threat AttributionThreatLabz attributes this attack to a China-nexus threat actor with high confidence, and we assess with medium confidence that this activity could be linked to Mustang Panda based on the following factors.Use of PlugX: The PlugX backdoor is exclusively used by China-nexus threat actors and multiple variants of PlugX are used in-the-wild. The PlugX backdoor variant used in this attack has heavy code overlaps with the DOPLUGS campaign described in 2024.Decryption keys: The RC4 key qwedfgx202211 used to decrypt the PlugX configuration in this case is the same as the one used in the DOPLUGS campaign. The RC4 key 20260301@@@ used by the shellcode loader to decrypt shellcode in this attack follows a YYYYMMDD@@@ format, similar to an RC4 key used by a China-nexus threat actor in 2024 as documented here.Social engineering lures: China-nexus threat actors like Mustang Panda are known to very quickly weaponize themes related to current events, particularly geopolitics. ThreatLabz recently observed this behavior in the LOTUSLITE backdoor (Case Study 2), where the threat actor quickly weaponized Middle East conflictrelated themes.Obfuscation techniques: While CFF and MBA are not unique to PlugX, the CFF implementation used in both the shellcode and the PlugX backdoor matches patterns ThreatLabz has observed multiple times in Mustang Panda activity, as noted here and here.Decryption routine: The PlugX configuration decryption routine closely resembles one observed in prior Exchange Server attacks attributed to the PKPLUG group (an alias of Mustang Panda). ConclusionThis campaign, attributed to a China-nexus threat actor, targeted countries in the Persian Gulf region using a multi-stage attack chain that ultimately deployed a PlugX backdoor variant. Our analysis underscores how China-nexus actors, including Mustang Panda, rapidly weaponize geopolitical events, such as the ongoing Middle East conflict, to craft timely social engineering lures.ThreatLabz urges the security community to exercise caution when opening unsolicited files or clicking links that claim to provide news or updates related to the Middle East conflict.Zscaler CoverageZscaler’s multilayered cloud security platform detects indicators related to the targeted attacks mentioned in this blog at various levels with the following threat names:Win32.Backdoor.PlugXIndicators Of Compromise (IOCs)File indicatorsHashesFilenameDescription20eb9f216a1177ee539a012e6301a93e43c36b06573aeadabb55fd46c55a68c41a16ecc7733a0a0ead4fc38173d7e30c7f2e14442ede32507e8adcbb8d3bd719fd2079d0photo_2026-03-01_01-20-48.zipZIP archive containing the LNKEb27bbc29b36ae9c66970654925d8c3bE3dc5ef72a9d08790f2f21726fa270b77dea3803fa3a1153018ac1e1a35a65e445a2bad33eac582c225cf6c38d0886802481cd43photo_2026-03-01_01-20-48.pdf.lnkStage 1 malicious Windows shortcut LNK fileB92e4615bb8026a593f0a72451285140E15c3ff555a30dff5b66333492eed43e07ec72a110df3c46624c416f44764d7903b8079bc797c967284afc5bc333eeba0fdbba180.lnkStage 2 malicious Windows shortcut LNK fileDa91acba97f7d2935149d80142df8ec9Ec955e2b6874159c63578d6bb85fe67117d45508e50a4069e173256498e9e801b8f0dcda5a217290869300055ad8a854d4ea210c3Decoy PDF file used as a social engineering lureA158f22a6bf5e3678a499c3a2b039b16A5e42ac01e59d61c582e696edfde76452e35a43c5adae26409c6576f95270ce9ca3877df3ee60849c18540fd92c0c9c974ba2f6d4TAR archive4f6ea828ab0456539cf7d79af90acf8731817d5baa9cc6ff22c172652ef312b7300c18a2c78eb1cecef5f865b6d150adcf67fa5712c5a16b94f1618c32191e61fbe69590ShellFolderDepend.dllShellcode loaderBf298f5b0ea62640f538922b32b8c3ed2d70a3f331278b490361d3f7274082f69184209d1ddbed0328a60bb4f725b4ef798d5d14f29c04f7ffe9a7a6940cacb557119a1cShelter.exEncrypted shellcode93a98995ebfd672793b3413606211fa3537044b0c8930522aa1bbbf6220077b36abcdf54014192c07267294116115d867b1dd48d851f0fa4c011cd96e4c5a5f81a6d1de3N/ADecrypted shellcode43622a9b16021a5fb053e89ea5cb2c4cBdf4b77508c9295a2e70736ee6d689722f67802eef7a813124fd19d11bb5d944cb95779f5fe09ff5a18c26399002759d4b0d66e7N/ADecrypted and decompressed PlugX backdoorNetwork indicatorsTypeIndicatorURL hosting the CHM filehxxps[:]//www.360printsol[.]com/2026/alfadhalah/thumbnail?img=index.pngC2 IP91.193.17[.]117MITRE ATT&CK FrameworkIDTactic, TechniqueDescriptionT1587.001Develop Capabilities: MalwareThe threat actor developed custom PlugX loaders.T1588.001Resource Development: Obtain Capabilities, MalwareThe threat actor used the PlugX backdoor, a known backdoor commonly used by China-nexus threat actors.T1608.001Resource Development: Stage Capabilities: Upload MalwareThe threat actor staged a malicious CHM file on a threat actor-controlled server.T1566Initial Access: PhishingThe threat actor phished users in the GCC region with an archive containing a lure referencing Iranian missile strikes against a US base in Bahrain.T1204.002Execution: User Execution: Malicious FileThe attack chain is initiated when a victim opens a malicious LNK file named photo_2026-03-01_01-20-48.pdf.lnk which was delivered inside a ZIP archive.T1059.003Execution: Command and Scripting Interpreter: Windows Command ShellThe initial LNK file’s target command-line uses cURL to download a malicious CHM file and to extract its contents.T1106Execution: Native APIShellFolderDepend.dll calls VirtualAlloc for shellcode and SystemFunction033 for RC4 decryption. PlugX uses RtlDecompressBuffer for payload decompression. T1547.001Persistence: Boot or Logon Autostart Execution: Registry Run Keys / Startup FolderShellFolderDepend.dll adds a Run key (BaiNetdisk) using reg.exe or RegSetValueExA to point to the malicious ShellFolder.exe.T1543.003Persistence: Create or Modify System Process: Windows ServiceThe PlugX backdoor payload is configured to operate as a Windows service (“Microsoft Desktop Dialog Broker”).T1548.002Privilege Escalation: Abuse Elevation Control Mechanism: Bypass User Account ControlPlugX contains code to abuse the Fodhelper UAC bypass technique to gain elevated privileges.T1036.007Defense Evasion: Masquerading: Double File ExtensionThe shortcut file was named photo_2026-03-01_01-20-48.pdf.lnk to appear as a benign PDF.T1036.005Defense Evasion: Masquerading: Match Legitimate Resource Name or LocationThe malicious LNK extracts components into %AppData%\BaiduNetdisk\ to mimic a legitimate cloud storage application.T1140Defense Evasion: Deobfuscate/Decode Files or InformationDecrypts shellcode using RC4, decrypts API names via XOR, decompresses payloads using LZNT1, and decrypts configurations in multiple stages.T1036.004Defense Evasion: Masquerading: Masquerade Task or ServicePlugX uses service names like “Microsoft Desktop Dialog Broker” to mimic legitimate Microsoft services.T1218.001Defense Evasion: System Binary Proxy Execution: Compiled HTML FileThe hh.exe file was used to conceal malicious components.T1620Defense Evasion: Reflective Code LoadingLoads the PlugX DLL directly into memory without writing it to disk.T1574.001Defense Evasion: Hijack Execution Flow: DLLUses DLL sideloading to load ShellFolderDepend.dll via ShellFolder.exe.T1027Defense Evasion: Obfuscated Files or InformationThe malware used in this attack utilized various code obfuscation techniques like CFF and MBA.T1027.002Defense Evasion: Obfuscated Files or Information: Software PackingThe shellcode acts as a packer, decrypting and decompressing the final backdoor at runtime.T1027.007Defense Evasion: Obfuscated Files or Information: Dynamic API ResolutionThe malware used in this attack stores API names in encrypted format and resolves imports dynamically at runtime.T1027.009Defense Evasion: Obfuscated Files or Information: Embedded PayloadsThe final backdoor is embedded in shellcode. The CHM file contains an embedded TAR archive with malicious components.T1027.013Defense Evasion: Obfuscated Files or Information: Encrypted/Encoded FileThe malwares used in this attack utilized RC4 and custom PRNG algorithms to encrypt files, shellcode, and configurations.T1027.015Defense Evasion: Obfuscated Files or Information: CompressionThe loader uses LZNT1 compression for the next-stage payload.T1027.016Defense Evasion: Obfuscated Files or Information: Junk Code InsertionThe malware used MBA, inserting useless junk operations to obscure program logic.T1082Discovery: System Information DiscoveryPlugX supports a System Fingerprint command to gather operating system and hardware details.T1518.001Discovery: Software Discovery: Security Software DiscoverySpecifically checks for the presence of Bitdefender Agent (bdagent.exe).T1083Discovery: File and Directory DiscoverySearches for specific extensions (*.doc*, *.pdf*, etc.) and uses a Disk plugin.T1071.001Command and Control: Application Layer Protocol: Web ProtocolsPlugX establishes C2 communication via HTTPS on port 443.T1572Command and Control: Protocol TunnelingPlugX has the capability to use DNS-over-HTTPS (DOH) using dns.google.T1090.001Command and Control: Proxy: Internal ProxyPlugX has the capability to relay C2 traffic between PlugX instances (Command ID 10).T1573.001Command and Control: Encrypted Channel: Symmetric CryptographyPlugX uses RC4 with a static key (VD*1^N1OCLtAGM$U) to encrypt C2 traffic.T1573.002Command and Control: Encrypted Channel: Asymmetric CryptographyVarious components in the attack chain use SSL/TLS within HTTPS for secure key exchange.T1095Command and Control: Non-Application Layer ProtocolPlugX supports TCP and UDP for C2 communications.T1105Command and Control: Ingress Tool TransferThe LNK file uses cURL to download a malicious CHM file from a remote URL.
First seen on securityboulevard.com
Jump to article: securityboulevard.com/2026/03/china-nexus-threat-actor-targets-persian-gulf-region-with-plugx/
![]()

