授权渗透测试 Debian 与 Ubuntu APT 供应链风险:验证中间人替换软件包的条件与回滚

枫少@KillBoy
枫少@KillBoy
枫少@KillBoy
管理员
412
文章
0
粉丝
渗透测试536字数 3481阅读11分36秒阅读模式
AI智能摘要
授权渗透测试中,APT供应链风险不能只看“有没有漏洞”。真正决定风险闭环的是四个条件能否同时成立:HTTP流量可被操纵、目标正处于软件包下载或安装窗口、Acquire::Retries非零,以及被替换的.deb能绕过完整性校验进入安装路径。CVE-2026-109518暴露的正是这一下载验证绕过面。测试如何在隔离网络、快照回滚与无害载荷约束下验证而不越界?
— AI 生成的文章内容摘要

在获得书面授权、使用隔离测试网络和可回滚快照的前提下,验证 Debian 与 Ubuntu APT 供应链风险,重点不是构造通用远程利用,而是确认四个条件是否同时成立:系统到软件源之间的 HTTP 流量是否可被操纵、目标是否正处于软件包下载或安装窗口、Acquire::Retries 是否非零,以及被替换的包能否在完整性校验之后进入安装路径。CVE-2026-109518 的公开信息显示,这是一处 APT 下载验证绕过:位于路径上的攻击者、恶意镜像或代理可在 APT 检查包之后替换 .deb,安装时以 root 执行包内脚本。测试应使用自建无害包和故障注入代理,任何一步越过授权范围或影响业务,都应停止并回滚。

授权 APT 供应链验证的四条件剖面示意图

授权边界、前置条件与安全控制

这类验证必须先把“允许做什么”写清楚,再谈技术步骤。授权文档至少应包含:测试资产清单(主机名、IP、镜像源、代理和仓库地址)、允许的时间窗口、允许的请求类型、禁止行为、紧急联系人和回滚责任人。测试网络应与生产业务隔离,使用独立 VLAN 或虚拟网络;测试机应具备快照,记录快照 ID;代理和测试仓库只服务于本次验证,不转发生产流量。

测试载荷必须无害。建议自建一个只写标记文件、不启动服务、不修改 SSH、防火墙、定时任务或账户的测试包。不要使用真实恶意包,也不要在生产主机上执行替换演练。若组织没有隔离代理或测试仓库,只做只读基线检查和日志核对,不进入安装演练。

停止条件应提前约定:出现非测试包被安装、测试流量进入生产网段、关键服务异常、代理影响其他主机、无法解释的 root 脚本行为、无法回滚或发现真实恶意包时,立即停止并保全证据。回滚优先级是快照恢复,其次是卸载测试包、恢复源列表、删除代理故障注入规则和清理测试仓库。

侦察:先记录基线,不要先动流量

只读侦察的目标是回答三个问题:系统版本和 APT 版本是什么、软件源使用什么协议、异常重试和自动更新是否可能发生。以下命令在测试机上执行,输出写入证据目录:

lsb_release -a
apt --version
apt-config dump | grep -i 'Acquire::Retries'
grep -RhsE '^(deb|URIs:)' /etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null
systemctl list-timers 'apt-daily*' 'unattended-upgrades*' --all

apt --version 用于和官方修复版本对照。源列表中如果出现 http://,说明系统到仓库之间存在可被路径攻击者观察或修改的 HTTP 段;https:// 能降低这类传输篡改面,但不能替代 APT 自身更新和仓库信任检查。Acquire::Retries 若显式显示为非零值,例如 Acquire::Retries "3";,说明重试条件明确存在;若没有显式输出,不要直接判定为 0,应按发行版默认行为判断。Ubuntu 官方公告明确指出 22.04 LTS 及更新版本默认受影响,较旧版本仅在 Acquire::Retries 设置为非零时受影响。定时器输出则帮助判断自动更新窗口,生产环境验证应避开这些窗口。

同时记录 APT 代理配置:

apt-config dump | grep -iE 'Acquire::(http|https)::Proxy'

如果系统通过不受控代理访问仓库,代理本身就是需要纳入授权范围和证据链的对象。代理日志应至少保留时间、客户端、请求 URL、状态码、重定向目标、响应长度和响应文件哈希。

假设与测试矩阵:四个条件逐一对照

把风险拆成四个可观察条件,比笼统判断“有没有漏洞”更有用。四个条件同时成立,才说明替换链条在测试环境中闭环;只有 HTTP 源,或只有重试配置,都不足以单独证明可利用。

条件可观察证据安全验证方式条件缺失时的含义
流量可控性源协议为 HTTP;测试代理能看到并修改响应仅在隔离网中观察请求,必要时注入 302 或 503HTTPS 或不可篡改路径会提高利用门槛
安装时机APT 正在下载或安装包;自动更新定时器活跃查看定时器、apt-get --download-only 记录没有包获取窗口时,替换条件难以成立
异常重试Acquire::Retries 非零,或发行版默认启用对照组设为 0,实验组保持默认重试为 0 时,重定向/临时错误不一定触发再次下载
包完整性实际下载文件哈希与索引哈希不一致但进入安装对照 apt-cache show 的 SHA256 与 sha256sum若 APT 拒绝不一致文件,链条未闭环

测试矩阵建议至少包含四组:HTTP 源加默认重试、HTTP 源加 Acquire::Retries=0、HTTPS 源加默认重试、已更新 APT 的 HTTP 源加默认重试。每组都使用同一个无害测试包和同一套代理日志字段。HTTPS 对照组不要在生产环境做 TLS 拦截或安装测试 CA;在隔离环境验证源协议和连接行为即可。实验组若出现非测试包、业务服务变化或代理规则影响到其他主机,立即停止。

无害替换演练:用故障注入代替恶意载荷

演练只回答“条件是否成立”,不追求构造真实攻击链。测试仓库中只发布无害包 A,代理在重试时返回同包名、同版本但内容不同的无害包 B;B 的安装脚本只写一个标记文件。这样既能观察 APT 是否接受重试后的包,又不会对系统产生实际破坏。

无害替换演练证据链与回滚示意图

构建无害测试包

在隔离工作目录中构建包 A。包 B 使用相同的 Package 和 Version,只改变 postinst 写入的标记内容,并且只放在代理的替换响应位置,不发布到测试仓库索引中,避免索引冲突。

mkdir -p labpkg-a/DEBIAN
cat > labpkg-a/DEBIAN/control <<'EOF'
Package: apt-cve-lab
Version: 0.0.1-lab
Architecture: all
Maintainer: Lab <lab@example.invalid>
Description: harmless marker for authorized APT validation
EOF
cat > labpkg-a/DEBIAN/postinst <<'EOF'
#!/bin/sh
set -e
printf '%s\n' 'marker-a' > /tmp/apt-cve-lab-marker
exit 0
EOF
chmod 0755 labpkg-a/DEBIAN/postinst
dpkg-deb --build labpkg-a apt-cve-lab_0.0.1-lab_a.deb

用同样方式构建 B,把标记改为 marker-b。测试仓库只放 A,并生成对应索引;记录 apt-cache show apt-cve-lab 中的 SHA256。不要把 B 放进正式索引,也不要在测试包中放置任何服务、账户或网络修改逻辑。

执行、观察与停止

先在测试机上执行仅下载步骤,确认请求路径和索引哈希:

sudo apt-get update
apt-get download apt-cve-lab
sha256sum apt-cve-lab_0.0.1-lab_a.deb
apt-cache show apt-cve-lab | grep -E 'Version|SHA256'

清理下载文件后,在快照保护的测试机上执行安装组。对照组先设置 Acquire::Retries=0,用代理对测试包 URL 返回一次 503 或 302,观察 APT 是否重试、是否失败、是否留下部分文件。实验组保持默认重试,代理在重试时返回无害包 B,然后执行:

sudo apt-get install -y apt-cve-lab
dpkg -s apt-cve-lab | grep -E 'Status|Version'
cat /tmp/apt-cve-lab-marker
sha256sum /var/cache/apt/archives/apt-cve-lab_0.0.1-lab_*.deb
grep -iE 'retry|302|503|apt-cve-lab' /var/log/apt/term.log

输出解读要围绕证据,而不是只看安装成功与否:标记是 marker-a 还是 marker-b;缓存文件哈希是否与索引 SHA256 一致;term.log 是否出现重试、重定向或临时错误;APT 是否在哈希不一致时拒绝安装。若实际文件哈希与索引不一致但仍进入安装路径,说明完整性条件在本次测试中闭环;若 APT 拒绝或未触发重试,记录为“当前条件下未闭环”,不要通过更换代理、放宽校验或叠加更多故障来强行制造结果。

这一步的停止条件包括:出现非测试包安装、标记文件之外的系统变化、代理日志混入生产地址、APT 日志出现无法解释的 root 脚本执行、快照不可用或回滚失败。停止后先保全代理日志、APT 日志、哈希和快照 ID,再处理环境。

风险判断与版本核对

风险判断应写成条件组合,而不是一句“存在高危漏洞”。如果 HTTP 路径可控、安装窗口存在、重试非零,并且无害替换包被接受并安装,应判定为高风险闭环,立即隔离测试主机、更新 APT、迁移 HTTPS 源并排查同类主机。若替换包被拒绝或哈希不一致被拦截,说明本次测试未闭环,但传输暴露和重试配置仍需整改。若只有 HTTP 源而 APT 已修复,风险显著降低,但仓库信任、代理控制和日志监控仍不能省略。

Ubuntu 官方公告给出的修复版本包括:22.04 LTS 的 2.4.15ubuntu0.1、24.04 LTS 的 2.8.4ubuntu0.1,20.04 LTS 为 2.0.12+esm1。Ubuntu 22.04 LTS 及更新版本默认受影响,较旧版本仅在 Acquire::Retries 非零时受影响。Debian 侧公开分析称 Debian 11 及更新版本已有修复,Debian 12 及更新版本默认启用重试;具体修复版本应以 Debian 安全公告为准,本文资料未给出可逐一列出的 Debian 版本号,因此不作推测。Canonical 对该漏洞的 CVSS 4.0 评分为 7.7 High;公开分析同时指出,披露时未见在野利用报告,但这不应被理解为风险不存在。

参考来源:Ubuntu 官方公告、ThreatDefence 的补丁与排查分析。

发行版/版本默认暴露条件(据公开资料)资料明确的修复版本
Ubuntu 22.04 LTS默认受影响2.4.15ubuntu0.1
Ubuntu 24.04 LTS默认受影响2.8.4ubuntu0.1
Ubuntu 20.04 LTS仅 Acquire::Retries 非零时受影响2.0.12+esm1
Debian 12 及更新公开分析列为默认启用重试、受影响以 Debian 安全公告为准
Debian 11公开分析称已有修复以 Debian 安全公告为准

整改:传输保护、仓库信任与 APT 更新

整改顺序建议是:先降低传输暴露,再更新 APT,最后做回归验证。不要在生产高峰直接改源;先备份并确认镜像支持 HTTPS。

sudo cp -a /etc/apt/sources.list /root/sources.list.bak.$(date +%F)
sudo cp -a /etc/apt/sources.list.d /root/sources.list.d.bak.$(date +%F)
grep -RhsE '^(deb|URIs:)' /etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null

对 sources.list 中的 deb http://... 和 Deb822 文件中的 URIs: http://...,逐条确认镜像是否提供 HTTPS 后手工修改,不建议用一条全局 sed 覆盖所有源。修改后执行 sudo apt-get update,确认索引下载正常。若内部镜像暂不支持 HTTPS,应限制 APT 出站到受控镜像或代理,并安排维护窗口尽快更新。

更新 APT 本身:

sudo apt-get update
sudo apt-get install --only-upgrade apt
apt --version

Debian 环境使用对应的 apt 包升级方式,并以 Debian 安全公告中的修复版本为准。更新后检查自动更新服务是否仍在运行:

systemctl status apt-daily.timer apt-daily-upgrade.timer unattended-upgrades.service

仓库信任方面,固定镜像地址,核对 Release 签名,禁止不受控代理,检查 Acquire::http::Proxy 和 Acquire::https::Proxy 是否符合预期。监控侧至少关注:APT 日志中的重试、302/503、异常包 URL,代理日志中的重定向和响应长度突变,以及实际包哈希与索引哈希不一致。/var/log/apt/history.log 和 /var/log/apt/term.log 应纳入日志留存;自动更新任务也应覆盖。

回归验证要重复测试矩阵,而不是只跑一次安装。确认修复版 APT 在 HTTP 默认重试场景下不再接受无害替换包,确认 HTTPS 源可正常更新,确认业务依赖包安装不受影响。若回归中仍出现替换包被安装,停止上线,按事件响应处理。

回滚、证据归档与报告字段

回滚优先使用快照。若测试包已安装,先在隔离环境执行卸载和标记清理,再恢复源列表备份、删除代理故障注入规则、关闭测试仓库,最后验证 apt-get update 和关键服务:

sudo apt-get remove --purge -y apt-cve-lab
sudo rm -f /tmp/apt-cve-lab-marker
sudo apt-get update

如果替换包可能修改了系统文件,不要只依赖卸载;直接恢复到测试前快照,并保留快照 ID、代理日志、APT 日志和包哈希作为证据。报告至少应包含以下字段,便于复核和复测:

字段内容
测试编号与授权编号与授权文档一一对应
资产与版本主机、发行版、APT 版本、源协议
测试矩阵对照组、实验组、重试配置、代理行为
证据请求 URL、状态码、重定向、索引 SHA256、实际文件 SHA256、标记内容
结论四条件是否闭环,风险等级与判断依据
整改APT 更新版本、HTTPS 迁移、仓库与代理控制
回滚快照 ID、卸载/恢复步骤、验证结果
复测复测时间、结果、复核人

这类授权渗透测试的价值不在于证明“能替换一次”,而在于把流量可控性、安装时机、重试配置和包完整性拆成可观察、可复核的条件,留下能支撑修复决策的证据。测试环境中的无害替换演练只是确认链条,最终产出应是传输保护、仓库信任、APT 更新和回归验证的闭环。

 
枫少@KillBoy
评论  5  访客  5
    • 彼得潘
      彼得潘 1

      先做快照再动代理,这顺序稳

      • 徐磊
        徐磊 1

        只跑只读基线检查也能省不少事

        • 往日旧事
          往日旧事 2

          默认重试这个坑真容易被忽略

          • 巴塞罗那塔
            巴塞罗那塔 0

            生产高峰改源确实别硬来

            • 寒江渔翁
              寒江渔翁 0

              有没有适合内网镜像的排查清单

            匿名

            发表评论

            匿名网友

            拖动滑块以完成验证