Linux系统的安全防护体系(如KASLR、SMAP/SMEP、DEP/NX、ASLR等)旨在阻止攻击者通过漏洞利用获取系统权限。攻击者通常通过信息泄漏、代码复用、内核对象操控等技术绕过这些防护,以下是常见方法及原理:
KASLR通过随机化内核代码、数据的内存地址,防止攻击者精准定位关键函数(如system)或数据结构(如cred)。绕过方法的核心是获取内核基址,进而计算目标地址:
dmesg日志泄露、/proc/pid/maps文件读取、CVE-2022-0185堆溢出)泄露内核对象地址(如task_struct、module),通过基址计算(如内核对象地址 - 固定偏移)得到内核基址。physmap基址、earlycon结构体中的函数指针),结合固定偏移推算内核基址。SMAP/SMEP分别禁止内核态访问用户态内存、执行用户态代码。绕过方法的关键是避免直接跳转至用户态代码:
ret结尾),通过控制栈指针依次执行这些片段,完成权限提升(如修改cred结构体)。ROP不依赖用户态代码,符合SMAP/SMEP要求。eBPF)或内置函数(如native_write_cr4)修改CR4寄存器,关闭SMAP/SMEP(需绕过内核对CR4的校验,如kernel 5.x中对native_write_cr4的修改)。DEP/NX禁止在堆、栈等非可执行内存区域运行代码,防止攻击者注入Shellcode。绕过方法的核心是复用现有代码:
execve("/bin/sh", NULL, NULL)等函数,直接执行系统命令,无需注入Shellcode。ROP链的构造需依赖libc或内核中的gadgets(如pop rdi; ret、mov rax, 0x3b; ret)。eBpf、nftables)生成可执行代码片段,通过堆喷射将这些片段布置在内存中,绕过NX保护。信息泄漏是绕过多数防护的前提,常见泄漏途径包括:
use-after-free(如CVE-2021-4154 GPU驱动漏洞)或堆溢出(如CVE-2022-0995 watch_queue漏洞)泄露内核对象地址(如task_struct中的cred指针)。/proc/pid/maps、/proc/pid/smaps等文件,获取进程内存布局及内核函数地址。dmesg命令泄露内核打印的敏感信息(如函数地址、堆栈内容)。任意地址读写是提权的关键,通过漏洞修改内核内存,控制程序执行流:
msg_msg、tty_struct等结构体的分配与释放),将目标对象(如cred)布置在可预测的位置,便于后续覆盖。setxattr+userfaultfd延长竞争窗口,或修改pipe_buffer的flags字段(如CVE-2022-0847 Dirty Cow漏洞),实现任意地址读写。modprobe_path(内核加载模块的路径)修改为用户可控的脚本路径(如/tmp/exploit.sh),当内核加载错误格式文件时,执行该脚本获取root权限。逻辑漏洞是由于程序逻辑设计缺陷导致的权限绕过,无需直接利用内存破坏:
CVE-2021-4034 Polkit pkexec漏洞,通过设置LD_PRELOAD等环境变量,劫持程序执行流,获取root权限。passwd)或内核线程的高权限,通过漏洞(如CVE-2016-5195 Dirty Cow)修改其内存,继承其权限。CVE-2017-7308 AF_PACKET漏洞,通过错误的对象类型转换(如将packet_sock转换为sock),破坏内存布局,实现权限提升。以上方法通常是组合使用的(如信息泄漏→KASLR绕过→ROP→提权),攻击者会根据漏洞特性选择合适的绕过技术。防御方需通过及时更新补丁、启用多层防护(如SELinux、Seccomp)、限制内核模块加载等方式降低风险。