X86_X32 的 recvmmsg 系统调用未正确清理从用户空间传递的超时指针。
将内核地址的指针作为超时参数传递给 recvmmsg,如果知道该地址的原始字节,就可以用已知数据覆盖它。如果最低有效字节是 0xff,等待 255 秒后它就会变成 0x00。
传递地址的第一个长整型( tv_sec )必须为正,第二个长整型( tv_nsec )必须小于 1000000000。
目标定位 ptmx_fops 结构体中的 release 函数指针,该结构体位于未初始化(因此可写)的内核内存中。将三个最高有效字节清零,从而将其转换为指向用户空间可映射地址的指针。选择 release 指针是因为它后面跟着 16 个 0x00 字节(因此 tv_nsec 有效)。打开 /dev/ptmx,关闭它,然后享受。不太优雅,但如果符号可解析,应该相当可靠。在 Ubuntu 13.10 上测试。
另见 http://blog.includesecurity.com/2014/03/exploit-CVE-2014-0038-x32-recvmmsg-kernel-vulnerablity.html
从 /proc/kallsyms 获取地址并运行利用程序:
./build.sh && ./timeoutpwn
如果你想为远程服务器构建二进制文件,可以尝试以下操作:
ssh user@host 'cat /proc/kallsyms' > syms.txt
CFLAGS=-static ./build.sh syms.txt
scp timeoutpwn user@host:
...
如果在 kallsyms 中找不到 ptmx_fops,请尝试从头文件包(Arch Linux 上的 linux-headers)提供的 vmlinux 中提取:
nm /lib/modules/$(uname -r)/build/vmlinux > syms.txt