Hacker News 25天前 · 2026-10-16 06:51:54 · 14 阅读
有人在种子站上传假剧集,Sonarr 中招抓下恶意 EXE
我在 NAS 上跑的是常规的 *arr 套件。平时都挺正常,直到我在仪表盘上看到一条警告。新一集《南方公园》卡在队列里,提示:
都 2026 年了,居然还有人信这个?
把 跳进去执行。 整个过程不落盘。为这六步加的全套混淆。
用的是 ChaCha20。他们通过全局变量拼出常量来隐藏,但拼出来还是
都 2026 年了,居然还有人信这个?
这是个 EXE
我把这事儿说清楚点。 有人拿《南方公园》某集的片名,在末尾加了.exe,然后传到了公开 Tracker 上,种子数竟然高达 2,392。谁在拿 EXE 当剧集分发啊?
结果 Sonarr 还真把它抓下来了,它办事从不让人失望。之后它就一直待在那儿,每隔 90 秒就试一次导入:
Copy
Import failed, path does not exist or is not accessible by Sonarr:
/data/downloads/torrents/South Park S29E03 1080p WEB H264-MeGusta.exe
连个带假 .mkv 和“编解码器安装器”的文件夹都懒得做,那是“旧时代”的做派了。
就一个 EXE。我是认真的。
qBittorrent 在添加两秒后就标记它为“完成”,且 total_downloaded: 0,所以实际上什么都没落盘。不知道为什么,也不在乎。谢了 qBit。
我在 Sonarr 里把它拉黑,这样会从 qBittorrent 中移除它,并阻止它再次抓取同样的垃圾恶意软件。
然后我故意又下载了一次。因为我现在很火,想知道里面到底有什么。
887 MB 的无意义填充
这是个真正的 PE,x64 GUI。实际程序大小只有 118 KB。 Copype end 0x1ce00
overlay 886653736 bytes
另外那 886 MB 是粘在文件末尾的随机垃圾。为什么?因为很多扫描器遇到这么大的文件就直接放弃了。
版本信息写着:
Copy
CompanyName Freeware Developers
FileDescription prepares application data
OriginalFilename SetupHelper.exe
“免费软件开发者”,呸,骗鬼。
我把前 118 KB 切下来丢进 IDA,因为我可不想把一整吉的废话加载进任何工具。然后我发现整个程序都被这种东西覆盖着:
Copy
dword_14000C020 ^= 0xF2C2EAC0;
v34 = 0;
dword_14000C020 ^= 0xF2C2EAC0;
对一个全局变量做异或。再异或回去。啥也没干。重复几百次。
它的存在纯粹是为了让反编译器输出变得面目全非,而且它确实做到了,恭喜。
把这些全去掉,逻辑其实只有六步:
- 打开它自己的文件。
- 读取最后 64 个字节。
- 用这些字节在垃圾数据中找到并解密隐藏的载荷。
- 手动将其映射为内存中的 PE。
PEB->ImageBaseAddress 指向它。文件尾
文件最后 64 字节就是全部配置:| 偏移 | 大小 | 说明 |
|---|---|---|
| 0x00 | 32 字节 | key,与 .data 里的 32 字节 mask 异或 |
| 0x20 | 12 字节 | ChaCha20 nonce |
| 0x2C | 4 字节 | payload 大小 ^ fnv1a(mask) |
| 0x30 | 4 字节 | (flags | padding << 8) ^ fnv1a(mask) |
| 0x34 | 8 字节 | payload 大小 ^ fnv1a(mask) |
| 0x3C | 4 字节 | fnv1a(mask) |
expand 32-byte k。见过 ChaCha20 的人不可能认不出 ChaCha20。flags = 3 会开启反调试检查(PEB->BeingDebugged、查询调试端口,老一套)和一个反沙箱评分。任何一个被触发,程序就悄悄退出。沙箱看到的就是一个正常程序打开文件然后退出。挺聪明。但问题是,key 就明晃晃地放在文件里。(???)根本不需要运行它:pythonCopymask = bytes.fromhex("56951de331cd7f254bf1931533dd82bc3c8bf542f0d1ed5736a40f394c51d0a1")
h = fnv1a(mask)
size = u64(footer, 0x34) ^ (h | h << 32)
fl = h ^ u32(footer, 0x30)
pad = fl >> 8
key = xor(mask, footer[:32])
nonce = footer[32:44]
payload = chacha20(key, nonce, data[-64 - pad - size : -64 - pad])这样就解出了第二个 PE。929 KB,MSVC 编译,C++20,捆绑了 zlib。搞了一堆反分析的幺蛾子,结果十几行 Python 就把混淆扒干净了。不出所料,是个 Stealer
字符串全加密,导入表只留 CRT,所有东西运行时才解析。结果WinMain 直接把所有模块按名字明文列了出来: Copyosinfo
browsers
telegram
wallets
discord
steam
clipboard
remoteaccess
credentialmanager
authy
notes
obs
ssh
email
games
filegrabber其余每个字符串都有专门的函数:cCopyv5 = _mm_xor_ps(v6, v5);
v7 = { 1924987977, 1270327144, 877876327, 271431577 };
v8 = { 641333755, -1942364857, ... };
sub_140080F40(&v5, v7, v8, 0x20);
两个常量异或生成密钥、IV 和密文长度。sub_140080F40 使用 AES,S-box 隐藏在 RC4 之后——显然一层加密还不够硬核。试了第一个模块的标准模式:
Copy
cbc b'w\x1c\xe9\xc6\xa0y\x96\xa4...'
ctr b'guid=\x00\x00\x00...'
AES-128-CTR,每个字符串独立一个密钥。672 处调用点。我绝不打算手动处理这些。于是我把所有调用点都从 IDA 里提取出来,在 Unicorn 中仅模拟每个调用点前几条指令,从寄存器中取出密钥、IV 和密文,再用 Python 解密。601 处解密结果清晰可读,剩下的藏在大函数里,但我根本不在乎——601 处已经足够了。
它想要的一切
- 浏览器:Chrome、Edge、Brave、Opera、Opera GX、Vivaldi、Firefox。包括密码、Cookie、自动填充,甚至 Chrome 新的应用绑定加密。
- 加密货币钱包:Exodus、Electrum、Atomic、Guarda、Coinomi、Ledger Live、Trezor Suite、Wasabi、Sparrow、Monero、Zcash、Armory,以及浏览器扩展钱包。
- 密码管理器:KeePass、KeePassXC、Bitwarden、1Password、NordPass、RoboForm、Windows 凭据管理器。
- 账户信息:Telegram、Discord token、Steam、Roblox Cookie、Minecraft 账户、Authy。
- 开发相关:
.ssh、.aws、.azure、gcloud、.kube、.docker。 - 远程访问:AnyDesk、TeamViewer、WinSCP、FileZilla、mRemoteNG、RDCMan。
- 其他:Outlook、Thunderbird、VPN 配置、OBS 设置、便签,以及桌面文件。
YouTube 频道
没有硬编码服务器,而是解密后得到: Copywww.youtube.com/channel/UC18vFC1xgebddr_7NsvgBYA
gist.githubusercontent.com/jasonterra69/48d9e264c05843f0cdc302143b4400c8/raw
[[
]]
ZhxchsdfhSGdfgsgdfAJsakdaksdk2364236AH
一个 YouTube 频道、一个 GitHub Gist、两个花括号,还有一个明显是某人乱按键盘生成的密钥。这个 YouTube 频道名叫“bubblegym”。创建于 2026 年 9 月 14 日:
对 Base64 解码后的数据进行 XOR 运算,密钥就是那段键盘乱按,结果得到了以下地址:
pythonCopy
b = base64.b64decode("OA0dDQ0HFBQHJyIHEkkQCAlJLS0JTgwAAB8S")
k = b"ZhxchsdfhSGdfgsgdfAJsakdaksdk2364236AH"
bytes(x ^ k[i % len(k)] for i, x in enumerate(b))
Copy
beenetprotect[dot]com/lgz/gdata
这个地址似乎还硬编码在二进制文件里作为后备方案???
据我理解,dead drop(死信箱/中转站)的初衷应该是可以随时更换服务器,而不让地址直接暴露在恶意软件中。但你居然把地址直接写进了恶意软件里,那再从 Gist 和 YouTube 获取地址还有什么意义?
Opsec 水平:Cloudflare 注册商
CopyDomain Name: BEENETPROTECT.COM
Creation Date: 2026-09-14T06:21:54Z
Registrar: Cloudflare, Inc.
Name Server: DONALD.NS.CLOUDFLARE.COM
Name Server: JULISSA.NS.CLOUDFLARE.COM
9 月 14 日注册。和那个“游戏频道”是同一天。构建日期是 10 月 6 日,10 月 8 日出现在 torrent 中。
给 *arr 用户的 PSA(公共安全通告)
如果你使用公共索引器运行 Sonarr 或 Radarr,这事肯定能撞上你。Sonarr 本身不能执行 exe,所以它不是问题所在。问题在于你的室友、你的父母,或者是凌晨 3 点你在下载文件夹里双击运行的那个(请勿执行这个垃圾恶意软件)你自己。 花五分钟做以下配置:- qBittorrent:将
*.exe、*.scr、*.lnk、*.bat、*.cmd添加到“排除文件名”,它会直接拒绝下载这些文件。 - Sonarr / Radarr:当看到这些文件时,使用带有“从客户端移除”功能的黑名单进行拦截。
- Prowlarr:如果某个 tracker 总是提供这种垃圾,降低其优先级或直接移除它。
原始来源: Hacker News