惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Hacker News: Ask HN
Hacker News: Ask HN
WordPress大学
WordPress大学
T
The Blog of Author Tim Ferriss
The GitHub Blog
The GitHub Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 聂微东
A
About on SuperTechFans
Stack Overflow Blog
Stack Overflow Blog
雷峰网
雷峰网
Microsoft Azure Blog
Microsoft Azure Blog
腾讯CDC
爱范儿
爱范儿
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 【当耐特】
V
Visual Studio Blog
有赞技术团队
有赞技术团队
U
Unit 42
D
Docker
小众软件
小众软件
F
Full Disclosure
I
Intezer
Scott Helme
Scott Helme
P
Privacy International News Feed
P
Proofpoint News Feed
Engineering at Meta
Engineering at Meta
Google DeepMind News
Google DeepMind News
B
Blog
Martin Fowler
Martin Fowler
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Vercel News
Vercel News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Spread Privacy
Spread Privacy
宝玉的分享
宝玉的分享
S
Security Affairs
www.infosecurity-magazine.com
www.infosecurity-magazine.com
月光博客
月光博客
C
Cisco Blogs
云风的 BLOG
云风的 BLOG
Schneier on Security
Schneier on Security
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Threat Research - Cisco Blogs
量子位
Hacker News - Newest:
Hacker News - Newest: "LLM"
H
Heimdal Security Blog
N
Netflix TechBlog - Medium
H
Hacker News: Front Page
P
Proofpoint News Feed
G
GRAHAM CLULEY
V
Vulnerabilities – Threatpost
S
Schneier on Security

Security Research | Blog

ClaudeFix: Shared Claude Chats Meet ClickFix | Zscaler Why Do F1 Teams Need Cybersecurity, and What Is AI’s Role? Indirect Prompt Injection Targets AI Agents | ThreatLabz Splunk Enterprise RCE (CVE-2026-20253) | ThreatLabz Edgecution: Malicious Edge Extension Backdoor | ThreatLabz SmartApeSG Supply Chain Attack Targets Okendo | ThreatLabz AI Generated ClickFix Attack Delivers SmartRAT | ThreatLabz What the ThreatLabz 2026 Phishing and Initial Access Report Means for the Public Sector | Zscaler Shai-Hulud: Miasma, Hades, & AI Scanner Evasion | ThreatLabz Zscaler ThreatLabz 2026 Phishing and Initial Access Report Technical Analysis of MLTBackdoor | ThreatLabz When the Scanner Starts Thinking: Learnings from Mythos & GPT 5.5 Cyber in Security Testing | Zscaler OpenClaw Skill Distributes Remcos & GhostLoader | ThreatLabz Tropic Trooper: AdaptixC2 + Custom Beacon | ThreatLabz Do not delete blog (testing) | Zscaler Payouts King Takes Aim at the Ransomware Throne | ThreatLabz The Alibaba Incident and Why Zero Trust Matters More Than Ever In-Memory Loader Drops ScreenConnect | ThreatLabz Supply Chain Attacks Surge in March 2026 | ThreatLabz Claude Code Leak: Critical AI Security Threat 2026 Latest Xloader Obfuscation Code & C2 Protocol | ThreatLabz CVE-2026-20131: Analysis of FMC RCE | ThreatLabz Technical Analysis of SnappyClient | ThreatLabz Middle East Conflict Fuels Cyber Attacks | ThreatLabz Dust Specter APT Targets Gov’t Officials in Iraq | ThreatLabz APT37 Adds New Tools For Air-Gapped Networks | ThreatLabz GuLoader Malware Obfuscation Techniques Analyzed GuLoader Obfuscation Analysis | ThreatLabz Technical Analysis of Marco Stealer | ThreatLabz Latest Public Sector AI Adoption Trends: What Government, Healthcare, and Education Security Teams Need to Know | Zscaler Operation Neusploit: APT28 Uses CVE-2026-21509 | ThreatLabz 7 Predictions for 2026 | Zscaler SHEETCREEP, FIREPOWER, and MAILCREEP Analysis | ThreatLabz AI is Now Default Enterprise Accelerator: Takeaways from ThreatLabz 2026 AI Security Report | Zscaler GOGITTER, GITSHELLPAD, and GOSHELL Analysis | ThreatLabz Malicious NPM Packages Deliver NodeCordRAT | ThreatLabz What’s Powering Enterprise AI in 2025: ThreatLabz Report Sneak Peek | Zscaler BlindEagle Deploys Caminho and DCRAT | ThreatLabz Technical Analysis of the BlackForce Phishing Kit | ThreatLabz React2Shell RCE Vulnerability (CVE-2025-55182) | ThreatLabz Shai-Hulud V2 Poses Risk to NPM Supply Chain | ThreatLabz Technical Analysis of Matanbuchus 3.0 | ThreatLabz In-Depth Analysis: Water Gamayun APT Multi-Stage Attack Uncovered CVE-2025-50165: Windows Graphics Component Flaw | ThreatLabz Mobile, IoT, and OT Risks Converge in the Public Sector | Zscaler Industry Attacks Surge, Mobile Malware Spreads: The ThreatLabz 2025 Mobile, IoT & OT Report | Zscaler Zscaler Discovers Vulnerability in Keras Models Allowing Arbitrary File Access and SSRF (CVE-2025-12058) | Zscaler F5 Security Incident Advisory | Zscaler Under the Radar: How Non-Web Protocols Are Redefining the Attack Surface | Zscaler SEO Poisoning Targets Ivanti VPN: Credential Theft Alert Cisco Firewall and VPN Zero Day Attacks | ThreatLabz COLDRIVER Adds BAITSWITCH and SIMPLEFIX | ThreatLabz YiBackdoor: Linked to IcedID and Latrodectus | ThreatLabz Technical Analysis of Zloader Updates | ThreatLabz Mitigating Risks from the Shai-Hulud NPM Worm | ThreatLabz Malicious PyPI Packages Deliver SilentSync RAT | ThreatLabz Technical Analysis of SmokeLoader Version 2025 | ThreatLabz Technical Analysis of kkRAT | ThreatLabz APT37: Rust Backdoor & Python Loader | ThreatLabz Anatsa’s Latest Updates | ThreatLabz Termncolor and Colorinal Explained | ThreatLabz GenAI Used to Impersonate Brazil’s Govt Websites | ThreatLabz Tracking Updates to Raspberry Robin | ThreatLabz Ransomware Surges, Extortion Escalates: ThreatLabz 2025 Ransomware Report | Zscaler China-nexus APT Targets the Tibetan Community | ThreatLabz CVE-2025-53770 | ThreatLabz Black Hat SEO Poisoning Search Engine Results For AI | ThreatLabz
China-nexus Group Targets Arabian Gulf Region | ThreatLabz
Sudeep Singh · 2026-03-13 · via Security Research | Blog

Technical Analysis

Attack chain

On 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.

Attack chain leading to deployment of PlugX.

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.

PDF lure referencing Iranian missile strikes against a US base in Bahrain.

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.

Filename

Description 

0.lnk

Stage 2 Windows shortcut.

3

Decoy PDF used as a lure.

4

TAR archive containing malicious components.

Table 1: Files extracted from the CHM

The 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.

Directory structure of 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:

  1. Allocates executable memory with VirtualAlloc.
  2. Copies the decrypted shellcode into memory.
  3. Transfers execution to the decrypted shellcode.


PlugX shellcode loader analysis

This 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_blob

The 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.

Corrupted MZ/PE headers in the decrypted PlugX backdoor.

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.

Offset

Expected structure and bytes

Actual bytes present

Description

0x00 - 0x3B

IMAGE_DOS_HEADER (4D 5A 90 00...)

ASCII: XseAJbaL...

Overwritten (60 bytes)

0x3C - 0x3F

e_lfanew pointer

78 00 00 00

Intact (4 bytes)

0x40 - 0x77

DOS Stub ("... This program cannot be run in DOS mode …")

ASCII: FSlznpPq...

Overwritten (56 bytes)

0x78 - 0x7B

PE Signature (50 45 00 00)

19 31 00 00

Overwritten (4 bytes)

0x7C - 0x8F

COFF File Header

4C 01 06 00 A4 5A...

Intact (20 bytes)

Table 2: Summary of the various fields in the corrupted PlugX MZ/PE headers.

Reflective DLL injection

The 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];
} _CONTEXT

In 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 analysis

The 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 1

First, 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.

Offset

Field

Decrypted Value

+0x10

Extensions

*.doc*|*.pdf|*.xls*|*.ppt*|*.mp3|*.wav

+0x810

Date filter

Last 30 days.

+0x828

C2 IP / Port

https://91.193.17[.]117:443

+0x0d58

Persistence Path

%ProgramFiles%\Microsoft\Display Broker

+0x0f58

Registry Name

DesktopDialogBroker

+0x1158

Service Display Name

Microsoft Desktop Dialog Broker

+0x1358

Service Description

Manages the connection and configuration of local and remote displays dialog.

+0x1558

C2 Traffic RC4 Key

VD*1^N1OCLtAGM$U

Table 3: The decrypted configuration used for this PlugX sample.

This PlugX sample supports the following C2 channels:

  • TCP
  • HTTPS
  • DOH for domain resolution using https://dns.google/dns-query
  • UDP

This PlugX sample supports the following C2 commands. These are largely similar to prior PlugX analysis, and a detailed description is available here.

Command ID

Description

0

NOP

1

Collect and send system information.

2

Request another command.

3

Trigger plugins.

4

Disconnect

5

Exit

6

Get configuration.

7

Update configuration.

8

Information about processes with injections (userinit.exe).

9

Get results of LAN scanning.

10

Proxy to other PlugX instances.

Table 4: C2 commands supported by this sample of PlugX.

This sample uses the following plugins:

Magic (hex)

Plugin Name

0x20120325

Disk

0x20120204

Process

0x20120117

Service

0x20120315

RegEdit

0x20120215

Netstat

0x20120213

Nethood

0x20120128

Option

0x20120325

PortMap

0x20120160

Screen

0x20120305

Shell

0x20120225

Telnet

0x20120323

SQL

0x20120324

Keylog

Table 5: Plugins used by this sample of PlugX.