CVE-2026-46333 漏洞分析报告
原创
simeon的文章
simeon的文章
小兵搞安全
2026年6月11日 13:33
北京
在小说阅读器读本章
去阅读
一、漏洞概述
漏洞名称/代号
ssh-keysign-pwn
漏洞类型
Linux内核权限提升(Improper Privilege Management, CWE-269)
CVSS评分
- 基础评分:5.5 (Medium) - 按照本地访问、低复杂度、用户交互的常规评估
- 部分安全厂商评分:9.8 (Critical) - 考虑到实际利用成功率接近100%且影响范围广
发现者/披露方
Qualys威胁研究团队(Qualys Threat Research Unit)
披露时间
2026年5月14日
影响范围
- Linux内核版本:4.14 ~ 6.19.11
- 受影响主流发行版:Debian、Ubuntu、Fedora、RHEL、CentOS、AlmaLinux等
- 潜伏时长:约6-9年(2016年或2020年引入,取决于具体内核分支)
风险等级
高危。普通用户可稳定利用该漏洞读取root拥有的任意敏感文件,包括系统密码哈希、SSH主机密钥等,直接威胁系统安全。
二、技术原理深度分析
漏洞产生的根本原因
漏洞位于内核__ptrace_may_access()函数中,属于检查时间-使用时间(TOCTOU) 竞态漏洞的一种变体。根本原因是:当目标进程的task->mm指针为NULL时,内核会跳过dumpable安全检查,而攻击者可以利用进程退出时的时序窗口制造这一条件。
受影响的代码模块/函数
核心函数:__ptrace_may_access()(定义于kernel/ptrace.c)
关键代码路径:
do_exit()
-
进程退出处理函数
2.exit_mm() -
释放进程内存描述符(mm)
3.put_files_struct() -
关闭进程文件描述符
4.pidfd_getfd() -
通过pidfd获取目标进程的文件描述符
漏洞关键逻辑:在__ptrace_may_access()函数中,当task->mm == NULL时,函数直接返回0(允许访问),跳过了对ptrace_mode和dumpable的安全检查。这一设计原本用于处理内核线程(内核线程没有mm),但被攻击者利用于用户态进程退出的中间状态。
漏洞触发条件
- 系统中存在setuid或setgid程序(如
ssh-keysign、chage等) - 攻击者拥有本地普通用户权限
- 内核支持
pidfd_getfd()系统调用(Linux 5.6及以上版本) - ptrace\_scope未设置为2(限制性模式)
完整的攻击流程/利用链
攻击利用链(以ssh-keysign为例) :
步骤1:攻击者以普通用户身份启动setuid程序(ssh-keysign)
步骤2:ssh-keysign以root权限运行,打开/etc/shadow等敏感文件
步骤3:攻击者监控目标进程状态,等待其进入退出流程
步骤4:do\_exit()先调用exit\_mm()将task->mm置为NULL
步骤5:在文件描述符被关闭前的极短窗口内,攻击者调用pidfd\_getfd()
步骤6:由于mm=NULL,\_\_ptrace\_may\_access()跳过安全检查,允许窃取fd
步骤7:攻击者通过窃取的文件描述符读取敏感文件内容
技术细节
1. 进程退出的执行顺序
Linux内核中do_exit()函数的关键执行顺序:
do\_exit()
├── exit\_mm()// 释放mm结构,task->mm = NULL
├── exit\_files()// 释放文件描述符表
├── exit\_fs()
└── ...
关键在于:exit_mm() 在 exit_files() 之前执行。这意味着在mm被释放后、文件描述符被关闭前,存在一个短暂的时间窗口,此时进程的task->mm == NULL,但文件描述符仍然有效。
2. pidfd\_getfd 的权限检查
pidfd_getfd()系统调用在执行时会调用__ptrace_may_access()进行权限检查。当目标进程mm == NULL时,检查被绕过,攻击者即可获取目标进程的任意文件描述符。
3. 竞态窗口的利用
由于竞态窗口非常短暂(微秒级),攻击者需要:
- 使用
pidfd_open()获取进程文件描述符 - 通过
poll()或waitid()监听进程退出事件 - 在检测到进程即将退出时,快速循环调用
pidfd_getfd() - 利用Linux调度的不确定性增加命中窗口的概率
实际测试表明,通过反复执行,攻击成功率接近100% 。
4. 攻击目标的选择
攻击者需要选择在退出前会打开敏感文件的setuid程序。典型目标包括:
- ssh-keysign
:SSH的主机认证辅助程序,会读取SSH主机私钥
* chage
:修改用户密码过期信息,会读取/etc/shadow
* passwd
:修改用户密码,会读取/写入/etc/shadow
* su
:切换用户,会读取/etc/passwd和/etc/shadow
三、影响范围与风险评估
受影响的软件版本
| 发行版 | 受影响版本 | 修复版本 |
|---|---|---|
| Linux主线内核 | 4.14 ~ 6.19.11 | 6.19.12+ |
| Debian | bookworm (12)、trixie (13) | 待发布安全更新 |
| Ubuntu | 22.04 LTS、24.04 LTS、24.10 | 各版本已发布内核更新 |
| Fedora | 39、40、41 | 已推送更新 |
| RHEL | 8.x、9.x | 已发布RHSA |
| AlmaLinux | 8.x、9.x | 已推送内核更新 |
受影响的平台/系统
- 所有运行受影响版本Linux内核的x86\_64、ARM64等架构系统
- 物理服务器、虚拟机、容器环境均受影响
攻击面分析
攻击向量:本地攻击
- 需要本地用户权限(普通用户即可)
- 无法远程直接利用,但可配合远程代码执行漏洞进行提权
攻击面广度:
- 几乎所有Linux发行版都受影响
- 只要系统中存在setuid程序即可被利用
- 容器环境中若允许
pidfd_getfd()系统调用也会受影响
实际危害程度
高危害。攻击者可获取:
- /etc/shadow
-
所有用户的密码哈希,可用于离线爆破
2. SSH主机私钥 -
可冒充该服务器进行中间人攻击
3. 其他敏感文件 -
如Kerberos keytab、应用配置中的密码等
4. 特权进程打开的任意文件 -
扩展攻击面
虽然是本地提权漏洞,但在多用户系统、共享主机环境、容器逃逸场景下危害极大。
在野利用状态
- 未确认
。截至2026年6月,尚无公开的在野利用报告
* 但由于POC已公开且利用难度低,不排除已被攻击者掌握
四、POC/EXP分析
公开状态
✅ 已公开完整POC
利用难度评级
低。普通用户权限即可利用,攻击脚本可稳定复现,成功率接近100%。
POC/EXP来源与可信度
- 发布者
:安全研究员 \_SiCk(GitHub账号:0xdeadbeefnetwork)
* 发布时间
:2026年5月14日(漏洞披露后数小时内)
* 项目地址
:https://github.com/0xdeadbeefnetwork/ssh-keysign-pwn
* 可信度
:高。已被多个安全厂商和社区验证有效
利用代码关键片段分析
POC包含两种主要利用路径:
路径1:窃取SSH主机私钥
利用ssh-keysign程序读取SSH主机密钥
ssh-keysign是setuid root程序,用于主机认证
程序会打开/etc/ssh/ssh\host\\*\_key文件
在程序退出瞬间窃取文件描述符
路径2:读取/etc/shadow密码哈希
利用chage或passwd等setuid程序
这些程序需要读取/etc/shadow进行密码验证
同样在退出窗口窃取文件描述符
核心利用逻辑(伪代码) :
// 1. 创建子进程执行setuid程序
pid = fork();
if(pid==0){
execve(\"/usr/libexec/openssh/ssh-keysign\",argv,envp);
}
// 2. 获取pidfd
intpidfd = pidfd\_open(pid,0);
// 3. 等待进程进入退出状态
// 使用poll/epoll监听pidfd的POLLERR事件
// 4. 在竞态窗口内反复尝试窃取文件描述符
for(inti = 0; i<1000; i++){
intfd = pidfd\_getfd(pidfd,target\_fd,0);
if(fd>=0){
// 成功窃取,读取文件内容
charbuf[4096];
read(fd,buf,sizeof(buf));
break;
}
}
利用成功的前提条件
- 攻击者拥有本地普通用户账户
- 目标系统存在可被利用的setuid程序(大多数Linux系统默认存在)
- 内核版本支持
pidfd_getfd()系统调用(5.6+) /proc/sys/kernel/yama/ptrace_scope
不为2
检测与绕过方法
检测方法:
- 监控
pidfd_getfd()系统调用的异常使用 - 检查setuid程序异常退出模式
- 监控敏感文件的异常访问模式
绕过方法:
- 攻击者可选择不同的setuid程序作为攻击目标
- 可通过调整重试次数和时机绕过简单的频率检测
五、修复与防护方案
官方修复补丁/版本
主线内核修复:
- 修复提交:Linus Torvalds 提交的 commit
31e62c2ebbfd - 提交信息:\"ptrace: Don't allow accessing an undumpable mm via the NULL mm check\"
- 链接:https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=31e62c2ebbfdc3fe3dbdf5e02c92a9dc67087a3a
各发行版修复状态:
- Ubuntu:已发布USN安全公告,各版本内核均已更新
- Fedora:已推送更新
- AlmaLinux:2026年5月15日发布安全公告
- Debian:已发布DSA安全公告
修复原理简述
修复的核心是修改__ptrace_may_access()函数中的mm == NULL检查逻辑。修复后,内核不会仅仅因为mm为NULL就跳过所有权限检查,而是会:
- 对于确实没有mm的内核线程,保持原有逻辑
- 对于曾经有mm但已被释放的用户进程,使用进程凭证(credentials)进行权限检查
- 确保dumpable标志被正确评估,即使mm已被释放
临时缓解措施
在无法立即升级内核的情况下,可采取以下缓解措施:
- 设置ptrace\_scope为限制性模式
echo2 > /proc/sys/kernel/yama/ptrace\_scope
# 或在/etc/sysctl.conf中添加:
kernel.yama.ptrace\_scope =2
说明:ptrace\_scope=2表示只允许由父进程启动的跟踪,显著缩小攻击面
2. 审查和移除不必要的setuid程序
# 查找系统中的setuid程序
find / -perm-4000-type f 2>/dev/null
# 移除不必要的setuid位或程序
3. 容器环境防护
- 使用seccomp过滤
pidfd_getfd()系统调用 - 确保容器以非root用户运行
- 限制容器的capabilities
- 凭证轮换
- 假设SSH主机密钥可能已泄露,考虑轮换密钥
- 提醒用户修改密码,防范密码哈希泄露风险
检测方法
日志检测:
- 监控auditd日志中
pidfd_getfd系统调用的使用 - 关注setuid程序的异常频繁调用
- 关键字:
pidfd_getfd、ptrace、异常的文件描述符复制
流量/行为检测:
- 检测普通用户进程对敏感文件的异常读取
- 监控ssh-keysign等程序的异常调用模式
防护建议
- 立即升级内核
:这是最根本的解决方案
2. 启用Yama ptrace限制
:将ptrace\_scope设置为2
3. 最小化setuid程序
:移除不必要的setuid程序
4. 加强监控
:部署文件完整性监控和异常行为检测
5. 凭证管理
:定期轮换SSH主机密钥和用户密码
6. 容器加固
:在容器环境中使用seccomp和用户命名空间隔离
六、参考来源
- Qualys官方披露 - 漏洞发现方的官方公告
- Linux内核git提交 - 官方修复补丁
- AlmaLinux安全公告 - 发行版安全公告
- SecureBulletin分析 - 技术分析文章
- GitHub - ssh-keysign-pwn POC - 公开POC仓库
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论