首页
社区
课程
招聘
[分享]2019-SUCTF-SUDriver [seq_operations]
发表于: 3天前 1086

[分享]2019-SUCTF-SUDriver [seq_operations]

3天前
1086

这篇文章是我复现 2019 年 SUCTF 内核题 SUDriver 时的一篇学习笔记。作为内核安全的初学者,在死磕这道题的过程中,我花了不少时间尝试自己动手把 Exploit 给搓出来。在这个过程中踩了不少坑,也学到了很多,特此记录下来。

文章主要记录了以下几个学习点:

本人目前是一名大三学生,正在二进制漏洞和 Linux 内核方向艰难摸索。深知自己距离行业的标准还有很长的路要走,很多底层机制理解得也还不够透彻。将笔记发出来主要是想向各位前辈请教,同时本人也正在寻找全国范围内的实习机会,渴望能有一个真实的实战环境让我继续学习。文章中难免存在错漏,恳请各位师傅轻喷并指正!
Github链接:af1K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6^5L8Y4q4B7L8Y4x3`.
个人博客:10aK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6^5L8Y4q4B7L8Y4y4Q4x3X3g2Y4K9i4c8Z5N6h3u0Q4x3X3g2A6L8#2)9J5c8R3`.`.

启动脚本中开启了 smepkaslr,内核版本为 4.20.12

0x73311337 是创建一个堆块,大小自定义,最大 0xFFE0x13377331 是释放堆块,在利用中没什么用

明显的一个格式化字符串漏洞,可以用于泄露内核基地址

这个函数是IDA识别错误,底层还是write函数,参数分别为文件操作符,写入数据,写入长度,长度我们可以自定义,所以这是一个越界写

有任意地址写,而且内核版本 4.20.12 的环境下 ,可以大概是只能利用越界写修改结构体指针的方式控制内核执行流,我原本打算利用 tty_struct 结构体的,但是这个环境没有挂载 devpts 伪文件系统,所以用了 seq_operations 结构体来做平替

小提示 : 这道题没有开启在 4.14 引入的 Hardened freelist 所以,劫持 modprobe_path 也是一个不错的选择

踩坑 : 我还尝试了 timerfd_ctx 结构体,但是越界写破坏了红黑树节点,虽然程序没有开启 smap,我们可以在用户态伪造红黑树节点,但是因为该版本的timerfd_ctx 结构体偏移问题,没有合适的 gadget 可用,最后放弃了

真的是很奇怪,不知道为什么用户堆块就是进不去梳子型的堆喷....

我采用了 [堆喷,创建堆块,堆喷] 的方式完成堆布局

我们往创建出来的的堆块写入一些数据,一会动态检查是否构造完成了

nokaslr 环境下利用格式化字符串泄露栈上的函数地址,然后计算偏移后,就可以用在 kaslr 环境下了

当我们 read 一个 stat 文件时,内核会调用其 proc_opsproc_read_iter 指针,其默认值为 seq_read_iter() 函数,定义于 fs/seq_file.c 中,注意到有如下逻辑

即其会调用 seq_operations 中的 start 函数指针,那么我们只需要控制 seq_operations->start 后再读取对应 stat 文件便能控制内核执行流

同时在我们执行内核调用时,会在栈底形成一个 pt_regs 结构体,结构如下

假设我们能计算出我们在 read 一个 stat 文件时的栈指针和 pt_regs 结构体的距离,我们就能通过往 start 指针写入一个类似add rsp 0xxxx; ret;gadget 完成控制内核执行流

注意程序开启了 KPTI,我们可以使用 swapgs_restore_regs_and_return_to_usermode 函数加上一个偏移完成丝滑返回用户态,下面是原理分析,感兴趣可以看看

我们在 single_start 函数打上断点,手动修改寄存器的值,计算距离 pt_regs 结构体的距离

修改 start 指针,依次读取所有 start 文件即可

???? 重要:exp的一些问题


传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2天前 被xnqjns编辑 ,原因:
收藏
免费 1
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回