XWorm v3.1 — Static Analysis & Config Decryption

TLP: WHITE — Educational & defensive research only.
All analysis was performed in an isolated environment. No live C2 interaction was initiated.

Analyst: Mohamed Aziz
Environment: FlareVM on VirtualBox (network-isolated during static phase)
Sample SHA-256: b4ae0aa38f19cf8c917061bcd03ee501ec97faac1582d0b8ca488f8c97c00a53


Sample Overview

Property Value
Filename xworm.exe
SHA-256 b4ae0aa38f19cf8c917061bcd03ee501ec97faac1582d0b8ca488f8c97c00a53
Size 35.50 KB
Architecture PE32 (32-bit), GUI subsystem
Compiler VB.NET → .NET Framework 4.0 (CLR v4.0.30319)
Packer / Loader In-memory loading via Assembly.Invoke (entropy ≈ 7.47)
VT Detections 54 / 66 (March 2026)
Family Tags XWorm, AsyncRAT-derived, MSIL Trojan

XWorm is a commercially sold Remote Access Trojan (RAT) that has been active since at least 2022. This sample belongs to the v3.0–5.0 family branch. It is written entirely in VB.NET and communicates over raw TCP using AES-ECB encrypted commands with a custom delimiter protocol.


🔍 Initial Triage — Detect It Easy

DIE Scan

Running the sample through Detect It Easy v3.10 reveals several key attributes:


⚙️ Decompilation — dnSpy Structure

Assembly Tree

Using dnSpy v6.5.1 reveals a clean, single-namespace structure. The core logic is distributed across classes like AlgorithmAES for crypto, ClientSocket for network, and XLogger for keylogging.


🛡️ Static Analysis

AlgorithmAES — Config Decryption

The AlgorithmAES class implements a custom AES-256-ECB cipher. The 256-bit key is derived from an MD5 hash of the mutex string (s5GEomZ0YdjtQjkV), duplicated with a one-byte overlap.

AlgorithmAES

Settings Class — Encrypted Configuration

All operator-defined settings are stored as Base64-encoded AES ciphertext in the Settings class.

Settings

public class Settings
{
    public static string Host     = "+WYZT6uQ5vRq9XrQGTnfkOK8rg+eK6AFZ18W0DFqvBo=";
    public static string Port     = "IdAbp9SVeK+ongr2W9NzIA==";
    // ...
    public static string Mutex    = "s5GEomZ0YdjtQjkV";
}

Persistence Mechanisms

XWorm establishes persistence through three distinct channels:

  1. Registry Run Key (HKCU): Registers itself under ...\Windows\CurrentVersion\Run.
  2. Startup Folder Shortcut (.lnk): Creates a shortcut in the Startup folder and locks the file handle.
  3. AppData Binary Drop: Copies itself to %AppData%.

🔑 Configuration Decryption

Below is the full decrypted configuration extracted from this sample using my custom Python script:

Setting Decrypted Value Purpose
Host jerrymac2008.duckdns.org Primary C2 domain
Port 4078 TCP port
KEY <123456789> AES key for C2 traffic
SPL <Xwormmm> Command delimiter
Mutex s5GEomZ0YdjtQjkV Mutex & AES key source

🐍 Python Decryptor Script

I wrote a replica of XWorm's AlgorithmAES logic to automate configuration extraction.

import hashlib, base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad

def make_xworm_key(mutex: str) -> bytes:
    md5 = hashlib.md5(mutex.encode("utf-8")).digest()
    key = bytearray(32)
    key[0:16]  = md5
    key[15:31] = md5   # one-byte overlap
    return bytes(key)

def xworm_decrypt(b64_str, mutex):
    key = make_xworm_key(mutex)
    data = base64.b64decode(b64_str)
    cipher = AES.new(key, AES.MODE_ECB)
    return unpad(cipher.decrypt(data), 16).decode("utf-8")

📡 Network & C2 Protocol

XWorm uses a length-prefixed protocol: [ASCII length][0x00][AES-128-ECB ciphertext].

Registration Beacon (Decrypted)

Upon connection, the malware sends an INFO packet containing victim details:

INFO<Xwormmm>9ECAF35B7A5D26FAB5DC<Xwormmm>flare<Xwormmm>Windows 10 Pro 64bit<Xwormmm>XWorm V3.1...

Command Dispatcher

The Messages.Read() method dispatches over 20 commands, including:


🖥️ Dynamic Analysis

Testing on FlareVM with FakeNet-NG confirmed the persistence and network predictions.

Keylogger Output

The keylogger successfully captured keystrokes and window titles in %TEMP%\Log.tmp, including navigation attempts by the analyst.


🛑 YARA Rule

rule XWorm_v3_v5_VBNet
{
    meta:
        description = "Detects XWorm v3.0–3.1 samples"
        author      = "Mohamed Aziz"
    strings:
        $mutex     = "s5GEomZ0YdjtQjkV" wide ascii
        $class1    = "AlgorithmAES" wide ascii
        $log_path  = "Log.tmp" wide ascii
    condition:
        uint16(0) == 0x5A4D and ($mutex and 2 of them)
}

🛠️ Tools & Techniques


🔗 External Resources