dbe586b56376ac96097b76ed353b6ad89977d3345774d80fce846fe97370b86fsilentnet: dbe586b5 — Zig 0.12.0 PE64 launcher with XOR-obfuscated C2 and TLS 1.3 HTTP client
A 1.14 MB PE64+ executable compiled with Zig 0.12.0, distributed as Launcher.exe. The binary performs host fingerprinting, decrypts XOR-obfuscated strings at runtime, and initiates outbound TLS 1.3 HTTP communication via Zig's std.http client. It can spawn child processes and relocate files. No packing, no anti-analysis, no VM checks. All behavior inferred statically; CAPE detonation was skipped due to lack of Windows guest.
What It Is
| Attribute | Observation |
|---|---|
| File type | PE32+ executable (GUI) x86-64, 7 sections ^[file.txt] |
| Size | 1,138,688 bytes |
| Compilation | Fri May 22 11:03:04 2026 UTC ^[pefile.txt:38] |
| Toolchain | Zig 0.12.0 (LLVM/LLD, linker version 14.0) ^[pefile.txt:49] ^[strings.txt:1350] |
| Signed | No ^[rabin2-info.txt:27] |
| Packed | No |
| Resources | None ^[terminal:python pefile resource check] |
| TLS callbacks | Directory present; callback array empty (no anti-analysis hooks) ^[pefile.txt:367] |
| Entropy | .text 6.37, .rdata 1.08 (plaintext data in .rdata, not encrypted at rest) ^[pefile.txt:95] ^[pefile.txt:115] |
| Family | silentnet (OpenCTI label, single observed sample) ^[metadata.json] |
How It Works
Entry point 0x401000 calls a large startup routine (fcn.00401011) that performs at least six XOR-decryption loops on stack-allocated buffers, unpacking strings used later in execution. Each loop loads an encrypted blob from .rdata and a key pointer (both rip-relative), then decrypts with r8b = [rdx+r8] ^ [rcx+rax] before storing to a local buffer ^[r2:fcn.00401011]. Decrypted strings are consumed by subsequent API calls; their plaintext content was not recovered statically because the keys are also embedded in .rdata and applied only at runtime.
After decryption, the routine gathers host information via GetSystemInfo, GlobalMemoryStatusEx, GetDiskFreeSpaceExW, and GetTickCount64 ^[r2:fcn.00401011 @ 0x4011d5]. It then opens a registry key via RegOpenKeyExA with samDesired = 0x20019 (KEY_READ) ^[r2:fcn.00401011 @ 0x40114a]. The specific key path is XOR-encrypted and not visible statically.
Network functionality is built on Zig's std.http client with native TLS 1.3 support. Evidence includes the literal (std.http) format string, user-agent: zig/0.12.0, TLS handshake state strings (c hs traffic, s hs traffic, finished), and TLS alert names (TlsAlertInsufficientSecurity) ^[strings.txt:1352] ^[strings.txt:971]. The import table includes WS2_32.dll socket APIs (WSAStartup, getaddrinfo, WSASocketW, connect) and CRYPT32.dll certificate APIs (CertOpenSystemStoreW, CertEnumCertificatesInStore) ^[pefile.txt:359] ^[pefile.txt:347]. No hardcoded C2 URL, domain, or IP was recovered statically; these are presumed to be among the XOR-decrypted strings.
Process creation capability is present via CreateProcessW ^[pefile.txt:303]. MoveFileW suggests file relocation or staging ^[pefile.txt:314].
Decompiled Behavior
The entry function (fcn.00401011, ~0x4000+ bytes) is structured as a sequence of XOR-decryption blocks interleaved with system API calls:
- Block 1 (0x401076): decrypts a 0x0E-byte blob → consumed as registry key path for
RegOpenKeyExA. - Block 2 (0x401128): decrypts a 0x20-byte blob → used as value name for
RegQueryValueExA. - Block 3 (0x4012a9): decrypts a 0x24-byte blob → stored to a global at
0x513678, flagged as initialized. - Block 4 (0x40130d): decrypts a 0x2A-byte blob → stored alongside Block 3 data.
- Block 5 (0x40136f): decrypts a 0x0A-byte blob → used as a short configuration token.
- Block 6 (0x4013ba): decrypts a 0x36-byte blob → likely a URL or hostname for C2.
Each block follows the same pattern: load rcx (encrypted data), rdx (key), iterate rax from 0 to N, XOR, write to rsp+offset. Key lengths vary (0x0A, 0x0E, 0x10, 0x13, 0x20, 0x24, 0x2A, 0x36), suggesting either multiple short keys or offsets into a longer master key.
The socket/HTTP function (fcn.0041601d, called from fcn.0041309a) calls getaddrinfo → WSASocketW → connect, referencing pre-allocated sockaddr structures at 0x4d13d0–0x4d1450 ^[r2:fcn.0041601d]. The switch-case at 0x416263 handles HTTP response status codes (35–52 range), suggesting the C2 protocol speaks HTTP with numeric status responses.
fcn.00402494 (called from entry) also contains XOR-decryption loops and calls CreateProcessW at 0x405e31 ^[r2:fcn.00402494 @ 0x405e31], spawning a child process with command-line arguments built from decrypted strings.
C2 Infrastructure
No hardcoded C2 URLs, domains, or IPs were recovered statically. The binary resolves addresses at runtime via getaddrinfo using XOR-decrypted host strings. The std.http client supports:
connection: keep-aliveandconnection: close^[strings.txt:1354] ^[strings.txt:1355]- Chunked transfer encoding ^[strings.txt:1130]
- Gzip and deflate content encoding ^[strings.txt:1171] ^[strings.txt:1172]
- Proxy authorization ^[strings.txt:1360]
- TLS 1.3 with certificate verification (including
CertOpenSystemStoreW) ^[pefile.txt:347]
Interesting Tidbits
- Clean Zig build: No packing, no anti-debug, no VM checks, no stripped symbols. The binary is as close to a debug build as malware gets — suggesting either rapid development or reliance on the language's obscurity for evasion.
- TLS 1.3 native: Uses Zig's built-in TLS stack rather than OpenSSL or Schannel, evidenced by
TLS 1.3, server CertificateVerify,c hs traffic,s hs traffic, andfinishedhandshake state strings ^[strings.txt:971]. - Registry reconnaissance: Opens a registry key early in execution via
RegOpenKeyExA^[r2:fcn.00401011 @ 0x40114a]. The path is XOR-encrypted. - Certificate store enumeration:
CertOpenSystemStoreWandCertEnumCertificatesInStoresuggest it may inspect the root certificate store, possibly for pinning or trust manipulation ^[pefile.txt:347]. - Entropy anomaly:
.rdataentropy is 1.08, extremely low. This section contains the XOR keys and encrypted strings in plaintext; obfuscation is applied only at runtime. - No persistence strings: No
Runkeys,schtasks,Startupfolders, or service names were recovered in plaintext. Persistence mechanism, if any, is also XOR-encrypted or absent. - Binwalk artifacts: AES S-Box, AES Inverse S-Box, Base64 index tables, and CRC32 polynomial tables were detected ^[binwalk.txt:5] ^[binwalk.txt:7] ^[binwalk.txt:9] ^[binwalk.txt:10]. These are standard Zig stdlib tables (TLS/AES, HTTP/Base64, hash/CRC32) and not unique to this binary.
How To Mess With It (Homelab Replication)
Toolchain: Install Zig 0.12.0 from ziglang.org/download.
Target: zig build-exe -target x86_64-windows-gnu -OReleaseSmall main.zig
Working snippet: Use std.http.Client with std.crypto.tls.Client for a minimal TLS 1.3 GET request. The stdlib handles getaddrinfo, WSASocketW, and certificate validation automatically.
XOR obfuscation: Encrypt strings at compile time with a repeating XOR key, decrypt in main() before passing to std.http or registry functions.
Verification: Compile the reproducer and compare strings output to this sample — you should see user-agent: zig/0.12.0, (std.http), and TLS handshake state strings.
What you'll learn: How a modern systems-language stdlib (Zig) produces a self-contained PE with TLS, HTTP, crypto, and registry APIs without external DLL dependencies beyond the Windows system set.
Deployable Signatures
YARA
rule silentnet_zig_012_launcher {
meta:
description = "Zig 0.12.0 compiled PE64 with std.http client and XOR string decryption"
author = "malware-corpus"
date = "2026-06-10"
hash = "dbe586b56376ac96097b76ed353b6ad89977d3345774d80fce846fe97370b86f"
strings:
$zig_ua = "user-agent: zig/0.12.0" ascii wide
$std_http = " (std.http)" ascii wide
$tls13_cv = "TLS 1.3, server CertificateVerify" ascii wide
$panic1 = "thread {} panic: " ascii wide
$panic2 = "Panicked during a panic. Aborting." ascii wide
$conn_keep = "connection: keep-alive" ascii wide
$conn_close = "connection: close" ascii wide
$microsoft_windows = "Microsoft\\Windows" ascii wide
condition:
uint16(0) == 0x5A4D and
pe.machine == pe.MACHINE_AMD64 and
pe.linker_version.major == 14 and
filesize > 1MB and filesize < 2MB and
4 of ($zig_ua, $std_http, $tls13_cv, $panic1, $panic2) and
2 of ($conn_keep, $conn_close, $microsoft_windows)
}
Behavioral Hunt Query
Sigma-like pseudocode:
Process creation where parent image contains "Launcher.exe" and child process is spawned within 30 seconds of initial execution, combined with network connection to non-local IP over port 443 with TLS 1.3 SNI pattern (no prior DNS query from same process observed). Registry read of HKLM\Software\Microsoft\Windows by process with low prevalence hash.
IOC List
| Type | Value |
|---|---|
| SHA-256 | dbe586b56376ac96097b76ed353b6ad89977d3345774d80fce846fe97370b86f |
| SHA-1 | cf5a7c4d01929942ab42743a8b344ca0b7a963af ^[pefile.txt:97] |
| MD5 | bef1534974f1d0aab505b09820208e71 ^[pefile.txt:96] |
| Size | 1,138,688 bytes |
| Filename | Launcher.exe |
| Compilation | 2026-05-22 11:03:04 UTC |
| Import fingerprint | ntdll + KERNEL32 + ADVAPI32 + CRYPT32 + WS2_32 (minimal socket/crypto/registry set) |
Behavioral Fingerprint
This binary is a 64-bit Windows GUI executable compiled with Zig 0.12.0. On launch, it decrypts multiple XOR-obfuscated strings on the stack, then calls GetSystemInfo, GlobalMemoryStatusEx, GetDiskFreeSpaceExW, and GetTickCount64 to fingerprint the host. It reads from the registry via RegOpenKeyExA and opens the certificate store via CertOpenSystemStoreW. It then resolves a hostname via getaddrinfo, creates a socket with WSASocketW, and initiates a TLS 1.3 connection over HTTPS using Zig's std.http client. It can spawn child processes via CreateProcessW and move files via MoveFileW. No persistence mechanism was statically identified.
Detection Signatures
- Capa: N/A — capa rule set was not installed during triage ^[capa.txt]
- MITRE ATT&CK (static inference):
- T1082 — System Information Discovery
- T1016 — System Network Configuration Discovery
- T1071.001 — Application Layer Protocol: Web Protocols
- T1105 — Ingress Tool Transfer
- T1059.003 — Windows Command Shell
- T1564.001 — Hidden Files and Directories
References
- MalwareBazaar:
dbe586b56376ac96097b76ed353b6ad89977d3345774d80fce846fe97370b86f - OpenCTI artifact:
ffec9f60-3770-4c94-9f66-951041036844^[metadata.json] - OpenCTI labels:
exe,malware-bazaar,silentnet^[metadata.json]
Provenance
Analysis derived from file.txt, pefile.txt, strings.txt, rabin2-info.txt, binwalk.txt, and radare2 decompilation (fcn.00401011, fcn.0041601d, fcn.00402494). FLOSS and CAPA tools failed due to CLI misconfiguration. Dynamic analysis (CAPE) was skipped — no Windows guest available. All behavior is statically inferred and marked as such. No orphan wikilinks in this report.