796a371d25a0a76a03f74fddd75c3774077d1329b7a27366a1bf9c6dfecd882cus0file: 796a371d — MSVC 14.50 x64 encrypted-overlay dropper, GDCRYPT custom loader framework
Executive Summary
PE32+ x64 dropper/loader with a 608 KB encrypted overlay (82 % of file) and a custom decryption/mapping stub branded GDCRYPT!kernel32. Heavy anti-sandbox gating (QPC timing, RAM, CPU count, path checks) before reading its own overlay, decrypting the inner payload, and mapping it reflectively via direct ntdll primitives. Distributed via the gcleaner multi-payload bundler pipeline. Static-only analysis; CAPE skipped due to no Windows guest.
What It Is
- SHA-256:
796a371d25a0a76a03f74fddd75c3774077d1329b7a27366a1bf9c6dfecd882c - Size: 744,566 bytes (727 KB on disk) ^[file.txt]
- Format: PE32+ executable (GUI) x86-64, 6 sections ^[file.txt]
- Timestamp: Stomped to
Tue Jul 3 06:17:46 2007 UTC— falsified ^[pefile.txt:38] - Linker: MSVC 14.50 (Visual Studio 2019/2022 era) ^[exiftool.json]
- Signed: Unsigned ^[rabin2-info.txt]
- Overlay: 608,374 bytes appended at file offset
0x21400(high entropy, encrypted) ^[terminal: python overlay check] - Distribution label:
dropped-by-gcleaner/us0.filevia OpenCTI ^[metadata.json]
How It Works
On execution, the stub enters a hardening routine at fcn.1400013f0 ^[r2:fcn.1400013f0] that performs a cascade of environment checks before touching the payload:
- QPC frequency/counter timing gate — Calls
QueryPerformanceFrequency,QueryPerformanceCounter,Sleep(25), then measures elapsed time. If the ratio is outside a hardcoded threshold, aborts. ^[r2:fcn.1400013f0] - Uptime gate —
GetTickCount64must return >0x8f21(~36 seconds) or the binary exits. Defeats fresh-snapshot sandboxes. ^[r2:fcn.1400013f0] - RAM gate —
GlobalMemoryStatusExmust report ≥ 256 MB or abort. ^[r2:fcn.1400013f0] - CPU count gate —
GetSystemInfochecks processor count; single-processor systems abort. ^[r2:fcn.1400013f0] - Path gate — Converts its own module path to uppercase, then checks for
PROGRAMDATA,PROGRAM FILES, or\WINDOWS\. If any match, aborts. This ensures it only runs from user-writable paths such as%TEMP%. ^[r2:fcn.1400013f0] ^[strings.txt:159-162]
If all gates pass, the stub creates a mutex (unnamed), releases it, then enters a jittered Sleep loop based on GetTickCount modulo arithmetic before proceeding to payload extraction.
Payload Extraction & Reflective Mapping
The inner payload lives in the 608 KB overlay. The stub reads its own file via CreateFileA/GetFileSize/ReadFile ^[r2:fcn.1400013f0] (xref to GetFileSize at 0x1400018e0), decrypts the overlay in memory, and maps it reflectively. Evidence for reflective mapping:
- Direct ntdll imports resolved at runtime:
NtAllocateVirtualMemory,NtProtectVirtualMemory,NtFreeVirtualMemory,RtlAddFunctionTable^[strings.txt:156-159] VirtualAlloc/VirtualProtect/CreateProcessAin the standard IAT ^[r2:list_imports]FlushInstructionCache— typical after self-modifying or injected code ^[r2:list_imports]GetProcAddress/LoadLibraryA— dynamic API resolution for payload dependencies ^[r2:list_imports]
The GDCRYPT!kernel32 marker at .rdata offset 0x145d0 (RVA 0x153d0) ^[terminal: python pefile scan] strongly suggests the decryption stub belongs to a custom crypter/loader framework the author calls GDCRYPT. A second occurrence tGDCRYPT! appears nearby ^[r2:list_strings].
Payload Naming Convention
The string %s%s.exe at RVA 0x153a0 ^[strings.txt:163] implies the inner payload is written to disk with a two-part filename (e.g., <dir><name>.exe), likely under %TEMP% after decryption.
.NET Fallback Indicator
mscoree.dll and CorExitProcess appear in strings ^[strings.txt:231], suggesting the inner payload may be a .NET assembly and the loader handles CLR bootstrap if reflection fails.
Decompiled Behavior
Radare2 analysis (level 3) recovered 532 functions. Entry point entry0 at 0x140001d90 ^[r2:entry0] delegates to fcn.140001de0 (initialisation) and fcn.1400013f0 (main payload orchestrator). The latter is the most interesting surface — it contains all anti-sandbox gates, overlay read logic, and the jittered sleep loop. A call-table dispatch at fcn.140013b00 (goto loc_rax) ^[r2:fcn.140013b00] is used for indirect function calls, a common anti-static-analysis pattern in custom loaders.
Notable function call chain from entry:
entry0→fcn.140001de0(init) →fcn.140002290/fcn.140002950→fcn.140007e34→ back toentry0entry0→fcn.1400013f0(main) →GetFileSize,GetTempPathA,GetModuleFileNameA,CreateMutexA,Sleep,CreateFileA, etc.
C2 Infrastructure
No hardcoded C2 recovered statically. Network indicators are expected to be embedded inside the encrypted overlay and resolved at runtime by the inner payload. The loader itself has no WS2_32, WinHTTP, or WinInet imports. Distribution is via the gcleaner pipeline.
Interesting Tidbits
- Stomped timestamp: The PE timestamp claims 2007, but the linker version (14.50) is circa 2019–2022. Classic anti-forensics. ^[pefile.txt:38] ^[exiftool.json]
- GDCRYPT branding: The
GDCRYPT!kernel32marker is unique in this corpus. Suggests a private or small-batch crypter, not a commodity builder. ^[strings.txt:154] - Base36-like charset:
bcdfghjklmnpqrstvwxyz0123456789— a 32-character alphabet omitting vowels and uppercase. Possibly used for filename generation or a keyed encoding layer. ^[strings.txt:155] - No .rsrc section: Unlike many dropper families in this corpus, there are no embedded icons, manifests, or RCData payloads. The entire malicious content is in the overlay.
- Six sections only: Clean MSVC layout (.text, .rdata, .data, .pdata, .fptable, .reloc). No packed or packed-like section names. ^[pefile.txt:79-199]
How To Mess With It (Homelab Replication)
Goal: Reproduce an encrypted-overlay dropper with anti-sandbox gates.
- Compile a 64-bit MSVC C++ stub (VS 2022,
/MT, x64 Release). - Implement
QueryPerformanceCountertiming gate withSleep(25)and ratio check. - Add
GlobalMemoryStatusEx≥ 256 MB,GetSystemInfoprocessor count ≥ 2, andGetTickCount64> 36 s gates. - Check
GetModuleFileNameApath forPROGRAMDATA,PROGRAM FILES,WINDOWSsubstrings (case-insensitive). - Read own PE file from disk starting at the overlay offset (
PointerToRawData + SizeOfRawDataof last section). - Decrypt with AES-256-CBC (key can be embedded obfuscated in .rdata).
- Map decrypted payload with
VirtualAlloc+VirtualProtect(RX), or useNtAllocateVirtualMemoryfor stealth. - Transfer execution via
((void(*)())ptr)()orCreateProcessAwithCREATE_SUSPENDEDfor hollowing.
Verification: Run in a 1-CPU, 128 MB VM with < 10 s uptime — stub should exit silently. Run on a 4-CPU, 4 GB host from %TEMP% with > 60 s uptime — payload should execute.
Deployable Signatures
YARA Rule
rule us0file_gdcrypt_loader {
meta:
description = "us0file / GDCRYPT encrypted-overlay x64 dropper"
author = "PacketPursuit"
hash = "796a371d25a0a76a03f74fddd75c3774077d1329b7a27366a1bf9c6dfecd882c"
strings:
$gdcrypt = "GDCRYPT!kernel32" ascii wide
$tgdcrypt = "tGDCRYPT!" ascii wide
$ntalloc = "NtAllocateVirtualMemory" ascii
$ntprotect = "NtProtectVirtualMemory" ascii
$charset = "bcdfghjklmnpqrstvwxyz0123456789" ascii
$fmt = "%s%s.exe" ascii
$mscoree = "mscoree.dll" ascii
condition:
uint16(0) == 0x5A4D and
uint32(uint32(0x3C)) == 0x00004550 and
uint16(uint32(0x3C)+0x18) == 0x20B and // PE32+
3 of ($gdcrypt, $ntalloc, $ntprotect, $charset, $fmt, $mscoree)
}
Behavioral Hunt Query (Sigma-like)
A process matching this fingerprint should be flagged:
- 64-bit PE with no
.rsrcsection and ≥ 500 KB overlay - Calls
CreateFileAon its own module path within 5 seconds of launch - Calls
GlobalMemoryStatusEx,GetSystemInfo,QueryPerformanceCounter, andSleep(25)in sequence - Calls
NtAllocateVirtualMemoryorVirtualAllocwithMEM_COMMIT | MEM_RESERVEandPAGE_EXECUTE_READshortly after file read
IOC List
| Indicator | Value |
|---|---|
| SHA-256 | 796a371d25a0a76a03f74fddd75c3774077d1329b7a27366a1bf9c6dfecd882c |
| ssdeep | 12288:T5SlDfoAncPEnE6IvCq+pyJhvurwFavepkB9pWD2S9IXwLIodlRx:TgxcP/JhJlurkpwpWDFIodDx ^[triage.json] |
| Family label (OpenCTI) | us0.file / dropped-by-gcleaner |
| Loader marker | GDCRYPT!kernel32 |
| Filename pattern | %s%s.exe (two-part concatenation) |
| Expected staging path | %TEMP% (path-gated against system directories) |
Detection Signatures
| ATT&CK Technique | Evidence | Source |
|---|---|---|
| T1055 — Process Injection | NtAllocateVirtualMemory, NtProtectVirtualMemory, CreateProcessA, FlushInstructionCache |
^[r2:list_imports] |
| T1620 — Reflective Code Loading | Custom overlay read → decrypt → VirtualProtect → indirect dispatch |
Static inference from entry chain ^[r2:entry0] |
| T1497.001 — Virtualization/Sandbox Evasion | RAM < 256 MB, CPU count, path checks | ^[r2:fcn.1400013f0] |
| T1497.003 — Time Based Evasion | QPC timing gate, GetTickCount64 uptime > 36 s |
^[r2:fcn.1400013f0] |
| T1106 — Native API | Direct ntdll primitive strings | ^[strings.txt:156-159] |
| T1564.003 — Hide Artifacts | 608 KB encrypted overlay concealing payload | ^[terminal: python overlay check] |
References
- Artifact ID:
f0822e14-f2df-4b0b-897c-1f1740918101^[metadata.json] - OpenCTI labels:
dropped-by-gcleaner,us0.file^[triage.json] - Related entity: gcleaner — distribution infrastructure
- Related concept: reflective-pe-loader — runtime payload mapping pattern
Provenance
Analysis based on static outputs generated by triage pipeline on 2026-05-29: file, exiftool, pefile, strings, rabin2, binwalk, triage.json, metadata.json. Radare2 analysis level 3 performed during deep-dive on 2026-08-26. CAPE detonation skipped — no Windows guest available. Floss and capa errored during triage (signature path missing).