APT态势与威胁情报系列
之前刷公众号看到名为APT研究顶级会议的推文,被”保持好奇,永不停止学习”的精神深深打动,于是想要跟随前辈们的脚步,做一个系列,来一场纯粹的探索。
在我看来,APT 的核心不在于高阶的战术,而是隐藏。身份、流量、痕迹,层层伪装,长期潜伏**。这个系列的目标,就是把公开报告里这些“身份隐藏”的技法拆开,留下冷静的记录,让红队从中学会藏身,蓝队于此着手识别**
既要推荐“强调身份隐藏”的 APT 报告,又要有实战味。不打磨,不粉饰,直指“大隐隐于市”式的真实干货。下面是几份非常契合这类风格、强调“身份隐藏”的 APT 报告推荐,我将援引以下报告中涉及的事件作为本系列前几话的研究重点
Kaspersky — “Q2 2024 APT 趋势报告”
Kaspersky — “Linux 平台 APT 攻击概览”
尽管这些事件在如今看来是比较陈旧的素材,但其构造攻击链条思路的精巧与所谓骗术的优雅,值得在当下蓝队安全体系逐渐完善的”攻防不对等”大情景下给予红队人员更深化的思考
XZ 后门事件
聚焦 liblzma backdoor 部分,感受供应链攻击如何做到“隐形入侵 + ”。

攻击背景
- 时间点:2024 年 3 月。
- 目标组件:XZ Utils 压缩库(liblzma),被广泛集成在主流 Linux 发行版中。
- 利用链条:因为
liblzma被 OpenSSH 的sshd间接依赖,所以一旦构建过程被污染,就能在sshd进程中触发恶意逻辑。
攻击手法(身份隐藏 + 供应链渗透)
长期社工 + 社区潜伏
攻击者以“陈嘉昌”身份混入开源社区,参与开发讨论,伪造贡献记录。
在公开场合反复互动,建立“可信开发者”形象。

操控构建过程
- 恶意代码不是直接写进主分支,而是巧妙地放在测试/构建辅助脚本中。
- 通过复杂的压缩脚本链条,最终影响到
liblzma,再间接作用于sshd。
后门特性
- 在
sshd进程中植入潜在的远程代码执行能力。 - 隐蔽度极高,普通代码审计几乎难以发现,直到二进制行为异常才被揭露。
- 在
这是供应链攻击的顶级案例,不仅是技术层面,更是 身份隐藏+社工渗透+长期潜伏 的完美结合。
事件时间线
2024.01.19 XZ 网站被新维护者 (jiaT75) 移至 GitHub 页面
2024.02.15 .gitignore 中新增 “build-to-host.m4”
2024.02.23 引入两个包含恶意脚本阶段的“测试文件”
2024.02.24 XZ 5.6.0 发布
2024.02.26 CMakeLists.txt 提交破坏 Landlock 安全功能的内容
2024.03.04 后门导致 Valgrind 出现问题
2024.03.09 更新两个“测试文件”,修改 CRC 功能,修复 Valgrind 问题
2024.03.09 XZ 5.6.1 发布
2024.03.28 发现错误,Debian 和 RedHat 通知
2024.03.28 Debian 将 XZ 5.6.1 回滚至 5.4.5-0.2 版本
2024.03.29 OSS-security 邮件列表发布邮件
2024.03.29 RedHat 确认后门 XZ 已在 Fedora Rawhide 和 Fedora Linux 40 beta 中发布
2024.03.30 Debian 关闭构建并启动重建进程
2024.04.02 XZ 主开发商认同后门事件
更详细的xz 开源攻击时间线

核心1——长期社工 + 社区潜伏
众所周知,在长期攻防的发展中,钓鱼/近源攻击在突破外点的工作中起到了越来越重要的作用。为什么?很简单的道理,防御思维的盲点 是 红队机会
防御方热衷搞静态分析、模糊测试,偏执于“技术检测”,但对开源技术社区所谓的社区文化、人力缺口、社交信任几乎没有防护机制。xz后门事件便成为了血淋淋的例子**,高级的攻击者不和防御机制玩所谓的”签名对抗”,而是接触开源文化,玩信任经济,在社会工程学上不断赢得防御方的正反馈,逐步化身为可信用户植入后门。**下面就讲讲JiaTan的潜伏大戏

2021
JiaT75(Jia Tan)创建了他们的 GitHub 帐户并打开了一个PR用于修改警告功能中的文本提示,同时利用不安全的变体替换了safe_print,同时这份代码在没有任何讨论的情况下就被合并了。
2022
2022年4月,Jia Tan通过邮件列表提交了补丁,同时出现了一个新角色——吉加尔·库马尔 ,他向开源社区施压并不断要求为xz添加另一个维护者
在向 Lasse Collin 施压添加另一名维护者的电子邮件三天后,JiaT75 首次提交PR给 xz: 测试:为硬件功能创建了测试。 自从这次提交以来,他们正式成为 xz 的定期贡献者
另一个帐户—— 丹尼斯·恩斯 (Dennis Ens) 也参与了施压,要求**维护者给出XZ for C的维护权。**电子邮件格式相似,姓名+数字格式相似。这个帐户也从未在 xz 讨论之外出现过,也没有发现任何相关的帐户。

从这些账户特征作为分析的出发点,就可以从中发掘出这极可能是一场有组织性的开源文化心理压迫,通过多个账户向维护者施压并提升关键用户的可信度,并逼迫维护者让权
本质上就是典型的 astroturfing(人造舆论场)。多个账号协调一致,不断提出“增加维护者/交出权限”的要求。邮件往复堆叠,给单一维护者(Lasse Collin)营造持续的心理压力。

利用维护者精力有限+孤立无援的状态,通过群体施压逼迫让权。
2023
JiaT75 于 2023 年 1 月 7 日合并了他们的第一次提交,从这天起,他正式进入“可信开发者”行列,具备了在仓库里直接推动变更的能力。
3 月,Google oss-fuzz 中的主要联系电子邮件更新为 JiaTan 的,而不是 Lasse Collin。这标明着JiaTan正式谋权成为了官方维护者之一,项目安全测试的第一手沟通渠道也被转移到JiaTan者手上。
同时 对应本次供应链的漏洞关键代码也成功落地,虽然 Lasse Collin 被认为是该漏洞的作者,但 Jia Tan 也参与了该漏洞的开发,该漏洞最初由 Hans Jansen 于 6 月份编写:
- Commit: liblzma: Add ifunc implementation to crc64_fast.c
- PR: Replaced crc64_fast constructor with ifunc by hansjans162
也就是**//Hans 写代码 → Jia 推提交 → 署名套到 Lasse。//**
事实证明,黑客可以为了你左右脑互博

对应的,在这里的Author署名被套到了Lasse

HansJansen的账户在此前后几乎没有任何账户活动,只是为了将危险代码落地到XZ的官方代码中
有人生成
2024
一个针对 Google oss-fuzz 的拉取请求 ,把项目 URL 从 tukaani.org/xz/ 改成 xz.tukaani.org/xz-utils/。看似是个普通的“项目路径调整”。
原始域名 tukaani.org 在芬兰的一个主机商上托管,是 Lasse Collin 掌控的基础设施。
新增的 xz.tukaani.org 子域却指向 GitHub Pages,控制权转移到了攻击者能操作的范围。
结果:项目外部的官方入口逐步被 Jia 掌控。
包含执行此后门所需的最后步骤也被添加到存储库:
后续则是被某个安全研究员发现对应 liblzma模块占用了大量CPU时间,导致了延迟,因此深入的探究并发现了该漏洞利用链

核心2 ——操作构建过程
植入后门的引导程序,是Jia Tan在2024年,也就是潜伏最后阶段提交的两个测试文件[bad-3-corrupt_lzma2.xz,good-large_compressed.lzma],这些文件看似无害,但实际上攻击者可以在需要时提取隐藏在错误数据中的shell脚本与后门。

这一段已经是 XZ backdoor 的“武器化阶段”,之前几个月都是打地基、养身份、铺环境,现在是真正让后门能跑起来了
1. 控制分发入口
- Github Releases:表面上发的是正常源码,里面虽然有测试文件但不会直接执行 → 无害。
- xz.tukaani.org:关键!大多数 Linux 发行版不是从 Github 拉源码,而是从 xz.tukaani.org(也就是JiaTan在2024年恶意篡改导向他个人接管的gitpage) 下载。
- 这个子域名已经被 Jia Tan 接管。
- 于是 真正带恶意的版本只在这个 URL 发布。
这就像在“官方商店”和“供应链仓库”里分别放不同的货,测试者看到的干净,发行版打包用的却是投毒版。
大多数发行版都使用此 URL,下载时,它附带一个名为 build-to-host.m4 的文件,其中就包含恶意代码。

它会在构建过程(./configure 阶段)被执行,这意味着只要有人打包/编译,就会触发。这行代码主要用 tr 修复一个看似“坏掉的”测试文件:bad-3-corrupt_lzma2.xz。把修复后的数据管道给 xz -d 解压,解压的数据隐藏了一个 shell 脚本,最后使用 build-to-host.m4 触发的bin/bash执行这个shell脚本
2.Payload解密上线后门

恶意 .m4 文件释放的shell脚本首先会检查:
- 是否在 Linux 系统上运行;
- 是否在正确的 build 流程中(避免在错误环境里暴露)
下一阶段载荷载体:good-large_compressed.lzma
文件表面上是“正确压缩的 XZ 测试文件”。
实际上在解压出来的数据里混入了大量“垃圾字节”,恶意 payload 被埋在其中。
伪装点:文件名里写着“good”,压缩也确实没问题,更容易骗过人工审查。
因此如何通过清洗下一阶段载荷载体中的垃圾数据,上线后门,shell脚本也有一套非常规的拆分拼接手法
head 命令流水线:
- 每次要么丢掉 1024 字节,要么提取 2048 或 724 字节。
- 循环下来,拼凑出 33,492 字节(= 2048*16 + 724)。
tail 命令:
- 在拼接结果里只保留最后 31,265 字节,丢掉其余部分。
3. 解码与执行
tr:做字符替换,把字节流进行一次简单位移/还原(去混淆)。xz -d:把转换后的数据再用xz解压,得到一段 原始 LZMA 流。pipe → shell:最终把解压结果直接送进/bin/sh执行。
4. 最终提取阶段
脚本先确认运行环境是否满足攻击者预设条件:
- 项目构建时是否启用了 IFUNC。
- 编译器是否为 GCC。
- 工程里是否存在攻击脚本需要的两个测试文件。

后门二进制提取流程
载体:依然是 good-large_compressed.lzma,但这次换了新的偏移位置。
提取过程通过一系列命令运行,每个命令的结果作为下一个命令的输入。格式化的单行代码如下所示:

操作链条:
- 用 XZ 工具先解压文件。
eval $i执行一串head调用,切割数据流,逐步拼出隐藏 payload。- 用自定义的 类 RC4 算法 对数据解密。
- 得到另一个压缩文件,再次用 XZ 解压。
- 按预定义偏移丢掉数据头的一部分字节,得到最终 payload。
- 把结果保存为
liblzma_la-crc64-fast.o。
意义:这个 .o 文件就是实打实的后门对象,会在后续 链接流程 中直接嵌入 liblzma。
脚本还会修改 crc_x86_clmul.h 文件里的函数:把 __get_cpuid 改成 _get_cpuid。避免编译/链接时报错,确保恶意 .o 文件能顺利合入最终库。
这一步是“拼图最后一块”:没有这行改动,恶意对象可能不会被编译器接受。
感染链条概览
入口:xz 5.6.0 / 5.6.1 tarball(从被攻陷的 xz.tukaani.org 下载)。
构建阶段:
- 调用恶意的
m4/build-to-host.m4脚本。 - 脚本修复并解压
bad-3-corrupt_lzma.xz,释放出第一段 shell 脚本。 - 这个脚本再去解压
good-large_compressed.lzma的一部分。
后续链条:
- 从
good-large_compressed.lzma提取加密数据。 - 通过 AWK 实现的定制 RC4-like 算法解密。
- 再次用 xz 解压得到二进制数据。
- 最终落盘成
liblzma_la-crc64-fast.o,在编译/链接过程中被嵌入库里。

由于本系列主要分析的是整条感染链条中JiaTan如何隐藏恶意代码与真实目的,因此对于后门代码的分析暂且搁置,感兴趣的朋友们可以自行查阅XZ后门分析。

在 XZ 案例中,攻击者直接利用了 开源文化的人际信任机制,通过身份渗透、社交压迫、长期 patch 养成,把恶意逻辑塞进了光天化日之下的构建脚本。
这种 高度互动的社交工程 + 技术投毒的结合,是过去大部分 APT 还没玩过的套路。

总结与警示
XZ backdoor 事件并不是单纯的“代码被投毒”,而是一场 供应链信任实验:攻击者在身份层面通过社交工程和长期潜伏撬开了开源社区的信任防线;在技术层面,他们把恶意逻辑嵌进构建流程和测试文件里,环环相扣,直到最终在毫无预警的情况下把后门编译进关键的系统库。
对红队来说,这说明 身份与流程的操纵 已经可以和传统漏洞利用、0day 并列为攻击路径;未来高水平的 APT 行动很可能会把“人 + 代码 + 供应链”三者结合,达到比单纯技术投毒更深的隐匿。
对蓝队而言,警醒点在于:
- 你不能再只盯着二进制里的签名和恶意代码片段;
- 你必须把注意力扩展到 开源生态的人力因素、构建链的完整性 和 分发渠道的真实性;
- 单靠 fuzz、静态分析、CI 扫描都不够,因为这类攻击压根不是靠 0day,而是靠你习以为常的“流程漏洞”。
一句话:如果信任链本身被玩坏,再强的检测也只是摆设。
