首页
社区
课程
招聘
[原创]2019-10-25-InCTF-Internationals-2019-pwnbox分析
发表于: 2019-11-18 14:39 7851

[原创]2019-10-25-InCTF-Internationals-2019-pwnbox分析

2019-11-18 14:39
7851

对rootfs.img解包修改

修改

setsid cttyhack setuidgid 0 /bin/sh 获得root权限,来获取/proc/kallsyms的信息

重新打包脚本:

调试时通过cat /sys/module/core/sections/.text获取驱动加载的基地址

本题获取命令如下:
/ # grep 0 /sys/module/mod/sections/.text
0xffffffffc0000000

在gdb调试时,add-symbol-file core.ko addr对基地址进行加载可调试

从bzImage中提取vmlinux,提取脚本如下:
https://github.com/torvalds/linux/blob/master/scripts/extract-vmlinux

./extract-vmlinux ./bzImage > vmlinux

fcntl系统调用可以用来对已打开的文件描述符进行各种控制操作以改变已打开文件的的各种属性

头文件为:

kcmp检查两个进程的对应的文件描述符idx1和idx2是否指向同一个文件,相同返回0。

参考链接:https://www.cnblogs.com/zxc2man/p/7649240.html

通过mmap指定私有匿名映射,不会立即分配这块内存,在实际访问这块内存才会通过userfaultfd进行分配操作

fget()函数会调用 fget_unlocked(),获取struct file的文件描述符fd,并对引用计数f_count加1。

file 结构定义(sys/sys/file.h):

漏洞点在于box_set 函数:

关闭设备的大体流程

sys_close()->filp_close()->fput()->fput()->release(),所以调用fput函数会调用到 fput()函数,减少对文件的引用计数

在执行[2] 前调用了check_encfile,如果encfile->f_op != &encBox_fops条件成立,将会调用fput函数,所以一共调用了两次fput,引用计数f_count减少2,导致uaf漏洞。要满足该判断条件,只需要文件块不是由box_create分配出来的就行。

利用方式借鉴于Project Zero的https://bugs.chromium.org/p/project-zero/issues/detail?id=808
(CVE-2016-4557)

[1]处调用set_box函数,由于fd_3是由box_new申请得到,所以encfile->f_op = &encBox_fops,不进行fput操作。

iov = init_userfaltfd()函数返回的是MAP_ANONYMOUS属性的页地址,访问时会触发缺页错误。

通过ssize_t writev(int fd, const struct iovec *iov, int iovcnt);函数将iov地址上的内容写入uaf_fd对应的文件中。

函数调用链如下:writev->do_writev->vfs_writev->do_readv_writev

在vfs_writev函数中对文件的可写权限进行了判断,此时uaf_fd对应/home/user/ll文件,可通过判断。(正常/etc/passwd普通用户是不可写的)

在判断可写权限和执行写操作之间的窗口就是我们的条件竞争窗口。我们可以通过userfaultfd来对该竞争窗口进行攻击,达到暂停执行写操作的效果,延长攻击窗口。

在调用do_readv_writev时,会先将调用import_iovec函数从用户层复制iovec结构,之后再进行写操作。因为访问了用户层内存,所以触发了缺页错误,进入userfaltfd处理流程,在流程中执行pwn()函数触发漏洞,将uaf_fd指向/etc/passwd文件,并且通过ioctl(uffd, UFFDIO_COPY, &uffdio_copy)操作给iov地址上写入payload。

最后执行写操作,将iov上的内容写入/etc/passwd。

触发double-fput,形成UAF漏洞的过程如下:

[1]处file->private_data为[0]处赋值的4,对fd_4文件描述符进行操作,引用计数先增1,后触发漏洞连续减去两次,此时fd_4的文件引用计数为1。通过dup2函数使得fd_6也指向fd_4文件,引用计数此时为2。[2]处调用set_box,触发漏洞,先增1,变成3后,又连续两次减去1,变成1。最后利用close函数令引用计数清零,此时文件块属于释放状态,但uaf_fd仍指向该文件块。

在exp中插桩输出调试信息:

调试信息如下:

后续的操作就是通过不断地open("/etc/passwd"),利用kcmp系统调用进行比较,判断是否申请到了之前释放的文件块。如果成功申请到,此时uaf_fd就指向了/etc/passwd文件,可以通过操作uaf_fd对/etc/passwd进行操作。

https://blog.bi0s.in/2019/10/11/Pwn/Kernel-Exploitation/pwnbox_md/

https://secfault-security.com/blog/FreeBSD-SA-1902.fd.html

https://ruxcon.org.au/assets/2016/slides/ruxcon2016-Vitaly.pdf


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2019-11-18 14:40 被笔墨编辑 ,原因:
收藏
免费 5
支持
分享
最新回复 (1)
雪    币: 26785
活跃值: (63217)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
2
感谢分享!
2019-11-18 15:06
0
游客
登录 | 注册 方可回帖
返回
//