943cf1ebeb089abcd2e6ff0c2bfefa4631855948ab3ef3811cba1c635aa389d1ghostpulse: 943cf1eb — Confirmed twin of 833bffd0 with individualized texture_mon.yaml encrypted payload
Executive Summary
A 12 MB 7-Zip SFX archive that is a byte-identical structural twin of the previously analyzed 833bffd0 sample. The outer SFX stub, inner Qt5 payload (CommunicMes.exe), and key/config sidecar (physics1024.map) all hash identically. The only delta is the 9.7 MB texture_mon.yaml encrypted payload, whose SHA-256 differs — confirming a builder that reuses the same loader but generates per-sample individualized ciphertext. No CAPE detonation available (no Windows guest); all behavior inferred from static extraction and hash comparison.
What It Is
- Outer container: 7-Zip SFX mod (
7ZSfxMod_x86.exe, Oleg Scherbakov, 2010), MSVC linker v8.0, compiled 2010-06-27 ^[file.txt] ^[exiftool.json] - Archive: LZMA-compressed 7z solid archive embedded at offset
0x2df4a; 11 files extracted ^[binwalk.txt] ^[sfx-config.json] - Inner payload:
CommunicMes.exe— PE32+ x64, MSVC 14.26 (VS 2019), 8 sections, no exports, byte-identical to833bffd0inner payload (SHA-256dd4469b6...) ^[file.txt] ^[rabin2-info.txt] - PDB path:
D:\EPM\EPM19.9_release\Output\Release_x64\PELetterAdjust.pdb— EaseUS Partition Manager masquerade ^[strings.txt:1] - Sidecar files:
texture_mon.yaml(9.7 MB, entropy 7.91) — individualized per-sample encrypted payload vs833bffd0;physics1024.map(34 KB, entropy 5.49) — identical key/config sidecar to833bffd0^[extracted/entropy-analysis]
How It Works
Stage 1 — SFX Extraction
Identical to 833bffd0: silent extraction to %TEMP% via RunProgram="%%T\\CommunicMes.exe" with Progress=no and GUIFlags=8 (suppress GUI). ^[sfx-config.json] The 7z archive contains the Qt5 runtime, MSVC redistributables, and three attacker-controlled files: CommunicMes.exe, texture_mon.yaml, and physics1024.map.
Stage 2 — Qt5 Payload Execution
CommunicMes.exe is a Qt5 GUI application compiled for x64. Import surface: Qt5Core (QProcess/QFile/QDir/QStorageInfo APIs), KERNEL32, SHELL32, and the UCRT/VCRT runtime. ^[rabin2-info.txt] No direct crypto, networking, or injection imports — malicious behavior is dynamically resolved or implemented inside the encrypted sidecar files. radare2 analysis reveals 562 functions, standard MSVC C++ CRT initialization, and QProcess::startDetached usage for child process spawning. ^[r2:analysis-output]
Stage 3 — Encrypted Sidecar Loading
texture_mon.yaml is 9.7 MB with Shannon entropy of 7.91 (near-random), consistent with encrypted payload data. It is the only per-sample individualized artifact — its SHA-256 differs from 833bffd0 (597f95aa... vs 840c209e...), while all other archive contents are byte-identical. physics1024.map (34 KB, entropy 5.49) is unchanged, suggesting it serves as a shared decryption key, configuration header, or IV/key-schedule file. The inner executable references .texture_mon.yaml in its .rdata section, confirming runtime file-open pattern. ^[strings.txt]
Decompiled Behavior
radare2 analysis of CommunicMes.exe (identical to 833bffd0 inner payload) shows standard MSVC C++ CRT initialization (__initterm_e, __initterm) followed by Qt5 framework calls. The most relevant behavioral indicator is QProcess::startDetached for child process execution, which can bypass conventional parent-child telemetry. No direct obfuscation, anti-debug, or control-flow flattening is present in the inner binary. ^[r2:analysis-output]
Notable strings in .rdata (identical to 833bffd0):
X:\Program Files\Other\Tools\EPM.bat— batch path for EaseUS masqueradediskpart.exe /s %1,assign letter=%1,remove letter=%1— disk-partition manipulation commandsTexturePattern,.texture_mon.yaml— confirms runtime reference to encrypted payload file
C2 Infrastructure
No static C2 indicators recovered. Network connectivity, if any, is expected to be encrypted inside texture_mon.yaml and decrypted at runtime by the Qt5 application. The absence of observable C2 strings is consistent with a modular loader pattern where per-sample C2 config is delivered inside the individualized sidecar.
Interesting Tidbits
-
Builder confirmation: The fact that
CommunicMes.exeandphysics1024.mapare byte-identical across two distinct outer samples (833bffd0and943cf1eb) confirms the GhostPulse builder uses a fixed inner-loader template and re-encrypts only the payload sidecar per distribution. This is economical — one compiled loader, many campaigns. ^[extracted/hash-comparison] -
Per-sample payload differentiation:
texture_mon.yamlis the individualized component. Its SHA-256 differs, but its size (9.7 MB vs 9.8 MB in833bffd0) and entropy (~7.9) remain consistent, suggesting the builder pads or re-encrypts a common inner payload with per-sample keys. ^[extracted/hash-comparison] -
Family scale: This is the 50th confirmed GhostPulse sibling in the PacketPursuit corpus. With 49 prior siblings and the builder reusing the same loader template, the true distribution count is likely far higher. ^[ghostpulse]
-
EaseUS masquerade depth: The PDB path references EPM19.9 (EaseUS Partition Master v19.9), a real product. The diskpart strings and partition logic thematically reinforce the masquerade. ^[strings.txt]
-
Qt5 as evasion surface: Bundling the entire Qt5 runtime (~6 MB for Qt5Core.dll alone) inflates the payload and buries malicious imports inside a massive legitimate library surface. ^[rabin2-info.txt]
How To Mess With It (Homelab Replication)
Identical to 833bffd0 — see the ghostpulse entity page for the full build recipe. Key takeaways:
- Build a Qt5 C++ GUI app with MSVC 2019+ linking dynamically against Qt5Core.dll
- Open a hardcoded sidecar file from the application directory, decrypt in-memory, and reflectively execute
- Compile with
/SUBSYSTEM:WINDOWS - Package with 7-Zip SFX (
7zSfxMod) usingRunProgram="%%T\\YourApp.exe" - Bundle Qt5Core.dll, UCRT, VCRT, and your encrypted sidecar
Per-sample builder variant: The builder reuses the same CommunicMes.exe and physics1024.map but generates a fresh texture_mon.yaml per campaign. To replicate this pattern, keep the loader and key file static, and re-encrypt the inner payload with a campaign-specific key.
Deployable Signatures
YARA Rule — GhostPulse SFX Loader (Twin Detection)
rule GhostPulse_SFX_Qt5_Loader_Twin {
meta:
description = "Detects GhostPulse family 7-Zip SFX dropper with Qt5 inner payload and individualized texture_mon.yaml"
author = "PacketPursuit"
date = "2026-07-30"
sha256 = "943cf1ebeb089abcd2e6ff0c2bfefa4631855948ab3ef3811cba1c635aa389d1"
strings:
$sfx1 = "7ZSfxMod" ascii
$sfx2 = "7-Zip SFX" wide
$runprog = /RunProgram="%%T\\[A-Za-z]{5,20}\.exe"/ wide
$qt5 = "Qt5Core.dll" ascii
$yaml = ".texture_mon.yaml" ascii
$map = ".physics1024.map" ascii
condition:
uint16(0) == 0x5A4D and
filesize > 5MB and filesize < 25MB and
($sfx1 or $sfx2) and
$runprog and
($qt5 or $yaml or $map)
}
YARA Rule — GhostPulse Individualized Sidecar
rule GhostPulse_Individualized_TextureMon {
meta:
description = "Detects GhostPulse individualized encrypted payload sidecar texture_mon.yaml"
author = "PacketPursuit"
date = "2026-07-30"
strings:
$yaml = ".texture_mon.yaml" ascii
$tex = "TexturePattern" ascii
condition:
uint16(0) == 0x5A4D and
pe.machine == pe.MACHINE_AMD64 and
any of ($yaml, $tex)
}
Behavioral Hunt Query (Sigma)
title: GhostPulse Qt5 Encrypted Sidecar Execution (Twin Variant)
logsource:
category: process_creation
product: windows
detection:
selection:
CommandLine|contains:
- 'CommunicMes.exe'
ParentImage|endswith:
- '\7zSfxMod.exe'
- '\7z.exe'
sidecar:
- TargetFilename|endswith:
- 'texture_mon.yaml'
- 'physics1024.map'
condition: selection or sidecar
falsepositives:
- Unknown
level: high
IOC List
| Type | Value | Context |
|---|---|---|
| SHA-256 (outer) | 943cf1ebeb089abcd2e6ff0c2bfefa4631855948ab3ef3811cba1c635aa389d1 |
7-Zip SFX dropper (this sample) |
| SHA-256 (inner) | dd4469b6bb8bf5ce4dd8560cecf1cfc16272f18f26960a4569d636b8b02aec96 |
CommunicMes.exe (confirmed twin) |
| SHA-256 (sidecar, individualized) | 597f95aad7e8f81cacd60a1d2ea7872e8507b197c39ecb89c5514534561d741e |
texture_mon.yaml (unique to this sample) |
| SHA-256 (sidecar, shared) | cccf57e73ad1d23b674c0c6a64d10fc108a4dce2b569f09db86595c0e06845a8 |
physics1024.map (identical to 833bffd0) |
| PDB path | D:\EPM\EPM19.9_release\Output\Release_x64\PELetterAdjust.pdb |
Masquerade artifact |
| File paths | %TEMP%\CommunicMes.exe |
Extracted payload |
| File paths | %TEMP%\texture_mon.yaml |
Individualized encrypted sidecar |
| File paths | %TEMP%\physics1024.map |
Shared key/config sidecar |
Detection Signatures
| Technique | ATT&CK ID | Evidence |
|---|---|---|
| Masquerading | T1036.005 | EaseUS Partition Manager PDB path and diskpart strings |
| Ingress Tool Transfer | T1105 | 7-Zip SFX extracts payload from embedded archive |
| Encrypted Payload | T1027.002 | texture_mon.yaml (9.7 MB, entropy 7.91) — individualized per sample |
| Data Obfuscation | T1027 | physics1024.map suspected shared key material |
| Process Injection (inferred) | T1055 | QProcess::startDetached used for child execution |
References
- ghostpulse — Entity page for this family
- /intel/analyses/833bffd0ff2291001e0cb62f529cf947ba2753fa5888820848a2014eda2dc334.html — First detailed analysis (confirmed twin)
- Sample source: OpenCTI / MalwareBazaar, artifact ID
f4c70c52-ef44-42bf-a89f-10f2002b3243 - EaseUS Partition Manager (legitimate): https://www.easeus.com/partition-manager/
- 7-Zip SFX Mod (legitimate): https://github.com/chrislake/7zsfxmod
Provenance
- Outer binary analysis:
filev5.44,exiftoolv12.76,pefilePython module,binwalkv2.3.4,radare2v5.x - Archive extraction:
7zv23.01, offset 188234 (0x2df4a) - Inner binary analysis:
filev5.44,radare2v5.x (562 functions, level-2 analysis) - Entropy calculation: Python 3
math.entropyvia custom script - Hash comparison: Python 3
hashlib.sha256across extracted files - Capa: signatures path missing — no results ^[capa.txt]
- Floss: CLI argument error — no results ^[floss.txt]
- Dynamic analysis: Skipped — CAPE has no Windows guest available for PE32 platform ^[dynamic-analysis.md]