启动脚本
#!/bin/sh
stty intr ^]
qemu-system-x86_64 -enable-kvm -cpu kvm64,+smep,+smap -m 64M -kernel ./bzImage -initrd ./rootfs.cpio -append "root=/dev/ram rw console=ttyS0 oops=panic panic=1 quiet kaslr" -monitor /dev/null -nographic 2>/dev/null
init
#!/bin/sh
mknod -m 0666 /dev/null c 1 3
mknod -m 0660 /dev/ttyS0 c 4 64
mount -t proc proc /proc
mount -t sysfs sysfs /sys
cat /root/signature
echo 2 > /proc/sys/kernel/kptr_restrict
echo 1 > /proc/sys/kernel/dmesg_restrict
insmod /zerofs.ko
setsid cttyhack setuidgid 1000 sh
umount /proc
umount /sys
poweroff -f
主要就是凸显拒绝/proc/kallsymble泄露地址。
然后没有设置ptmx文件的权限
换言之就是能劫持tty结构体 能覆盖ptmx结构体。
看得出来逆向会非常的辛苦
看看函数我们应该能感受的出来
这显然长的很像一个文件系统。
我们要额外学习一些虚拟文件系统的知识。
“一切皆是文件”是 Unix/Linux 的基本哲学之一。不仅普通的文件,目录、字符设备、块设备、 套接字等在 Unix/Linux中都是以文件被对待;它们虽然类型不同,但是对其提供的却是同一套操作接口。
虚拟文件系统正是实现上述 Linux 特性的关键所在。虚拟文件系统(Virtual File System, 简称 VFS), 是Linux内核中的一个软件层,用于给用户空间的程序提供文件系统接口;同时,它也提供了内核中的一个抽象功能,允许不同的文件系统共存。系统中所有的文件系统不但依赖VFS 共存,而且也依靠 VFS 协同工作。为了能够支持各种实际文件系统,VFS 定义了所有文件系统都支持的基本的、概念上的接口和数据结构;同时实际文件系统也提供 VFS所期望的抽象接口和数据结构,将自身的诸如文件、目录等概念在形式上与VFS的定义保持一致。换句话说,一个实际的文件系统想要被 Linux支持,就必须提供一个符合VFS标准 的接口,才能与 VFS 协同工作。实际文件系统在统一的接口和数据结构下隐藏了具体的实现细节,所以在VFS层和内核的其他部分看来,所有文件系统都是相同的。
Linux虚拟文件系统四大对象:
•超级块(super block)
•索引节点(inode)
•目录项(dentry)
•文件对象(file)
超级块在每个文件系统的根上,描述和维护文件系统的状态。文件系统中管理的每个对象(文件或目录)在 Linux 中表示为一个inode。inode 包含管理文件系统中的对象所需的所有元数据(包括可以在对象上执行的操作)。dentry用来实现名称和 inode之间的映射,dentry还维护目录和文件之间的关系,从而支持在文件系统中移动。文件对象描述的是进程已经打开的文件。因为一个文件可以被多个进程打开,所以一个文件可以存在多个文件对象。但是由于文件是唯一的,那么inode就是唯一的,目录项也是定的。
我们知道一个文件系统的镜像,需要mount到目录上,才能使用。而mount是如何来识别这些文件系统的?这就靠驱动,register_filesystem将用户定义的文件系统注册,链接到系统维护的一个文件系统表上,mount遍历这张表,丛中取出对应的文件系统,并使用驱动里提供的一系列函数进行文件操作。
函数太多我们直接定位漏洞函数吧。
get_inode函数中是从文件系统镜像里去读取一个文件的inode,里面会记录文件大小等属性。
如果我们对文件里的size进行伪造,那么就可以造成溢出。
然后具体利用就跟klist那个题目一样。
利用溢出搜索到cred结构体
然后修改
提权。
exp写起来感觉好麻烦的样子
咕咕咕
大佬博客贴过来
可以去里面看看
ha1vk