跳转到帖子

Sudoedit 参数注入提权漏洞 CVE-2023-22809 验证与修复

精选回复

发布于

漏洞概述

CVE-2023-22809 是 sudoedit 的参数注入漏洞,影响 sudo 1.8.0 至 1.9.12p1,官方在 1.9.12p2 中修复。攻击者必须已经获得某个文件的 sudoedit 授权,才能进一步绕过 sudoers 中限定的文件边界,编辑其他由 root 管理的文件。

  • 漏洞类型:本地权限提升、参数注入、权限边界绕过
  • 影响范围:sudo 1.8.0 至 1.9.12p1,发行版回补版本需以厂商公告为准
  • 前置条件:攻击者拥有低权限系统账号,且 sudoers 允许其执行至少一条 sudoedit 规则
  • 典型链路:普通账号落地 → 发现 sudoedit 权限 → 绕过文件白名单 → 修改 root 管理文件 → 提升权限
以下验证仅适用于已授权测试环境。验证目标应使用专门创建的 canary 文件,不应直接修改 sudoers、口令文件、systemd 单元或动态链接器配置。

问题定位

首先确认当前账号是否拥有 sudoedit 权限。该漏洞不等于“安装了受影响版本即可提权”,没有 sudoedit 授权时通常不具备利用条件。

sudo -l
sudo --version | head -n 1
command -v sudo
ls -l "$(command -v sudo)"

重点检查 sudo -l 输出中是否存在类似规则:

(root) NOPASSWD: sudoedit /etc/app/config.ini

同时检查规则来源,避免只查看主配置文件而遗漏 /etc/sudoers.d 下的拆分配置:

sudo visudo -c
sudo grep -RInE 'sudoedit|/usr/bin/sudoedit' /etc/sudoers /etc/sudoers.d 2>/dev/null

不要仅根据上游版本字符串判断是否存在漏洞。Debian、Ubuntu、RHEL 等发行版可能将补丁回移到旧版本包中,应同时检查软件包版本和发行版安全变更记录。

# Debian、Ubuntu
dpkg-query -W sudo
apt-cache policy sudo
zgrep -i 'CVE-2023-22809' /usr/share/doc/sudo/changelog* 2>/dev/null

# RHEL、Rocky Linux、AlmaLinux、Fedora
rpm -q sudo
rpm -q --changelog sudo | grep -i -m1 'CVE-2023-22809'

技术分析

sudoedit 的设计目标是让普通用户使用自己的编辑器修改被 sudoers 精确授权的文件。sudo 负责复制目标文件到临时位置,编辑器仍以调用用户身份运行,退出后再由特权流程完成安全检查和回写。

漏洞版本允许通过 SUDO_EDITOR、VISUAL 或 EDITOR 指定带参数的编辑器。当变量中出现参数分隔符“--”时,sudo 前端与 sudoers 策略插件对后续参数的理解不一致:策略插件只校验命令行中原本授权的文件,而编辑阶段可能把变量中附加的路径一并作为待编辑文件处理。结果是原本只允许修改 /etc/app/config.ini 的账号,可能越过文件级授权边界。

该问题的关键不在编辑器本身,而在特权程序与策略插件对参数边界解析不一致。即使 sudoers 使用了精确路径匹配,只要运行版本仍受影响,文件白名单也可能失效。

安全验证步骤

建议先在隔离测试机复现,并由管理员准备一个 root 所有、普通用户不可写的 canary 文件。以下示例中的 tester 仅被允许编辑 /etc/app/config.ini。

管理员准备测试对象:

sudo install -d -o root -g root -m 0755 /etc/app
printf '%s\n' 'mode=production' | sudo tee /etc/app/config.ini >/dev/null
sudo chown root:root /etc/app/config.ini
sudo chmod 0644 /etc/app/config.ini

printf '%s\n' 'baseline' | sudo tee /var/tmp/sudoedit-proof >/dev/null
sudo chown root:root /var/tmp/sudoedit-proof
sudo chmod 0600 /var/tmp/sudoedit-proof

printf '%s\n' 'tester ALL=(root) NOPASSWD: sudoedit /etc/app/config.ini' | sudo tee /etc/sudoers.d/sudoedit-lab >/dev/null
sudo chmod 0440 /etc/sudoers.d/sudoedit-lab
sudo visudo -cf /etc/sudoers.d/sudoedit-lab

切换到 tester 后,先确认其无法直接读取或写入 canary 文件,再进行受控验证:

id
cat /var/tmp/sudoedit-proof
printf '%s\n' test >> /var/tmp/sudoedit-proof

SUDO_EDITOR='vi -- /var/tmp/sudoedit-proof' sudoedit /etc/app/config.ini

进入编辑器后只修改 sudoedit-proof 的临时副本,例如将 baseline 改为 validated,不要修改其他文件。退出后由管理员检查:

sudo stat /var/tmp/sudoedit-proof
sudo cat /var/tmp/sudoedit-proof
sudo stat /etc/app/config.ini

如果未获授权的 /var/tmp/sudoedit-proof 被成功回写,说明 sudoedit 的文件授权边界已被绕过。已修复版本应拒绝或安全处理包含参数分隔符的编辑器设置,不应把额外路径纳入编辑列表。

验证结束后应立即删除实验规则和 canary 文件:

sudo rm -f /etc/sudoers.d/sudoedit-lab /var/tmp/sudoedit-proof
sudo visudo -c

日志留痕与事件排查

常规 sudo 日志通常能够记录 sudoedit 调用及原始授权目标,但未必完整记录 SUDO_EDITOR 的值。因此,仅搜索命令行中的敏感路径可能漏报,应结合 sudoedit 调用、文件变更时间和 auditd 记录进行判断。

# Debian、Ubuntu
grep -E 'sudo(edit)?|COMMAND=.*sudoedit' /var/log/auth.log* 2>/dev/null

# 使用 journald 的系统
journalctl --since '7 days ago' | grep -E 'sudo(edit)?|COMMAND=.*sudoedit'

# 检查高风险文件近期变化
sudo find /etc -xdev -type f -mtime -7 \
  \( -path '/etc/sudoers*' -o -path '/etc/passwd' -o -path '/etc/shadow' \
     -o -path '/etc/ld.so.preload' -o -path '/etc/systemd/system/*' \) \
  -printf '%TY-%Tm-%Td %TH:%TM:%TS %u:%g %m %p\n' 2>/dev/null

在重要服务器上,可提前使用 auditd 监控容易形成持久化或权限提升的配置文件。以下规则应结合业务环境控制数量,避免产生过多日志:

sudo auditctl -w /etc/sudoers -p wa -k sudo_policy_change
sudo auditctl -w /etc/sudoers.d -p wa -k sudo_policy_change
sudo auditctl -w /etc/ld.so.preload -p wa -k loader_change
sudo auditctl -w /etc/systemd/system -p wa -k systemd_persistence

sudo ausearch -k sudo_policy_change -i
sudo ausearch -k loader_change -i
sudo ausearch -k systemd_persistence -i

若怀疑漏洞已被利用,还应检查目标时间窗口内新增的 sudoers 规则、SUID 文件、root SSH 密钥、计划任务和 systemd 服务,并将文件时间线与 sudo 登录记录关联。文件修改时间只能作为线索,不能单独作为未入侵结论。

风险判断

  • 高风险:版本受影响,普通账号拥有 root 身份下的 sudoedit 权限,且目标主机承载重要业务。
  • 中风险:版本受影响且存在 sudoedit 规则,但仅限隔离测试账号或受控运维入口。
  • 低风险:发行版已回补 CVE-2023-22809,或系统不存在任何 sudoedit 授权。

如果 sudoedit 规则允许多组运维人员使用,风险不能只按当前在线账号判断。历史离职账号、共享账号、跳板机泄露凭据以及应用服务账号被接管,都可能把该漏洞接入实际内网攻击链。

修复与加固建议

  • 优先升级到 sudo 1.9.12p2 或发行版明确标记已修复 CVE-2023-22809 的安全包,不建议只依赖环境变量过滤作为长期措施。
  • 执行 visudo -c 校验配置,并重新审计所有 sudoedit 规则,确认每条规则是否仍有业务必要。
  • 避免将目录、通配符或可由低权限用户控制的路径交给 sudoedit;同时检查目标文件的父目录是否可写、是否存在软链接替换条件。
  • 无法立即升级时,可临时撤销非必要 sudoedit 权限,改由受控发布流程或固定功能的特权辅助程序完成配置更新。
  • 对 sudo 使用启用集中日志,并为 sudoers、systemd、计划任务和动态链接器配置建立文件完整性监控。
  • 完成修复后重新执行 canary 验证,确认附加路径无法被回写,而不是只确认软件包安装命令执行成功。
# 升级示例,实际以发行版仓库为准
sudo apt update && sudo apt install --only-upgrade sudo
# 或
sudo dnf upgrade sudo

sudo --version | head -n 1
sudo visudo -c

总结

CVE-2023-22809 的实际危害来自 sudoedit 文件级授权边界失效。排查时应同时满足三个维度:确认是否存在 sudoedit 授权、确认安装包是否包含修复补丁、确认关键文件是否出现异常回写。修复完成后,还应保留验证记录和文件时间线,避免把“已升级”误当作“未发生过利用”。

服务器与云环境安全示意图
服务器、云资产与权限边界梳理示意
漏洞验证与修复流程示意图
漏洞成因、验证条件与修复闭环示意

验证时有两个容易误判的点:发行版通常会回移补丁,不能只按版本号判断;另外该漏洞需要用户本身拥有某个 sudoedit 授权,并非任意本地用户都能直接利用。

先确认实际版本和授权范围:

sudo -V | head -n 1
sudo -l
sudo -l -U testuser

# Debian/Ubuntu 查看安全更新记录
apt changelog sudo 2>/dev/null | grep -i -A3 CVE-2023-22809

# RHEL/CentOS/Rocky/Alma
rpm -q --changelog sudo | grep -i -A3 CVE-2023-22809

上游受影响范围是 sudo 1.8.0 至 1.9.12p1,1.9.12p2 已修复,但最终应以发行版安全公告和包 changelog 为准。

如果需要做动态验证,建议只在隔离靶机中使用无业务影响的 canary 文件。例如管理员先创建测试文件,并通过 visudo 仅授权一个普通文件:

printf 'allowed\n' | sudo tee /var/tmp/allowed.txt
printf 'root-only\n' | sudo tee /var/tmp/root-only.txt
sudo chmod 600 /var/tmp/root-only.txt

sudo visudo -f /etc/sudoers.d/cve-2023-22809-test
testuser ALL=(root) sudoedit /var/tmp/allowed.txt

切换到 testuser 后测试参数注入:

SUDO_EDITOR='vim -- /var/tmp/root-only.txt' sudoedit /var/tmp/allowed.txt

存在漏洞时,未授权的 root-only.txt 可能被带入编辑器;修复后的版本会拒绝或忽略带有 -- 的编辑器参数。测试完成后删除 sudoers 测试文件,并执行:

sudo rm -f /etc/sudoers.d/cve-2023-22809-test \
  /var/tmp/allowed.txt /var/tmp/root-only.txt
sudo visudo -c

正式修复应优先升级发行版提供的 sudo 安全包。暂时无法升级时,可删除 sudoedit 场景中的编辑器环境变量作为缓解:

Defaults!sudoedit env_delete+="SUDO_EDITOR VISUAL EDITOR"

修改后用 visudo -c 检查语法,并重新登录后验证环境变量是否仍被接受。同时建议检查 sudoers 中是否存在过宽规则,例如 sudoedit ALL、目录通配符或同时带有 SETENV 的授权。日志中可检索历史调用,但常规 sudo 日志未必记录完整编辑器环境变量,因此只能作为线索,不能据此排除利用:

journalctl _COMM=sudo | grep -i sudoedit
grep -i sudoedit /var/log/auth.log /var/log/secure 2>/dev/null

创建帐户或登录后发表意见

最近浏览 0

  • 没有会员查看此页面。