0ab9a5703d797646e0d3d4d660d7a816bf0f8d720802183b82d99544c6f9b95awraith: 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-taggedPrometeiin 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:
- Resolves
%windir%viaGetEnvironmentVariableA^[r2:entry0 @ 0x4017a1]. - Appends
\mshlpda32.dllto build a companion-file path ^[r2:entry0 @ 0x401871]. - Opens the companion file with
CreateFileA(..., GENERIC_READ, OPEN_EXISTING)^[r2:entry0 @ 0x401916]. - Reads exactly 4 bytes from the companion file into a stack buffer ^[r2:entry0 @ 0x4018f6].
- 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.textsection) - Length: computed from file-read value minus a fixed bias (
0x14141415) - Algorithm:
byte[edi] ^= (key_byte + running_delta)wheredeltaincrements per iteration ^[r2:entry0 @ 0x40195f] - A trailing 8-byte sentinel
valid_cois checked after decryption. Mismatch aborts execution ^[r2:entry0 @ 0x401a0a].
Loop B — .data decryption
- Source: encrypted bytes at
0x435000(base of.datasection) - 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:
fcn.00401170— likely heap allocation / setup.fcn.004011ae— writes masquerade string toC:\Windows\temp\setup_gitlog.txt.fcn.004012a8— creates the fileC:\Windows\temp\setup_gitlog.txtwith masquerade headerPaiAuganMai Diag Utility - Setup\n^[r2:fcn.004012a8].fcn.00401499— spawnscmd.exe /c systeminfo>>C:\Windows\temp\setup_gitlog.txt&ping 8.8.8.8>>C:\Windows\temp\setup_gitlog.txtviaCreateProcessA^[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.dllin%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
.stuband.texthaveIMAGE_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:
PaiAuganMaidoes 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
systeminfoandpingoutput 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
wraithin 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) outputexiftool.json— ExifTool PE metadatapefile.txt— pefile parser (headers, sections, imports, version info)strings.txt— raw ASCII/Unicode stringsrabin2-info.txt— radare2 binary summarybinwalk.txt— embedded-artifact scantriage.json— triage pipeline metadatametadata.json— artifact metadatadynamic-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)