SHA-256: 0ab9a5703d797646e0d3d4d660d7a816bf0f8d720802183b82d99544c6f9b95a

wraith: 0ab9a570 — custom XOR companion-key PE32 stub, systeminfo harvesting, raw-socket C2 surface


title: wraith: 0ab9a570 — custom XOR companion-key PE32 stub, systeminfo harvesting, raw-socket C2 surface family: wraith type: analysis tags: [pe, malware-family, c2, defense-evasion, discovery, mitre-attck, obfuscation, evasion] confidence: medium sources: [/intel/analyses/0ab9a5703d797646e0d3d4d660d7a816bf0f8d720802183b82d99544c6f9b95a.html] created: 2026-08-04 updated: 2026-08-04

Executive Summary

A 246 KB PE32 GUI with a custom multi-stage XOR decryption stub. The entry point reads a 4-byte key from %windir%\mshlpda32.dll, then decrypts .text and .data in-place with a rolling XOR + delta loop. Once decrypted, the payload executes systeminfo and ping 8.8.8.8, redirecting output to C:\Windows\temp\setup_gitlog.txt under the masquerade string PaiAuganMai Diag Utility - Setup. The import surface includes full raw-socket WSOCK32 APIs and privilege-escalation routines (AdjustTokenPrivileges, OpenProcessToken). MalwareBazaar tags this sample wraith; the same tag co-occurs with the prometei botnet family. No CAPE detonation (no Windows guest) — all behavior inferred from static analysis.

What It Is

  • SHA-256: 0ab9a5703d797646e0d3d4d660d7a816bf0f8d720802183b82d99544c6f9b95a ^[metadata.json]
  • File: PE32 executable (GUI) Intel 80386, 6 sections, 246 KB ^[file.txt]
  • Linker: MajorLinkerVersion 6.0, compiled Mon Dec 29 16:42:03 2025 UTC ^[pefile.txt:40] ^[rabin2-info.txt:11]
  • Masquerade: Version info claims Microsoft Corporation / Host Process for Windows Service / sqhost.exe ^[exiftool.json:36-42]
  • Family: wraith (OpenCTI/MalwareBazaar label). Co-tagged Prometei in the broader corpus. ^[triage.json:10] ^[entities/prometei.md]
  • Signing: Unsigned (signed: false) ^[rabin2-info.txt:27]

How It Works

Stage 1 — Companion-File Key Reading

entry0 at 0x4017a1 performs the following:

  1. Resolves %windir% via GetEnvironmentVariableA ^[r2:entry0 @ 0x4017a1].
  2. Appends \mshlpda32.dll to build a companion-file path ^[r2:entry0 @ 0x401871].
  3. Opens the companion file with CreateFileA(..., GENERIC_READ, OPEN_EXISTING) ^[r2:entry0 @ 0x401916].
  4. Reads exactly 4 bytes from the companion file into a stack buffer ^[r2:entry0 @ 0x4018f6].
  5. Closes the file handle.

If the companion file is absent, decryption cannot proceed and the binary aborts. This is a filesystem-bound decryption gate — the payload is useless without the external key file.

Stage 2 — In-Place Section Decryption

Two sequential decryption loops follow, both using a rolling XOR keyed by the 4-byte companion value plus a running delta:

Loop A — .text decryption

  • Source: encrypted bytes at 0x402000 (base of .text section)
  • Length: computed from file-read value minus a fixed bias (0x14141415)
  • Algorithm: byte[edi] ^= (key_byte + running_delta) where delta increments per iteration ^[r2:entry0 @ 0x40195f]
  • A trailing 8-byte sentinel valid_co is checked after decryption. Mismatch aborts execution ^[r2:entry0 @ 0x401a0a].

Loop B — .data decryption

  • Source: encrypted bytes at 0x435000 (base of .data section)
  • Length: computed similarly with bias 0x17171718
  • Same rolling XOR + delta algorithm ^[r2:entry0 @ 0x401b14]
  • Sentinel check repeats.

The .data section is massively inflated: VirtualSize = 0x1806AC0 (~24 MB) vs SizeOfRawData = 0x4000 (16 KB) ^[pefile.txt:146-150]. The on-disk raw data is encrypted; the 24 MB virtual region is the staging ground for the decrypted payload.

Stage 3 — Payload Execution (observed in decrypted stub)

After both sections decrypt successfully, entry0 calls three functions before exiting:

  1. fcn.00401170 — likely heap allocation / setup.
  2. fcn.004011ae — writes masquerade string to C:\Windows\temp\setup_gitlog.txt.
  3. fcn.004012a8 — creates the file C:\Windows\temp\setup_gitlog.txt with masquerade header PaiAuganMai Diag Utility - Setup\n ^[r2:fcn.004012a8].
  4. fcn.00401499 — spawns cmd.exe /c systeminfo>>C:\Windows\temp\setup_gitlog.txt&ping 8.8.8.8>>C:\Windows\temp\setup_gitlog.txt via CreateProcessA ^[r2:fcn.00401499].

This is classic system information discovery plus a connectivity probe.

Import Surface (post-decryption, resolved from IAT)

KERNEL32.dll — process/thread creation (CreateProcessA/W, CreateThread, TerminateThread), memory (VirtualAlloc, HeapAlloc, ReadProcessMemory), file ops (CreateFileA/W, ReadFile, WriteFile, CopyFileA/W, DeleteFileA/W), timing (GetTickCount, Sleep), and loader resolution (GetProcAddress, LoadLibraryA) ^[pefile.txt:318-423].

ADVAPI32.dll — token privilege escalation (OpenProcessToken, LookupPrivilegeValueA, AdjustTokenPrivileges) and user/SID queries (GetTokenInformation, LookupAccountSidA, GetUserNameW) ^[pefile.txt:433-438].

WSOCK32.dll — full raw-socket surface: socket, connect, bind, listen, accept, send, recv, sendto, recvfrom, select, gethostbyname, inet_addr, inet_ntoa, WSAStartup ^[pefile.txt:471-491].

ole32.dll / OLEAUT32.dll — COM object creation (CoCreateInstance) and VARIANT manipulation ^[pefile.txt:448-461].

Decompiled Behavior

Radare2 analysis on the encrypted binary yields hallucinated pseudocode because the .text bytes are ciphertext. The function list is dominated by numeric stubs (fcn.00401bb3, fcn.00420e37, etc.) rather than named symbols ^[r2:afl]. The entry-point decompilation, however, correctly identifies the decryption logic because the stub is plaintext — the compiler placed the decryption routine in the small .stub section (0x1000 bytes, entropy 4.96) ^[pefile.txt:85-97].

After decryption, the payload at 0x402000 would reveal the true function graph. Without the companion key file, we cannot recover it statically.

C2 Infrastructure

No C2 strings recovered statically. The WSOCK32 import surface implies raw TCP/UDP C2 communication after the payload decrypts and executes. Hostnames, IPs, ports, and command protocols are likely embedded inside the encrypted .data payload. This sample is a key-dependent decryptor — static analysis stops at the stub. ^[dynamic-analysis.md]

Interesting Tidbits

  • Companion-file dependency: The binary is non-functional without mshlpda32.dll in %windir%. This is a deliberate anti-static / anti-sandbox measure — sandboxes that only ingest the single PE will never see the real payload. ^[r2:entry0]
  • Old linker, new timestamp: Linker v6.0 is ancient (Visual C++ 6.0 era), yet the PE timestamp is Dec 2025. Either the binary was built with a deliberately retro toolchain or the timestamp is forged. ^[pefile.txt:40]
  • RWX sections: Both .stub and .text have IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE (0xE0000020) ^[pefile.txt:96-97] ^[pefile.txt:116-117]. This is unusual for legitimate software and matches packed/self-modifying malware.
  • Masquerade string: PaiAuganMai does not map to any known legitimate software vendor. It may be a campaign-specific branding string or a transliteration of a name.
  • Systeminfo staging: Redirecting systeminfo and ping output to a temp text file is a lightweight exfil staging technique — the file can be read and uploaded by a later stage.

How To Mess With It (Homelab Replication)

Goal: Reproduce a companion-file key decryptor that reads an external file for its XOR key, decrypts an embedded payload in-memory, and then executes it.

Toolchain: Visual Studio 2022 (or MinGW-w64) targeting Win32, linking with /SECTION:.text,RWE to permit self-modifying code.

Compiler flags: /GS- /O2 /MT (disable stack cookies, optimize, static CRT).

Working source snippet (simplified):

#include <windows.h>
#include <stdio.h>

#pragma section(".text", execute, read, write)

extern "C" __declspec(allocate(".text")) unsigned char encrypted_payload[4096];

int main() {
    char windir[MAX_PATH];
    GetEnvironmentVariableA("windir", windir, MAX_PATH);
    strcat(windir, "\\key.bin");

    HANDLE h = CreateFileA(windir, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
    if (h == INVALID_HANDLE_VALUE) return 1;

    BYTE key[4]; DWORD rd;
    ReadFile(h, key, 4, &rd, NULL);
    CloseHandle(h);

    for (size_t i = 0; i < sizeof(encrypted_payload); i++) {
        encrypted_payload[i] ^= (key[i % 4] + i);
    }

    ((void(*)())encrypted_payload)();
    return 0;
}

Verification step: Compile, drop a 4-byte key file next to it, and observe the decrypted memory in x64dbg at the .text base. Compare entropy before/after decryption — it should drop from ~7.7 to ~5.5.

What you learn: How malware uses filesystem gating to evade static analysis, and why sandboxes must ingest all dropped files to detonate such samples correctly.

Deployable Signatures

YARA Rule

rule wraith_companion_key_stub {
    meta:
        description = "Wraith-family custom XOR decryptor reading companion file mshlpda32.dll"
        author = "PacketPursuit"
        date = "2026-08-04"
        sha256 = "0ab9a5703d797646e0d3d4d660d7a816bf0f8d720802183b82d99544c6f9b95a"
    strings:
        $companion = "mshlpda32.dll" ascii wide
        $masq1 = "PaiAuganMai Diag Utility - Setup" ascii wide
        $masq2 = "setup_gitlog.txt" ascii wide
        $cmd1 = "systeminfo" ascii wide
        $cmd2 = "ping 8.8.8.8" ascii wide
        $api1 = "GetEnvironmentVariableA" ascii
        $api2 = "CreateFileA" ascii
        $api3 = "ReadFile" ascii
        $section_rwx = { 20 00 00 E0 }   // IMAGE_SCN_MEM_EXECUTE|READ|WRITE
    condition:
        uint16(0) == 0x5A4D and
        pe.number_of_sections == 6 and
        ($companion or $masq1) and
        2 of ($cmd*) and
        2 of ($api*) and
        // Check for RWX on first two sections
        for any i in (0 .. pe.number_of_sections - 1): (
            pe.sections[i].characteristics & 0xE0000020 == 0xE0000020
        )
}

Behavioral Hunt Query (Sigma-like pseudocode)

title: Wraith Companion File and Systeminfo Harvesting
logsource:
    product: windows
    category: process_creation
detection:
    selection_cmd:
        CommandLine|contains:
            - 'systeminfo>>C:\Windows\temp\setup_gitlog.txt'
            - 'ping 8.8.8.8>>C:\Windows\temp\setup_gitlog.txt'
    selection_file:
        TargetFilename:
            - 'C:\Windows\temp\setup_gitlog.txt'
    selection_companion:
        TargetFilename:
            - 'C:\Windows\mshlpda32.dll'
    condition: 1 of selection_*
falsepositives:
    - Unknown; the masquerade strings are unique to this family.
level: high

IOC List

Indicator Type Notes
0ab9a5703d797646e0d3d4d660d7a816bf0f8d720802183b82d99544c6f9b95a SHA-256 This sample
mshlpda32.dll Filename Companion key file (filesystem indicator)
C:\Windows\temp\setup_gitlog.txt File path Staging output file
PaiAuganMai Diag Utility - Setup String Masquerade header in staging file
systeminfo>>C:\Windows\temp\setup_gitlog.txt Command pattern Process creation telemetry
ping 8.8.8.8>>C:\Windows\temp\setup_gitlog.txt Command pattern Connectivity probe

Behavioral Fingerprint

This binary opens its own companion file %windir%\mshlpda32.dll, reads exactly four bytes, then performs a rolling XOR decryption across .text and .data sections in-place. After decryption it spawns cmd.exe /c systeminfo and ping 8.8.8.8, redirecting both outputs to C:\Windows\temp\setup_gitlog.txt. The PE has two RWX sections and a 24 MB virtual .data region with only 16 KB raw data. Network surface is raw-socket WSOCK32 with no hardcoded C2 strings.

Detection Signatures

Technique ID Evidence
System Information Discovery T1082 systeminfo execution via CreateProcessA ^[r2:fcn.00401499]
Network Service Discovery T1046 ping 8.8.8.8 connectivity probe ^[r2:fcn.00401499]
Command and Control T1071.001 Raw TCP socket surface (WSOCK32 imports) ^[pefile.txt:471-491]
Obfuscated Files or Information T1027 Multi-stage rolling XOR decryption with companion key ^[r2:entry0]
Access Token Manipulation T1134.001 OpenProcessToken → LookupPrivilegeValueA → AdjustTokenPrivileges ^[pefile.txt:433-438]
Process Injection T1055 VirtualAlloc, ReadProcessMemory, CreateProcessW present; likely used by decrypted payload ^[pefile.txt:318-423]

References

  • Artifact ID: 61d6d326-afd6-4731-b4df-160efd524f48 (OpenCTI)
  • MalwareBazaar tag: wraith
  • Related entity: prometei — co-tagged wraith in broader corpus ^[entities/prometei.md]
  • Related technique: companion-file-key-decryption — filesystem-bound decryption gate ^[techniques/companion-file-key-decryption.md]

Provenance

  • file.txt — file(1) output
  • exiftool.json — ExifTool PE metadata
  • pefile.txt — pefile parser (headers, sections, imports, version info)
  • strings.txt — raw ASCII/Unicode strings
  • rabin2-info.txt — radare2 binary summary
  • binwalk.txt — embedded-artifact scan
  • triage.json — triage pipeline metadata
  • metadata.json — artifact metadata
  • dynamic-analysis.md — CAPE status (skipped, no Windows guest)
  • Radare2 decompilation of entry0, fcn.004012a8, fcn.00401499
  • Tools: radare2 5.x, pefile, ExifTool 12.76, file(1)