88f7d22ed2494fb53d1806011173dd739f77bda9ff8d20f130b4bc5fdde761d7silverfox: 88f7d22e — Bkav masquerade C stub, builder-morphed sibling of b37efcbc
Executive Summary
A 54 KB PE32+ x64 C stub from the SilverFox cluster, compiled May 28 2026 with an anachronistic MSVC 6.0 linker. It is byte-for-byte identical in build fingerprint to sibling b37efcbc (same XOR key, same timestamp, same stream-cipher constants) but carries a Bkav Corporation VersionInfo masquerade instead of the WPS Office lure seen in the earlier sample. This confirms builder-level morphing of metadata while the payload core remains static. Static-only analysis; no CAPE Windows guest available.^[dynamic-analysis.md]
What It Is
| Attribute | Detail |
|---|---|
| SHA-256 | 88f7d22ed2494fb53d1806011173dd739f77bda9ff8d20f130b4bc5fdde761d7 |
| Size | 54 272 bytes^[triage.json] |
| Format | PE32+ x64, 5 sections (.text, .rdata, .data, .pdata, .rsrc)^[file.txt]^[pefile.txt:77-175] |
| Linker | MSVC 6.0 (Major=6, Minor=0) — anachronistic for 2026^[pefile.txt:45-46]^[exiftool.json:18] |
| Language | C (lang: c)^[rabin2-info.txt:17] |
| Stripped | Yes, external PDB only^[pefile.txt:39]^[rabin2-info.txt:30] |
| Signed | No^[rabin2-info.txt:27] |
| Timestamp | Thu May 28 00:20:51 2026 UTC^[pefile.txt:34] |
| Filename | 2026.05.28裁员名单及补偿方案WPS.exe (Chinese staff list + severance compensation lure, WPS Office masquerade)^[triage.json:5] |
| VersionInfo | Bkav Corporation / Bkav Restore Service / BkavRestoreService.exe / BkavPro / 3.0.0.23^[exiftool.json:36-43]^[pefile.txt:261-268] |
Build / RE
- No packing or compression. No UPX, no LZSS, no RC4 engine, no custom stream-cipher payload block. The
.rsrcsection contains only standard dialog/string/icon resources (RT_DIALOG, RT_STRING, RT_ICON) with a benignBkavRestoreServicestring table.^[pefile.txt:390-500] - XOR-thunk API dispatch. Every API call is indirected through a single QWORD key
0x578d9d6102d087e9stored at.data:0x408000. Twelve encrypted function pointers live in.dataat VA0x409a98, each decrypted at runtime via XOR against a rotating key from the.datakey table.^[terminal:python .data analysis]^[r2:fcn.0040100d] - No FNV-1a resolver. Unlike the 50 KB sibling
82d425516199, this stub drops the FNV-1a hash→name→address chain entirely. The key is a single QWORD, simplifying reversal.^[r2:fcn.0040100d] - Standard IAT. Full visible import table from KERNEL32, ADVAPI32, SHELL32, PSAPI, and msvcrt — no PEB-walking, no zero-IAT obfuscation.^[pefile.txt:281-388]^[r2:list_imports]
- Three of four SilverFox stream-cipher constants present:
0xcaaafe23,0x3d57aa23,0x44d9bb23. The fourth (0x9e37cb23) is absent, matching the pattern seen inb37efcbcandaa029dcb.^[terminal:python search] - Process hollowing imports.
CreateProcessW,VirtualAllocEx,WriteProcessMemory,GetModuleInformationare all statically imported, strongly suggesting suspended-child injection.^[pefile.txt:323-353]
Deploy / ATT&CK
| ATT&CK ID | Technique | Evidence |
|---|---|---|
| T1055 | Process Injection | Static imports VirtualAllocEx, WriteProcessMemory, CreateProcessW^[pefile.txt:323-353] |
| T1055.012 | Process Hollowing | GetModuleInformation + hollowing API cluster present^[pefile.txt:353] |
| T1497.001 | Sandbox Evasion | __argc <= 1 gate at entry0; clean exit if no arguments^[r2:entry0] |
| T1070.004 | File Deletion | MoveFileExW imported^[pefile.txt:351] |
| T1106 | Native API | OpenProcessToken, LookupPrivilegeValueA, AdjustTokenPrivileges for privilege escalation^[pefile.txt:367-368] |
| T1562.001 | Impair Defenses | ShellExecuteExW fallback for UAC bypass or elevated execution^[pefile.txt:378] |
- Privilege escalation path:
OpenProcessToken→LookupPrivilegeValueA→AdjustTokenPrivilegessuggestsSeDebugPrivilegeor similar token escalation before injection.^[pefile.txt:367-368] - Self-deletion:
MoveFileExW(withMOVEFILE_DELAY_UNTIL_REBOOT) is the likely cleanup mechanism, consistent with all SilverFox C stubs.^[pefile.txt:351] - No C2 recoverable statically. No hardcoded IPs, domains, URLs, or mutex names. The payload is likely fetched at runtime (network pull) or delivered via a companion file — neither mechanism is visible in static strings.^[strings.txt]^[floss.txt]
Decompiled Behavior
The entry point (entry0 at 0x00405fb4) is a minimal MSVC CRT wrapper:^[r2:entry0]
- Calls
GetStartupInfoA,GetCommandLineA,__getmainargsto initialise the CRT. - Reads
__argc. Ifargc <= 1, exits cleanly — this is the sandbox gate.^[r2:entry0] - Calls
fcn.00405e59, the main orchestrator.
fcn.00405e59 (347 bytes) does the heavy lifting:^[r2:fcn.00405e59]
- Copies the command line via
_strdup. - Walks a table of encrypted function pointers at
.data:0x409a98(12 entries). - Each pointer is decrypted at call time by XOR against a rotating key from the
.data:0x408000key table. - The decrypted pointers resolve to small thunks in the
0x406130–0x406158range (msvcrt wrappers) and tofcn.004054b4(a 2-byte forwarder).
fcn.0040100d (233 bytes) demonstrates the thunk pattern in Ghidra-decompiled form:^[r2:fcn.0040100d]
- Loads encrypted pointer
0x578d9d610290e6d9from.data:0x409a98. - XORs it against the key at
.data:0x408000(0x578d9d6102d087e9). - Result:
0x406130— amemsetwrapper thunk. - Calls the decrypted address via
call r11.
No anti-debug checks, no VM detection, no PEB-walking. The entire anti-analysis budget is the __argc gate and the XOR-thunk indirection.
C2 Infrastructure
Not recoverable from static analysis. No network indicators in strings, floss, or decompiled code. The payload delivery mechanism is external to this binary.^[strings.txt]^[floss.txt]
Interesting Tidbits
- Builder-level morphing confirmed. This sample shares the exact same XOR key, timestamp, linker fingerprint, and code layout as
b37efcbc. The only material difference is the VersionInfo block (Bkav vs WPS Office). This is a builder that swaps metadata per campaign while reusing the same payload stub.^[exiftool.json:36-43] ^[entities/silverfox.md] - Bkav is a legitimate Vietnamese AV vendor. Masquerading as
Bkav Restore Serviceis a geographic pivot — previous siblings used Chinese company names (Sangfor, WPS). The actor may be A/B testing lure credibility across regions.^[exiftool.json:36-43] - Identical
.rsrctimestamp anomaly. The resource directory carries a secondary timestampThu May 28 18:36:23 2026 UTC, roughly 18 hours after the PE header timestamp. This suggests the resources were added or modified in a separate build step after compilation.^[pefile.txt:394] - MSVC 6.0 linker in 2026. Still observed in this cluster. Either a deliberate artifact from a legacy build VM or a fabricated linker version to evade heuristic detection.^[pefile.txt:45-46]
How To Mess With It (Homelab Replication)
- Build a minimal PE32+ x64 C program with MSVC 6.0 or an equivalent toolchain (e.g.,
mingw-w64with/link /version:6.0). - Implement a single-QWORD XOR-thunk dispatcher:
- Store a key
Kin.data. - Build an encrypted pointer table where each entry
E[i] = target_i ^ K[i % N]. - At runtime, decrypt via
target = E[i] ^ K[i % N]andcall target.
- Store a key
- Add an
__argcgate atmain()—if (argc <= 1) return 0;. - Import
CreateProcessW,VirtualAllocEx,WriteProcessMemory,MoveFileExW, andOpenProcessToken. - Compile stripped (
/striporsstrip). - Verify with
capa(once signatures are installed) — the import cluster alone should flag process hollowing and token manipulation.
What you'll learn: how a 55 KB stub with trivial static obfuscation still achieves meaningful defense evasion through API indirection and argument gating.
Deployable Signatures
YARA
rule SilverFox_XOR_Thunk_Bkav_Masquerade {
meta:
description = "SilverFox C-stub variant with XOR-thunk API dispatch and Bkav VersionInfo"
author = "PacketPursuit"
date = "2026-09-07"
sha256 = "88f7d22ed2494fb53d1806011173dd739f77bda9ff8d20f130b4bc5fdde761d7"
family = "silverfox"
strings:
$bkav1 = "Bkav Corporation" wide ascii
$bkav2 = "Bkav Restore Service" wide ascii
$bkav3 = "BkavRestoreService.exe" wide ascii
$bkav4 = "BkavPro" wide ascii
$key1 = { e9 87 d0 02 61 9d 8d 57 } // XOR key at .data start (little-endian)
$const1 = { 23 fe aa ca }
$const2 = { 23 aa 57 3d }
$const3 = { 23 bb d9 44 }
condition:
uint16(0) == 0x5A4D and
filesize < 60KB and
(2 of ($bkav*) or 1 of ($key*)) and
2 of ($const*)
}
Sigma (Process Creation)
title: SilverFox C Stub Process Hollowing
description: Detects SilverFox XOR-thunk variant process hollowing pattern
logsource:
category: process_creation
product: windows
detection:
selection:
Image|contains:
- 'BkavRestoreService'
- 'BkavPro'
CommandLine|re:
- '.*裁员.*'
- '.*WPS\.exe'
susp_api:
- LoadedImageName|contains: 'CreateProcessW'
- LoadedImageName|contains: 'VirtualAllocEx'
- LoadedImageName|contains: 'WriteProcessMemory'
condition: selection and susp_api
falsepositives:
- None expected (BkavRestoreService.exe with Chinese severance filename is not legitimate)
level: high
IOCs
| Type | Value | Notes |
|---|---|---|
| SHA-256 | 88f7d22ed2494fb53d1806011173dd739f77bda9ff8d20f130b4bc5fdde761d7 |
|
| SHA-1 | 219cc80b6eab57e8002309f7c0fa335971f31a02 |
.text section^[pefile.txt:94] |
| MD5 | 598fa2c46575c6a4a467d691577a0816 |
.text section^[pefile.txt:92] |
| Filename | 2026.05.28裁员名单及补偿方案WPS.exe |
Chinese severance lure^[triage.json:5] |
| InternalName | BkavRestoreService.exe |
VersionInfo^[exiftool.json:39] |
| ProductName | BkavPro |
VersionInfo^[exiftool.json:42] |
| CompanyName | Bkav Corporation |
VersionInfo^[exiftool.json:36] |
| XOR Key | 0x578d9d6102d087e9 |
.data:0x408000^[terminal:python .data analysis] |
| Stream constants | 0xcaaafe23, 0x3d57aa23, 0x44d9bb23 |
.text embedded^[terminal:python search] |
Behavioral Fingerprint
This binary is a 54–56 KB PE32+ x64 C stub compiled with an anachronistic MSVC 6.0 linker. It imports CreateProcessW, VirtualAllocEx, WriteProcessMemory, and MoveFileExW via a standard IAT, then indirects all API calls through a single QWORD XOR key stored in .data. At launch it checks __argc; if no arguments are present it exits cleanly. The VersionInfo masquerades as Bkav Restore Service by Bkav Corporation. Three SilverFox stream-cipher constants are embedded in .text. No payload is embedded statically — the stub expects an external delivery mechanism.
Detection Signatures
- CAPE skipped — no dynamic signature hits available.^[dynamic-analysis.md]
- Static import cluster (
CreateProcessW+VirtualAllocEx+WriteProcessMemory+MoveFileExW+OpenProcessToken) is a reliable hunt pivot for this stub family.^[pefile.txt:318-388]
References
- Artifact ID:
66be54cf-2563-4c56-80d3-d30e795dd87f - OpenCTI labels:
silverfox,valleyrat,trojan/silverfox.bg[qtsc]^[triage.json] - Related wiki: silverfox
- Confirmed sibling:
b37efcbc178c9f8d2c4059e55311279a435ff5cd9b00840ec17ef0f7110b106c— same XOR key, same timestamp, WPS masquerade^[entities/silverfox.md] - Confirmed sibling:
aa029dcb4bdff2ac1e34c4829c774146dcf494f890fb2aefa08f4998321d9e2c— same XOR key, same constants,EwpiLOHmasquerade^[entities/silverfox.md]
Provenance
file.txt—filev5.45pefile.txt—pefilePython libraryrabin2-info.txt— radare2 v5.xstrings.txt—stringsfrom GNU binutilsexiftool.json— ExifTool v12.76capa.txt— capa v9 (failed: missing signatures)floss.txt— flare-floss v3.1 (failed: CLI arg parsing)dynamic-analysis.md— CAPEv2 (skipped: no Windows guest)- radare2 static analysis with
aaa+pdc— 248 functions recovered, level 3 analysis - Python 3.12 byte-level inspection for XOR key recovery and constant search