FiveM

FiveM 里的“约翰叔叔”:GP212887 感染链与安全处置

解释“约翰叔叔”在这里指代的 FiveM 后门感染链,梳理已确认样本、检测证据、自动修复边界和服务器处置方法。

本文中的“约翰叔叔”不是人物介绍,也不用于推断现实身份。它是对一类 FiveM resource 感染链的社区称呼。CK 最初核验的样本名为 ox_lib-GP212887.zip,因此工具内部也使用 GP212887 作为这条精确样本链的标识。

这类问题的重点不是资源名称,而是攻击代码如何藏进正常 resource、如何被 manifest 接入,以及外部内容如何进入动态执行。最初样本出现在 ox_lib,不代表只有 ox_lib 会被感染。当前扫描器会遍历 resource、整个 resources 目录和 ZIP,并对所有匹配的 Lua、JavaScript、HTML、manifest、配置和二进制候选执行静态检查。

约翰叔叔感染链是什么

GP212887 不是一个孤立的恶意文件,而是多个文件互相接线形成的执行链。已确认样本同时修改资源入口、NUI 页面、Lua 初始化代码,并加入伪装成字体和正常前端文件的载荷容器。

样本位置 在感染链中的作用 当前处置
fxmanifest.lua 把 NUI 切换到恶意 dashboard,并加载额外 loader 精确恢复目标行,保留其他内容
resource/init.lua 通过字符拼接隐藏 load,尝试从伪字体读取并执行内容 只移除确认追加的恶意块
client/loader.js 读取资源内容,Base64 解码后交给动态函数执行 确认命中后删除
web/static/dashboard.html 内嵌远程取回并动态执行的前端载荷 确认命中后删除
web/fonts/Verdana.ttf 伪装成字体,实际字体头无效并带有活动域名 确认命中后删除

manifest 是这条链的重要连接点。单独存在一个可疑文件,不一定会被 FiveM 加载;当 manifest 同时把页面和脚本接入资源,多个信号才形成完整的高置信结论。

当前样本里确认了什么

分析过程只读取 ZIP 条目名和文件字节,计算 SHA-256,并对文本、Base64 和字符串混淆做静态还原。没有提取到可运行 resource,也没有调用 Lua、JavaScript、HTML 或 FiveM 运行环境。

当前样本中确认了这些事实:

  • client/loader.js 存在 Base64 解码后交给 new Function 的路径。
  • dashboard 中的静态 Base64 内容会访问外部地址,并把响应交给动态执行。
  • 伪 Verdana.ttf 没有合法 TTF 或 OTF 文件头,并包含经过插入字符混淆的同一活动域名。
  • manifest 同时接入 dashboard 和 loader。
  • resource/init.lua 中存在人为追加的伪字体动态加载入口。

样本签名包记录的历史活动域名包括:

  • jokerx1zai.com
  • jokery1zai.com

域名单独出现只能作为 IOC 线索,不能成为自动删除文件的唯一依据。正常文档、黑名单或安全工具也可能包含这些字符串。

报告中的字体偏移矛盾

原检查报告描述,Lua 会从 Verdana.ttf 的第 87565 字节开始取得载荷。但实际 ZIP 中的这个文件只有 91 字节,对当前副本执行同样的切片会得到空内容。

这个矛盾说明报告不能直接变成修复脚本,也不能说明样本安全:

  • 当前副本中的 Lua 字体取载荷路径可能无法按报告描述完成。
  • manifest 接入的 JavaScript loader 仍然存在。
  • dashboard 的远程取回和动态执行链可以独立成立。
  • 伪字体仍包含同一活动域名。
  • 其他变体可能携带更长的字体载荷。

因此 CK 的规则同时检查已知哈希和结构证据,不依赖单一文件尺寸或一条报告描述。

为什么不能看到 load 就删除

FiveM resource 中很多能力本身是正常的。PerformHttpRequest、fetch、Discord Webhook、Base64、Buffer.from、String.fromCharCode、load、os.execute 或混淆标记,单独出现都不足以证明后门。

扫描器只有看到稳定的数据流或多个独立信号时才升级结论,例如:

  1. 外部网络响应或网络事件参数成为不可信输入。
  2. 输入经过 Base64、XOR、LZString、KVP 或伪装文件持久化。
  3. 结果进入 load、loadstring、eval、new Function、Node VM 或系统命令执行。
  4. manifest 又明确加载了对应脚本。

这种“来源、处理、执行、接线”的组合判断,比关键词扫描更慢一些,但能显著减少误删正常资源。

不只扫描 ox_lib

CK 扫描移除后门 当前会扫描所有传入目标,而不是只认 ox_lib 目录名。v0.2.0 除了 GP212887 精确链,还覆盖:

  • Lua HTTP 响应直接进入 load 或 loadstring。
  • Lua 网络事件参数直接进入动态执行。
  • JavaScript 网络取回与 XOR、Base64、LZString、Node VM、eval 或 new Function 的组合链。
  • fxmanifest.lua 和 legacy __resource.lua 对已确认恶意脚本的接线。
  • Blum、Warden、Cipher 等公开 FiveM 后门活动的组合 IOC。
  • txAdmin 核心文件篡改标记和 JohnsUrUncle 管理员。
  • cfg、JSON、C#、DLL 和 EXE 字节中的已知 C2 字符串。

不同类型的处置强度并不相同。高置信恶意 JavaScript 可以在备份后移除并同步清理 manifest;完整闭合的单行 Lua RCE 可以精确删行。多行 Lua RCE、txAdmin 核心文件、管理员记录和二进制只告警,留给人工复核。

扫描与修复为什么分开

组件把操作拆成三个阶段:

  • scan:只读扫描,返回路径、规则、证据、严重度和是否可修复。
  • repair:默认只生成修复预览,显式确认写入后才创建备份并修改。
  • restore:按 Run ID 检查并恢复,发现修复后文件又被修改时默认拒绝覆盖。

目录修复会把备份放在目标 resource 外部,避免备份文件再次被 manifest 打包或加载。ZIP 默认生成新的 *.cleaned.zip,原 ZIP 保持不变。修复后必须重新静态扫描;仍有可自动修复的高危项时,目录写入会自动回滚,清洁 ZIP 也不会交付。

组件还会拒绝自动处理路径穿越、符号链接、重复路径、损坏或异常压缩比的 ZIP,防止“扫描恶意包”本身变成新的写入风险。

GP212887 的验证结果

对固定样本的 v0.2.0 回归结果为:

项目 结果
初始静态发现 15 项
Critical 14 项
自动修复动作 5 项
精确修改文件 2 个
删除恶意新增文件 3 个
保持哈希不变的其他文件 109 个
清洁副本复扫 0 项发现

5 个动作只修改 fxmanifest.lua、resource/init.lua,并删除三份确认恶意的新增文件。没有因为扩展通用规则而扩大这个样本的写入范围。

当前仓库的 15 项自动测试也全部通过,覆盖正常 HTTP/Base64 不误报、目录与 ZIP 修复、备份恢复、冲突保护、单行与多行 Lua 的处置差异、txAdmin 人工告警和通用 JavaScript 投递链。

服务器命中后还要做什么

清理 resource 只能阻止这份文件继续执行,不能证明服务器和开发机从未受影响。若感染版本曾经启动过,建议继续完成:

  1. 先隔离样本并保留只读副本、日志和哈希。
  2. 停止使用受影响 resource,检查其他资源和下载来源。
  3. 轮换数据库、面板、API、SSH、RDP 和机器人凭据。
  4. 检查计划任务、启动项、新账号、新文件和异常外联。
  5. 核对 txAdmin 管理员和核心文件,必要时用匹配版本重新部署。
  6. 让曾连接的客户端执行终端安全检查。
  7. 从可信来源重新取得关键组件,再进行差异核对。

不要在生产目录上直接批量搜索替换,也不要为了“确认行为”去运行可疑 ZIP。先扫描、预览和备份,再做最小范围修复。

能证明与不能证明的边界

静态扫描可以证明文件中存在特定字节、危险数据流、manifest 接线或已知样本哈希。它不能单独证明代码已经在某台服务器执行,也不能根据一个昵称、域名或文件推断现实攻击者身份。

工具也不是操作系统杀毒软件。它关注 FiveM resource 和相关配置中的静态链路。若服务器已经发生凭据泄露、系统持久化或横向移动,需要按完整安全事件处理。

项目与公开依据

本文最后核验:2026-07-17。IOC、后门实现和公开规则会变化,处置前应重新查看项目最新 Release 与覆盖文档。