Proposed Description
Rugmi (also known as Penguish, IDAT Loader) is a multi-stage loader that uses steganographic PNG files with IDAT chunk structures to deliver encrypted payloads. The loader typically arrives via trojanized installers (MSI/WiX) or DLL sideloading chains using legitimate signed binaries. Rugmi employs a modular architecture with small stub executables (tinystub), anti-forensics modules (tinyutilitymodule with _tiny_erase_ export), and shellcode launchers (LauncherLdr64). The encrypted payload is stored in a modified PNG structure where IDAT chunk data is XOR-encrypted rather than containing valid zlib-compressed image data. Decryption uses DWORD XOR with a key stored in the payload header, followed by LZNT1 decompression via RtlDecompressBuffer. The decrypted blob contains multiple PE files concatenated sequentially, which the loader parses and loads reflectively. Final payloads observed include Stealc, Amadey, Lumma Stealer, and other info-stealers.
References
VT Collections
Existing Malpedia References (to supplement, not replace)
- Malpedia currently lists 2 references for win.rugmi — this submission adds VT collections and technical analysis detail
Vendor Reports
Technical Details
Architecture
The Rugmi loader chain consists of the following components, typically packed into a single encrypted PNG payload blob:
| Component |
Description |
Identifying Feature |
tinystub (PE 0/1) |
Initial stub executables — minimal loaders |
Internal name "tinystub" |
LauncherLdr64 (PE 2) |
Shellcode launcher / reflective PE loader |
64-bit, imports RtlDecompressBuffer |
| Final payload (PE 3) |
The actual malware (Stealc, Amadey, etc.) |
Varies by campaign |
| Config blob (PE 4) |
Configuration data for final payload |
Non-standard PE or raw data |
tinyutilitymodule x86 (PE 5) |
Anti-forensics module, 32-bit |
Exports _tiny_erase_ |
tinyutilitymodule x64 (PE 6) |
Anti-forensics module, 64-bit |
Exports _tiny_erase_ |
| Support PEs (PE 7) |
Additional modules |
Campaign-dependent |
Encrypted PNG Payload Format
The steganographic payload uses a valid or near-valid PNG container:
- PNG header (
89 50 4E 47 0D 0A 1A 0A) may or may not be present
- Multiple IDAT chunks contain XOR-encrypted data instead of zlib-compressed image data
- IEND chunk terminates the structure
- Decryption: DWORD XOR key extracted from payload header, followed by LZNT1 decompression
- Result: concatenated PE files with MZ headers at predictable offsets
Anti-Forensics
The _tiny_erase_ export in tinyutilitymodule performs anti-forensics cleanup:
- Erases loader artifacts from disk
- Overwrites memory regions
- Available in both x86 and x64 variants for cross-architecture support
Samples
| Description |
SHA256 |
| Windpoulroul.rw (encrypted PNG payload) |
29136131505ff20f221b36920e62adbd00b1342ffabb29f26338a4783c249b3f |
| Staescheck.og (sideloading target) |
b9991feabb87534bed7298bffa6ded0de511a3d6980af40123a891174cbfd92c |
| Decrypted payload blob (8 PEs) |
c89f99602d833822c0954ac0266580919816da23b2adeb820dcf8b5639afb04a |
| PE 2 — LauncherLdr64 |
8e8e43a2f0069f081f5ffb77237faebcda9a46e8f8fd0e128500e74bbc9ea3a5 |
| PE 5 — tinyutilitymodule x86 |
68bee500e0080f21c003126e73b6d07804d23ac98b2376a8b76c26297d467abe |
| PE 6 — tinyutilitymodule x64 |
b02b8547644bbfe77428e59c5ccec56c412e3c83aec44180e59110189a249956 |
MITRE ATT&CK
- T1027.003 — Obfuscated Files or Information: Steganography
- T1574.002 — Hijack Execution Flow: DLL Side-Loading
- T1140 — Deobfuscate/Decode Files or Information (DWORD XOR + LZNT1)
- T1070 — Indicator Removal (
_tiny_erase_ anti-forensics module)
- T1055 — Process Injection (reflective PE loading)
- T1218 — System Binary Proxy Execution (sideloading via legitimate signed binaries)
YARA Rules
All three rules verified against real samples with zero false positives. Rugmi_IDAT_Loader matched tinyutilitymodule x86/x64 (hit: $erase, $stub2). Rugmi_Encrypted_PNG_Payload matched both Windpoulroul.rw and Staescheck.og (424 IDAT hits each). Rugmi_TinyUtilityModule matched tinyutilitymodule x86/x64.
rule Rugmi_IDAT_Loader {
meta:
author = "Lenard"
description = "Rugmi/IDAT Loader with DWORD XOR + LZNT1 decompression"
date = "2026-03-13"
reference = "https://www.virustotal.com/gui/collection/42f198150c527b18683dfe1878692e21330deabdfc99ac68997d318093666c23"
malpedia_family = "win.rugmi"
strings:
// Anti-forensics export
$erase = "_tiny_erase_" ascii
// Rugmi stub markers
$stub1 = "tinystub" ascii wide
$stub2 = "tinyutilitymodule" ascii wide
$stub3 = "LauncherLdr" ascii wide
// LZNT1 decompression via NT API
$lznt1 = "RtlDecompressBuffer" ascii wide
// IDAT chunk parsing
$idat = "IDAT" ascii
$iend = "IEND" ascii
condition:
uint16(0) == 0x5A4D and
(
($erase) or
(2 of ($stub*)) or
($idat and $iend and $lznt1) or
($lznt1 and 1 of ($stub*))
)
}
rule Rugmi_Encrypted_PNG_Payload {
meta:
author = "Lenard"
description = "Rugmi encrypted payload with XOR-encrypted IDAT chunk structure"
date = "2026-03-13"
reference = "https://www.virustotal.com/gui/collection/42f198150c527b18683dfe1878692e21330deabdfc99ac68997d318093666c23"
malpedia_family = "win.rugmi"
strings:
$idat = "IDAT" ascii
$iend = { 49 45 4E 44 AE 42 60 82 } // IEND chunk with CRC
condition:
uint16(0) != 0x5A4D and
$idat and
$iend and
#idat > 10 and
// File uses IDAT structure but is unusually large — heuristic for encrypted payload
filesize > 500KB
}
rule Rugmi_TinyUtilityModule {
meta:
author = "Lenard"
description = "Rugmi anti-forensics module with _tiny_erase_ export"
date = "2026-03-13"
malpedia_family = "win.rugmi"
strings:
$export = "_tiny_erase_" ascii
condition:
uint16(0) == 0x5A4D and
$export and
filesize < 100KB
}
Proposed Description
Rugmi (also known as Penguish, IDAT Loader) is a multi-stage loader that uses steganographic PNG files with IDAT chunk structures to deliver encrypted payloads. The loader typically arrives via trojanized installers (MSI/WiX) or DLL sideloading chains using legitimate signed binaries. Rugmi employs a modular architecture with small stub executables (
tinystub), anti-forensics modules (tinyutilitymodulewith_tiny_erase_export), and shellcode launchers (LauncherLdr64). The encrypted payload is stored in a modified PNG structure where IDAT chunk data is XOR-encrypted rather than containing valid zlib-compressed image data. Decryption uses DWORD XOR with a key stored in the payload header, followed by LZNT1 decompression viaRtlDecompressBuffer. The decrypted blob contains multiple PE files concatenated sequentially, which the loader parses and loads reflectively. Final payloads observed include Stealc, Amadey, Lumma Stealer, and other info-stealers.References
VT Collections
Existing Malpedia References (to supplement, not replace)
Vendor Reports
Technical Details
Architecture
The Rugmi loader chain consists of the following components, typically packed into a single encrypted PNG payload blob:
tinystub(PE 0/1)LauncherLdr64(PE 2)RtlDecompressBuffertinyutilitymodulex86 (PE 5)_tiny_erase_tinyutilitymodulex64 (PE 6)_tiny_erase_Encrypted PNG Payload Format
The steganographic payload uses a valid or near-valid PNG container:
89 50 4E 47 0D 0A 1A 0A) may or may not be presentAnti-Forensics
The
_tiny_erase_export intinyutilitymoduleperforms anti-forensics cleanup:Samples
29136131505ff20f221b36920e62adbd00b1342ffabb29f26338a4783c249b3fb9991feabb87534bed7298bffa6ded0de511a3d6980af40123a891174cbfd92cc89f99602d833822c0954ac0266580919816da23b2adeb820dcf8b5639afb04a8e8e43a2f0069f081f5ffb77237faebcda9a46e8f8fd0e128500e74bbc9ea3a568bee500e0080f21c003126e73b6d07804d23ac98b2376a8b76c26297d467abeb02b8547644bbfe77428e59c5ccec56c412e3c83aec44180e59110189a249956MITRE ATT&CK
_tiny_erase_anti-forensics module)YARA Rules
All three rules verified against real samples with zero false positives.
Rugmi_IDAT_Loadermatched tinyutilitymodule x86/x64 (hit:$erase,$stub2).Rugmi_Encrypted_PNG_Payloadmatched both Windpoulroul.rw and Staescheck.og (424 IDAT hits each).Rugmi_TinyUtilityModulematched tinyutilitymodule x86/x64.