WebRAT Go Stealer Analysis
sa1atik.cn, with TON-domain fallback.Sample
- File
- cd9c972e…2a0067.exe (from ZIP, password
infected) - SHA-256
- cd9c972e46b2cf283be8227c67417a4c5bb2009fc91a14b0845f20d86e2a0067
- MD5
- 1eeff92eb40e0409bab1e159c2e629bb
- Type
- PE32 GUI, x86, 12.5 MB, 6 sections, Go 1.24
- Size of analysis
- 5,526 procedures · 22,713 strings · 300
main.*functions recovered
How it was analyzed
strings showed Go packages, stealer routines and TON/Steam helpers.main.* names were applied.main.* names with addresses. rea decompile-all then decompiled 0x8cd9f0 to 0x8eba90 by address.main.dec is a multi-stage routine (XOR key array, 129-dword table, rotates, 0x9e3779b9). Static reading was not enough.Command-and-control chain
https://sa1atik.cn/sa1at/The sample tried this first; the lookup failed because the network was off.
webratxaye1.tonResolved through
tonapi.io and the ton.access.orbs.network API (runGetMethod).remoteadministratortool.tontonapi.io/v2/dns/…/resolvedns.google, 1.1.1.1 and cloudflare-dns.com. Transport includes HTTP/2, HTTP/3 (QUIC) and websockets.Code paths also show a Steam-profile decoder (decodeSteam) and a tg:// link finder, which suggests two more places the server address can be hidden. I did not observe either being used.
Capabilities
Credential and data theft
- Chrome, Edge, Brave, Yandex and other Chromium logins, cookies, autofill
- Chrome app-bound key (
GetAppBoundKey,decryptAPPB) - Firefox-family NSS store (
key4.db,nssPBE) - Discord tokens, Steam, Telegram
tdata, Ethereum keystore, many wallet extensions
Privilege and access
- Finds LSASS and impersonates SYSTEM (
findLsassProcess,impersonateSystem) DuplicateUserTokenFromSessionID,Elevate- Reports
Admin rights:to the server
Surveillance
- Keylogger (
runKeylogger,klog) - Screenshots (
getScreen,sendScreen), active window title - Host profile: HWID, GPU, GEO, user time, build ID and version
Remote control
doTaskloop withshellCommand,executeCommand,downloadFile- SOCKS-style proxy and forwarding code
- RDP libraries,
ffmpeg.exeand7z.exefetched from GitLab
Defense impairment (script in memory)
Add-MpPreference -ExclusionPathfor Program Files, AppData, LocalAppDatareagentc /disableturns off Windows recovery resetEnableLUA = 0disables UAC
Persistence and cleanup
staticinstalland aCurrentVersion\Runstring suggest autorunSuicidesuggests self-delete- Neither was confirmed in the sandbox run
Indicators of compromise
| Type | Value | Source |
|---|---|---|
| SHA-256 | cd9c972e46b2cf283be8227c67417a4c5bb2009fc91a14b0845f20d86e2a0067 | observed |
| Domain | sa1atik.cn | observed memory + failed lookup |
| URL | https://sa1atik.cn/sa1at/ | observed |
| TON domain | webratxaye1.ton | observed |
| TON domain | remoteadministratortool.ton | observed |
| URL | https://tonapi.io/v2/dns/remoteadministratortool.ton/resolve | observed |
| URL prefix | https://gitlab.com/webrat1/importantfiles/-/raw/main/ | observed |
| Files | 7z.exe · 7z.dll · ffmpeg.exe · MSTSCLib.dll · AxMSTSCLib.dll in %TEMP% | observed in script |
| Registry | HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\EnableLUA = 0 | observed in script |
| Command | reagentc /disable | observed in script |
| Behavior | Unknown Go binary spawns powershell.exe, taskkill /F /PID | from strings |
Not recorded: the real IP of sa1atik.cn and the content the TON domains resolve to, because the sandbox had no network. Treat the Defender exclusions, UAC change and GitLab downloads as capability evidence: the script was in memory, but Wine could not run it.
ATT&CK mapping
| Technique | Evidence | Confidence |
|---|---|---|
| T1555.003 Credentials from web browsers | Chromium and Gecko decryption routines, app-bound key | code + strings |
| T1134 Access token manipulation | impersonateSystem, DuplicateUserTokenFromSessionID | code + strings |
| T1056.001 Keylogging | runKeylogger, klog | code + strings |
| T1113 Screen capture | getScreen, sendScreen | code + strings |
| T1568 Dynamic resolution | TON DNS, DoH lookups | observed |
| T1102 Web service | GitLab staging, Steam decoder | observed / inferred |
| T1059.001 PowerShell | Embedded script, powershell.exe | observed |
| T1562.001 Impair defenses | Add-MpPreference -ExclusionPath | observed in script |
| T1112 Modify registry | EnableLUA = 0 | observed in script |
| T1490 Inhibit system recovery | reagentc /disable | observed in script |
| T1105 Ingress tool transfer | GitLab downloads, downloadFile | observed in script |
| T1560 Archive collected data | zipAddFS, 7z.exe | code + strings |
| T1021.001 Remote Desktop Protocol | MSTSCLib, AxMSTSCLib | inferred |
| T1547.001 Registry run keys | CurrentVersion\Run string | inferred |
YARA rules
Two rules. The first matches the executable on disk. The second matches decrypted config and the dropper script in a process dump.
rule MAL_WebRAT_Go_Stealer_Nov2026
{
meta:
description = "Go-based WebRAT-style infostealer / RAT (TON + DoH C2 resolution, Chromium app-bound key theft, keylogger)"
author = "analysis via rea + GoReSym + sandbox run"
date = "2026-11-01"
sha256 = "cd9c972e46b2cf283be8227c67417a4c5bb2009fc91a14b0845f20d86e2a0067"
reference = "local analysis"
strings:
// Go symbol names present in pclntab
$f1 = "main.decodeFromTonAddress" ascii
$f2 = "main.tryTonResolve" ascii
$f3 = "main.GetAppBoundKey" ascii
$f4 = "main.findLsassProcess" ascii
$f5 = "main.impersonateSystem" ascii
$f6 = "main.runKeylogger" ascii
$f7 = "main.decodeSteam" ascii
$f8 = "main.DecryptGecko" ascii
$f9 = "main.staticinstall" ascii
// operator log / status strings
$s1 = "steal finished!" ascii
$s2 = "SSLPIN DISABLED" ascii
$s3 = "CONN BEST ENABLED" ascii
$s4 = "found tg:// url" ascii
$s5 = "bestConnMethod" ascii
$s6 = "NO PREAPPBENCKEY ERR" ascii
$s7 = "FOUND BC: GOT RESULT" ascii
// resolver / lookup endpoints stored in clear
$r1 = "https://dns.google/resolve?name=" ascii
$r2 = "SELECT a11, a102 from nssPrivate" ascii
condition:
uint16(0) == 0x5A4D and filesize < 30MB and
(
( 5 of ($f*) ) or
( 4 of ($s*) and 2 of ($f*) ) or
( $r1 and $r2 and $f3 )
)
}
rule MAL_WebRAT_Go_Stealer_Memory_Config
{
meta:
description = "Decrypted C2 config and dropper script in process memory or a memory dump"
sha256 = "cd9c972e46b2cf283be8227c67417a4c5bb2009fc91a14b0845f20d86e2a0067"
strings:
$c1 = "sa1atik.cn" ascii wide
$c2 = "webratxaye1.ton" ascii wide
$c3 = "remoteadministratortool.ton" ascii wide
$c4 = "gitlab.com/webrat1/importantfiles" ascii wide
$p1 = "Add-MpPreference -ExclusionPath" ascii wide
$p2 = "reagentc /disable" ascii wide
$p3 = "EnableLUA" ascii wide
condition:
any of ($c*) or all of ($p*)
}
Validation
| Target | Rule | Result |
|---|---|---|
| Original sample | Nov2026 | match (all 9 function and 7 status strings hit) |
| Memory dump of the run | Memory_Config | match |
| /usr/bin, /usr/local/bin, Wine libraries | both | no matches |
| GoReSym (a benign Go binary) | both | no match |
The static rule keys on Go symbol names, so a rebuild with garble or stripped symbols will evade it. The status strings and DoH endpoint give a second route. Test against a larger clean corpus before deploying it as a blocking rule.
What to do
Block
sa1atik.cnat DNS and proxy- Alert on
.tonlookups throughtonapi.iofrom endpoints - GitLab
webrat1path
Hunt
- SHA-256 above
7z.exe,ffmpeg.exe,MSTSCLib.dllin %TEMP%- Defender exclusions on AppData and Program Files
- Unexpected
EnableLUA=0
If a host ran it
- Treat browser, Discord, Steam, Telegram and wallet credentials as stolen
- Rotate from a clean device; revoke sessions
- Move wallet funds
- Reimage; recovery reset may be disabled
Limits of this analysis
- The sample ran under Wine without a display and without network, so server commands, the Steam and Telegram paths, and persistence were not exercised.
main.decwas not reimplemented. The C2 values come from process memory after the program decrypted them itself. There may be more entries the run did not reach.- Ghidra's Go support failed on this binary, so pseudocode for Go functions is hard to read. Names come from GoReSym.
- Network blocking was the only containment. Bubblewrap and user namespaces were unavailable on the analysis machine.