← 返回信息流
AI 资讯Hacker News·3 小时前

一次失败的国家支持攻击解剖

原标题:Anatomy of a Failed (Nation-State?) Attack

速览

文章深入剖析了一起疑似由国家支持的网络攻击事件。通过拆解攻击过程,揭示了攻击者使用的战术与防御机制的对抗。此次分析有助于理解高级持续性威胁的特征及防御策略。

AI 深度解读

一次失败的(国家级?)攻击解剖

背景

近期,一位居住在加拿大的 Rust 开发者遭遇了一起精心策划的“虚假面试”网络钓鱼攻击。攻击者伪装成一家名为 Lua Ventures 的(实际上已停止运营的)新加坡去中心化金融(DeFi)风险投资机构,试图通过技术测试环节将恶意软件植入受害者的开发环境。

该攻击者使用了虚构的身份,但其姓名与现实中存在的某些人相似,作者特意在文中省略了这些无关人员的姓名以避免混淆。值得注意的是,Reddit 上的其他 Rust 社区成员也报告称遭遇了类似的定向攻击。

由于事件具有时效性,作者已将相关信息报告给加拿大相关机构(如加拿大网络犯罪中心 CCCS 等)。值得注意的是,包含恶意负载的图像文件在 VirusTotal 上并未触发任何杀毒引擎。作者将此次发现的恶意软件命名为“PinpinRAT”,这一名称源于恶意软件内部字符串,但其在网络上的其他已知名称尚不明确。

核心内容

攻击初期:建立信任与误导

攻击始于两周前的一封电子邮件,发件人自称来自 Lua Ventures。邮件看起来非常逼真,甚至包含了一个看似合法的 LinkedIn 个人资料链接。为了增加可信度,攻击者还提到了两家其“投资”的公司:LyrasingRoadpay。这两家公司虽然网络存在感薄弱,但处于早期阶段,因此并未引起作者最初的警觉。

随后,双方通过邮件协调了面试时间。通话中,对方是一位带有德国口音、自称正在旅途中的人。尽管细节略显奇怪,但并未触发作者的警惕机制。

陷阱设置:TypeScript 仓库与“测试”

通话结束后,攻击者发送了一封后续邮件,要求作者完成一项“测试”。作者克隆了提供的代码仓库,此时真正的红色警报才真正响起。

作者感到幸运的一点是,攻击者发送的是一个 TypeScript 仓库。对于 Rust 开发者而言,这本身就不合逻辑,且任务说明更像是一份 TypeScript 的求职面试,而非架构分析。出于谨慎和懒惰,作者将仓库打包并输入给 Claude(由 Anthropic 开发的大型语言模型)进行快速扫描。

恶意代码分析:PinpinRAT 的发现

Claude 迅速识别出了异常:

  1. 根目录的 package.json 没有 postinstallpreinstall 钩子,但这与项目使用 patch-package(通常绑定在 postinstall 中)的做法相矛盾。
  2. 作者手动扫描发现存在大量 patches/ 目录,这通常是用于掩盖真实恶意负载的噪音。

Claude 进一步在 typescript+5.9.2.patch 文件中发现了恶意载荷。该文件伪装成对 TypeScript 模块说明符的常规补丁,但在 tsc.jstypescript.js 的顶部注入了一个自执行的混淆存根(stub)。

该存根代码逻辑如下:

  • 解码 Base64 字符串。
  • 使用密钥 73 进行 XOR 解密。
  • 通过 new Function(...) 执行解密后的代码,并将 requireBufferWebAssemblyprocess 等关键对象传入。

这意味着,每当运行 tsc 或任何导入 typescript.js 的操作(如 npm run typecheck、构建或开发服务器启动)时,恶意代码就会执行。意识到风险后,作者立即停止在本地机器上进一步操作,将文件加密打包并在沙箱环境中继续分析。

恶意软件机制:三层混淆与持久化

该仓库以名为“Ticket Harbor”的渡轮票务应用为主题。任务文件指示用户在提交前运行类型检查、测试套件及构建命令,这正是触发恶意代码的陷阱。

执行链条如下:

  1. 隐藏补丁:四个独立的 postinstall 钩子运行 patch-package。其中一个钩子还对补丁文件执行 git update-index --skip-worktree,使其在 git status 中隐藏。
  2. 载荷注入typescript+5.9.2.patchtypescript.js_tsc.js 顶部注入自执行存根。该存根避免使用 eval 以规避检测,而是使用 new Function
  3. 第二阶载荷:加载器读取附加在隐藏文件 operators/3.png 中的数据块,运行一个嵌入的小型 WASM 存根,随后派生出一个静默的、分离的 Node.js 进程,携带一个 1.68 MB 的混淆第二阶载荷。
  4. 清理痕迹
    • 利用 git skip-worktree 隐藏文件。
    • 投放器在首次运行后重写补丁文件,删除自身注入的行。
    • 第二阶临时目录在执行后自删除。

PinpinRAT 的结构: 恶意软件经过三层混淆:首先是 obfuscator.io(声称具备 LLM 保护),随后是两层 Base64 编码。Claude 在沙箱中仅用约 5 分钟就逆向工程了解开这些混淆,速度远快于人工。

恶意功能:远程访问木马 (RAT)

该载荷是一个功能完整的远程访问木马(RAT),由具备专业知识的人员编写。它使用 RSA 密钥进行本地设置,并使用 AES-256-CBC 作为会话密钥。

启动行为:

  • 主机指纹收集:通过 checkin 例程收集并外泄主机信息,包括所有非内部接口的 IP 地址、用户名、主机名、OS 类型/版本/平台/架构、进程 PID、完整的 process.argv 以及 Node.js 版本。
  • 加密通信:生成 RSA-2048 密钥对和随机 AES-256 会话密钥,后续所有通信均使用 AES-256-CBC 加密并附带 HMAC-SHA256 完整性标签。

支持的控制命令:

  • env:转储并发送 process.env
  • upload:读取任意文件路径并外泄。
  • download:将攻击者提供的字节写入任何可写路径。
  • spawn:运行任意进程,支持可选的 Shell 扩展。
  • ls/cd/pwd/cp/mv:基本文件系统操作。
  • dns:通过指定解析器解析任意名称(可能用于 DNS 隧道)。
  • dismantle:自我移除。

关键要点

  • 社会工程学与技术结合:攻击者利用虚假的风投背景、LinkedIn 资料以及看似合理的“技术测试”任务,成功降低了开发者的警惕性。
  • 供应链/依赖注入风险:攻击者利用 patch-package 机制,通过修改 node_modules 中的核心库(TypeScript)来注入恶意代码。由于 patch-package 常用于修复依赖问题,这种手法极具隐蔽性。
  • LLM 在安全分析中的价值:作者利用 Claude 快速识别出混淆代码中的异常模式,并协助逆向工程多层混淆的恶意载荷。这展示了 AI 工具在加速威胁情报分析和恶意软件逆向工程方面的巨大潜力。
  • 多层混淆与反取证:恶意软件采用了 Git 隐藏技巧、代码自修改、临时文件自删除以及多层混淆(WASM、Base64、JS Obfuscator)来逃避检测和清理痕迹。
  • 高权限与持久化:一旦执行,RAT 即可获取主机完整控制权,包括文件读写、进程执行和网络通信,且通信经过强加密,难以被网络监控轻易识别。

意义与影响

此次事件揭示了针对软件开发者的定向攻击日益复杂化。攻击者不再仅仅依赖简单的钓鱼链接,而是深入技术工作流,利用开发者对代码审查的信任和对构建流程的依赖(如 npm installpostinstall 钩子)进行渗透。

对开发者的启示:

  1. 验证来源:对于来自陌生“招聘方”或“投资方”的代码仓库,尤其是涉及构建脚本和依赖补丁的,应保持极高警惕。
  2. **沙
查看原文 →grack.com