本周,一个虚假客户向我的收件箱发送了一个恶意的 GitHub 仓库,仅仅是运行了启动脚本,就让我两天的劳动成果付诸东流,并泄露了我存储在浏览器中的所有密码。
这个“客户”发布了一个高薪高级工程师职位,沟通非常迅速,并发送了一个看起来很专业的仓库。要求很简单:克隆代码,运行 npm run dev,然后发送一张截图以证明演示程序可以正常工作——没有合同,也没有背景调查。就在开发服务器启动的那一刻,配置文件中隐藏的代码便连接到了命令与控制 (C2) 服务器,获取了第二阶段的有效载荷 (payload),并开始从本地机器中窃取凭据。
攻击是如何展开的
恶意有效载荷隐藏在 postcss.config.js 中,大多数开发者通常会忽略这个文件,因为它通常只包含一些简单的 CSS 处理规则。在这种情况下,攻击者在一条合法语句的最右侧添加了一行经过混淆的 JavaScript 代码,并用空格填充以使其看起来不显眼。当执行 npm run dev 命令触发 PostCSS 流水线时,这行隐藏的代码就在不知不觉中运行了。
该恶意软件迅速执行了以下三个步骤:
- C2 联系 – 它向攻击者控制的服务器建立了网络连接,并通报了受感染的主机。
- 第二阶段下载 – 它拉取了包含实际数据窃取逻辑的额外代码。
- 浏览器凭据窃取 – 在 macOS 上,它查询了存储在系统钥匙串 (keychain) 中的 Chrome Safe Storage 密钥。如果用户批准了钥匙串提示,攻击者就会获取 Chrome 中保存的所有密码。
除了直接的窃取行为外,该有效载荷还把自己写入了几个常用的开发工具——VS Code、npm、Discord——因此,未来任何一次启动这些应用程序都会重新激活恶意代码。简单的重启并不能清除感染;下一次执行 npm install 或打开编辑器都会重新唤醒后门。
经常被忽视的危险信号
- 在签署任何合同之前要求运行代码。 正规的招聘流程通常在共享任何专有工作之前都会签署正式协议。
- 伪装成“项目简介”的压缩文件。 Zip 或 RAR 压缩包可以隐藏可执行脚本或恶意二进制文件。
- 要求提供个人电子邮件地址以“绕过平台过滤器”。 这种手段是为了将对话转移到受保护平台之外,从而避开滥用行为的举报。
- 要求候选人为加密钱包注资或购买测试代币的工作描述。 这类要求在真实的开发工作中是非常罕见的。
保持安全的实用步骤
- 在未经检查的情况下,绝不要执行陌生人的代码。 以只读视图打开仓库(例如通过 GitHub 的 raw 文件视图),并扫描每个脚本,特别是配置文件和
package.json中的scripts条目。 - 将所有附件视为纯文本。 如果收到 zip 文件,请在沙箱环境中解压,并在打开任何内容之前检查其内容。
- 使用专门的密码管理器,而不是浏览器存储。 即使浏览器的钥匙串被攻破,密码管理器的保险库仍然是隔离的。
- 在没有网络访问权限的隔离虚拟机或容器中运行不受信任的代码。 这可以阻止攻击者连接到 C2 服务器。
- 为所有账户启用双重身份验证 (2FA)。 如果密码被盗,第二个因素可以阻止未经授权的登录。
- 保持开发工具为最新版本,并在可用时启用自动完整性检查。 一些编辑器现在会在核心文件被意外修改时发出警告。
如果你怀疑自己运行了恶意代码,请假设系统已被攻破。备份重要数据,抹除驱动器并重新安装操作系统。简单的重启无法清除那种会重写常用应用文件的持久化机制。
底线: 一行隐藏的 JavaScript 代码就能将一次常规演示变成一场全面的凭据窃取行动。在验证之前,请将每个仓库都视为不可信,并将隔离作为工作流的默认环节。一时大意的代价远超仔细检查文件所花费的精力。
