sudo 限时授权绕过漏洞 CVE-2026-96512:少写一个 Z,过期规则照样能提权

作者:程序员白大力 · 2026-09-29 01:03

封面

引言

9 月 23 日,Red Hat 公开披露了 sudo 的一个新漏洞(CVE-2026-96512,CVSS 7.8):凡是用了限时提权规则的 Linux 服务器,只要时间戳末尾少写一个字母 Z,"过期作废"就可能变成"过期照用"。第二天 Red Hat 就发了补丁,但问题在于——这个功能不在默认配置里,绝大多数运维压根不知道自己有没有在用。

很多开发者的直觉是:sudo 要输密码、规则写死了允许的命令、还设了生效时间窗,三重保险万无一失。这个漏洞恰好戳破了第一层和第三层的关系:密码验证挡住的是"没资格的人",挡不住"有资格的人在错误的时间进来"。

一、事件复盘

先说清楚这件事的来龙去脉:

  • 8 月 28 日:独立安全研究员 Ermenson Junior 向 Red Hat 报告了这个问题;
  • 9 月 23 日:漏洞公开发布,编号 CVE-2026-96512,红帽官网和安全邮件列表(oss-security)同步披露,影响 RHEL 7 到 10 全系;
  • 9 月 24 日:Red Hat 发布修复公告 RHSA-2026:71609,sudo 上游也合入了修复代码。

漏洞的适用范围需要说准确:只影响在 sudoers 规则里使用了 NOTBEFORE 或 NOTAFTER 限时指令、且时间戳没有以 Z 结尾的配置。比如"该用户只允许在工作日 9 点到 18 点执行重启命令"这类规则。如果没用过限时功能,那这条漏洞与你无关。

到目前为止,官方评估为未被发现在野利用,且无法自动化利用——攻击者必须是这台机器上的本地低权限用户,还得恰好命中一条限时规则。听起来威胁不大?别急,往下看第三部分的误区分析。

二、技术核心拆解

这个漏洞的原理,用大白话讲就是一个"时区戏法"。

限时规则是怎么生效的? sudoers 里的 NOTBEFORE 和 NOTAFTER 相当于给提权命令加了一道时间闸门:现在几点、在不在允许的时间段内,在才放行。很多企业用它做"临时授权"——比如维护窗口才允许 sudo 重启服务,或者给外包人员的权限设定自动过期时间,到期不用人工回收。

问题出在哪? sudo 判断"现在几点"的时候,会参考调用者环境里的 TZ 环境变量(也就是时区设置)。而 sudo 是个 setuid-root 程序——意思是它以 root 身份运行,但环境变量却部分继承自普通用户。于是任何一个本地普通用户,都可以把自己的时区设成一个极端偏移值(比如 UTC+25 小时这种离谱设置),让 sudo 的时间判断整体平移,最多能挪动约 25 个小时。一条下午 6 点过期的规则,在攻击者的"时区"里还是下午 3 点——闸门就这么被绕开了。

为什么说这是个老毛病? 有意思的是,sudo 启动时本来就会清掉 TZ 环境变量再重新计算时区,算是做了部分防御。但上游确认这个防线在某些平台上不够用,所以这次干脆在时间计算前彻底移除 TZ 变量,从根上解决。这也是很多老牌基础软件的通病:20 年前的代码假定环境可控,如今环境早就不可控了。

时间戳末尾的 Z 是什么? 就是 ISO 8601 标准里的祖鲁时间(Zulu time),即 UTC。写成 20261231235959Z 的含义是"UTC 时间 2026 年 12 月 31 日 23 点 59 分 59 秒",这种写法会走另一条计算路径(timegm 函数),完全不看 TZ 环境变量,所以不受影响。

三层风险怎么看?

  • 功能层面:限时授权这一控制手段实质失效,权限回收机制形同虚设;
  • 安全层面:本地低权限用户可以在授权窗口之外执行本不该执行的特权命令,前提是存在未加 Z 的限时规则;
  • 合规层面:如果你的等保或内控体系依赖"权限时限"作为访问控制证据(比如审计要求外包权限必须自动过期),这个漏洞意味着该控制在技术上可被绕过,需要评估并留存补丁记录。

三、常见技术误区

误区一:设了过期时间,权限就自动安全了。 这是最普遍的错觉。时间限制是"便捷的控制",不是"强安全边界"。真正的权限回收要靠配置管理:临时授权到期后,由自动化流程真正删除或禁用规则,而不是单纯指望规则自己"过期作废"。这次的漏洞恰好证明:只要过期判断能被操纵,所谓自动过期就是纸糊的。

误区二:sudo 要输密码,所以不可能是漏洞入口。 密码验证解决的是"你是谁",时间限制解决的是"你什么时候可以"。两者是独立的闸门,绕过后者不需要碰前者。这个漏洞里攻击者的密码、身份、被授权的命令全都是真的,只是时间判断被骗了。类似的思路在很多系统里都成立:认证通过不等于授权合理。

误区三:这是服务器才要操心的事,跟我这个开发者无关。 恰恰相反。限时 sudo 规则最常见的使用场景就是开发环境和 CI/CD 构建机——"构建用户只允许在部署窗口执行部署脚本"这种规则不少团队都写过。你的笔记本、跳板机、测试服务器,只要 sudoers 里出现过 NOTBEFORE 或 NOTAFTER,就值得花一分钟排查。

四、实操指引

三步处理,按顺序来:

第一步:自查有没有踩坑。 在服务器上执行:

grep -rE 'NOT(BEFORE|AFTER)=' /etc/sudoers /etc/sudoers.d/

没有输出,说明没用限时功能,直接忽略这个漏洞;有输出,逐条检查时间戳末尾是否带 Z。

第二步:紧急缓解(不等补丁)。 给所有 NOTBEFORE 和 NOTAFTER 时间戳末尾补上 Z。例如把 NOTAFTER=20261231235959 改成 NOTAFTER=20261231235959Z。带 Z 的时间戳按 UTC 解释,不走 TZ 环境变量那条路,漏洞即被规避。注意补 Z 会改变时区语义——原来按本地时间写的规则,现在按 UTC 解释,时间点需要重新核对,东八区用户要留意 8 小时的偏移。

第三步:升级修复。 RHEL 各版本通过 RHSA-2026:71609 公告升级 sudo 到修复版本;其他发行版留意各自的安全公告跟进上游修复(上游提交已在 sudo 仓库合入)。用发行版包管理器正常更新即可,无需手动编译。

另外给使用云主机的团队提个醒:如果限时时长规则写在镜像或配置管理工具(Ansible、SaltStack 之类)的模板里,模板也要同步改,否则新开出来的机器还是老配置。

五、结尾

这个漏洞的技术含量不算顶级——CVSS 7.8,本地利用,无在野利用报告——但它暴露的思维问题很值钱:控制手段的有效性,取决于它依赖的每一个输入是否可信。时间判断依赖了不该依赖的 TZ 变量,一道设计精巧的闸门就被人用"换个时区"这种近乎行为艺术的方式绕开了。

对写代码的人来说,这也是个提醒:凡是"根据某个环境变量决定行为"的逻辑,都值得多问一句——这个变量,用户能不能自己设?

觉得有用的话,转给你身边管服务器的朋友,让他跑一下那条 grep 命令,一分钟的事。

本文由 AI 辅助生成并经人工审核发布,内容仅供参考。