一个存在了大约37年的整数溢出,加上一个独立的内核缺陷,串起来就能在OpenBSD 7.9上拿到root。发现并报告这两个漏洞的安全公司Calif,在OpenBSD九月发布补丁后,公开了详细分析和完整的PoC代码。
![]()
这条攻击链绕过了三样东西:OpenBSD的KARL内核地址随机化,以及SMAP和SMEP两项硬件保护。更值得琢磨的是,作为整条链入口的那个整数溢出,当初是被当作可靠性修复发布的,不是安全修复。
两个补丁,两种定性
shmat(4) attach函数里的整数溢出,在errata 018中修复,9月14日发布,定性为可靠性修复。补全整条链的引用计数use-after-free,则在errata 026中单独修复,9月30日发布,定性为安全修复。
两个补丁都能通过syspatch获取,覆盖所有架构。OpenBSD 7.8也拿到了那个整数溢出的修复。截至发稿,两个漏洞都没有分配CVE编号,也没有证据显示它们被用于实际攻击。
一个16位short撑了37年
共享内存的挂接计数器shm_nattch,在1988年的原始BSD源码里被定义为一个有符号16位short,最大值32,767。OpenBSD继承了这个类型,从来没有把它加宽。
攻击方式很直接:映射127个共享内存段,fork出259个进程,把计数器推过上限,回绕成−32,643。随后一个竞态条件触发use-after-free——被破坏的引用计数让内核释放了其他进程仍在使用的内存。
另一处独立的越界写覆盖了内核中的多播成员计数。受影响的socket关闭时,随之而来的递减操作会修改页表项,把一段用户内存映射切换成超级用户可访问,从而绕过SMAP和SMEP。之后,攻击者覆盖一个可预测内核地址上的函数指针,执行自己的代码。
KARL随机了内核,没随机分配器
研究员Andrew Griffiths写道:“OpenBSD的KARL会重新链接内核二进制,随机化函数地址和数据地址,但内核的内存分配器仍然是确定性的。”
启动时分配器和最佳适配分配器都缺少基址随机化,所以早期启动阶段的结构——包括lo0和enc0网络接口处理函数里的函数指针——在同一台硬件上每次重启都落在相同地址。整条攻击链不需要任何信息泄露漏洞。
除了这两个errata,Calif提出了四类加固方向:
- 内核链表的safe-unlinking(FreeBSD和NetBSD已在用)
- 页表自引用映射的随机化
- 内核分配器随机化
- 基于编译器的边界检查
Calif表示,他们在“今年早些时候”向OpenBSD报告了这些缺陷。PoC利用代码已在GitHub上公开。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.