ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

CTF-Wiki Linux 内核 DoS 攻击:内核崩溃、死锁与内存耗尽的实战路径

CTF-Wiki Linux 内核 DoS 攻击:内核崩溃、死锁与内存耗尽的实战路径 文档网络安全教程【免费下载链接】ctf-wikiCome and join us, we need you!项目地址https://gitcode.com/gh_mirrors/ct/ctf-wiki点击查看免费下载在 Linux 内核漏洞利用的三大目标提权、信息泄露、DoS中对内核发起 DoSDenial of Service拒绝服务攻击通常是最容易实现的一步攻击者不追求获取 root 权限或读取敏感数据只需要让内核无法正常工作即可达成目标。本文以 CTF-Wiki 的 Linux 内核态 pwn 知识体系为主线系统讲解三种典型的 DoS 路径——触发内核漏洞导致崩溃、触发内核死锁、以及通过大量内存申请造成内核内存耗尽并结合仓库内的环境搭建与利用技巧文档给出可复现的实验与判定方法。读完本文你将掌握内核崩溃oops/panic的触发与观测方式、内核死锁的原理与规避手段以及内存耗尽型 DoS 的实战边界。内核 DoS 在攻击目标中的定位在 CTF-Wiki 的 内核利用目标概述 中Linux 内核漏洞利用者的目的被归纳为三类提权Privilege Escalation让普通用户获取 root 权限访问原本受限的资源这是绝大部分 kernel pwn 题目的主目标。信息泄露Information Disclosure获取读取内核数据的能力具体泄露什么数据与利用场景紧密相关参见 信息泄露。DoSDenial of Service即使得内核崩溃、无法继续提供服务。三者中 DoS 的达成门槛最低。它不需要精确的地址计算、不需要绕过 SMEP/SMAP 等防护、也不需要构造复杂的 ROP 链只要能让内核进入不可恢复的错误状态即可。但正因其简单出题时往往不会把 DoS 作为唯一目标——不过理解 DoS 的机制恰恰是理解内核崩溃路径、内存管理和并发模型的基础也能帮助你在调试提权 exploit 失败时判断内核究竟死在了哪里。路径一触发内核漏洞导致崩溃原文指出第一种 DoS 方式是触发内核中的某个漏洞让内核崩溃。内核崩溃在现象上通常表现为 oops 或 panicoops内核检测到非法操作如空指针解引用、非法内存访问、GPF 异常等后打印的错误报告包含寄存器现场、调用栈、指令指针等信息此时内核会尝试继续运行或按配置直接进入 panic。panic内核进入不可恢复状态后调用panic()停止一切工作。从内核态 pwn 的角度看几乎所有可用于提权的原语——任意地址写、任意地址读、UAF、栈溢出、整数溢出等——都可以降级为崩溃原语触发空指针或无效地址的解引用例如对某个未初始化的函数指针调用会直接产生 oops利用任意写破坏关键内核数据如破坏页表、篡改task_struct链表、覆写中断描述符表内核后续访问时大概率 panic栈溢出覆写返回地址后没有正确恢复执行流最终也会以非法指令或段错误的形式崩溃。在 CTF-Wiki 内核态的堆利用、ROP 利用等章节中提到的各类漏洞利用手法其 exploit 失败时最常见的结局就是触发内核崩溃——这也是本地调试提权 exploit 时的常见现象。崩溃后的观测与内核启动参数要在实验环境中明确观测到崩溃行为需要正确配置内核启动参数。在仓库的 QEMU 环境搭建 文档给出的标准启动脚本中有两个参数直接决定了内核崩溃后的行为qemu-system-x86_64 \ -m 128M \ -kernel ./bzImage \ -hda ./rootfs.qcow2 \ -monitor /dev/null \ -append root/dev/sda rw rdinit/sbin/init consolettyS0 oopspanic panic1 loglevel3 quiet kaslr \ -cpu kvm64,smep \ -smp cores2,threads1 \ -nographic \ -snapshot \ -s关键参数含义如下oopspanic指定当内核发生 oops 时直接转入 panic而不是继续执行。这既能防止内核在崩溃后带伤运行产生二次破坏也能让一次漏洞触发与内核完全停止之间建立明确的因果关系便于判断 exploit 是否触碰到了内核的关键路径。panic1指定内核 panic 后 1 秒自动重启避免测试环境挂死。-snapshot以快照方式启动虚拟机中对文件系统的修改不会落盘重启后环境即恢复初始状态非常适合反复验证崩溃型 exploit。从攻击者的角度如果出题环境的启动参数里没有oopspanic那么一次软崩溃仅 oops 但内核继续运行可能不足以让服务真正不可用反之带oopspanic panic1的环境任何一次 oops 都等价于完整的 DoS。路径二触发内核死锁第二种 DoS 方式是触发内核中的死锁。死锁deadlock是指多个执行流互相持有对方需要的资源导致谁都无法继续推进。与用户态死锁不同内核死锁直接冻结整个系统或某个子系统自旋锁spinlock死锁自旋锁在持有期间不允许睡眠若持有者在持锁路径上发生调度、中断嵌套或再次尝试获取同一把锁会导致 CPU 长时间自旋空转系统整体卡死。互斥锁mutex死锁经典的互等环进程 A 持有锁 1 等待锁 2进程 B 持有锁 2 等待锁 1。RCU 阻塞RCU 临界区中执行了可能睡眠的操作导致宽限期无法结束相关内存回收全部停摆。在 CTF 场景下触发内核死锁通常依赖有漏洞的驱动/内核模块例如模块在持锁状态下调用了一个可以阻塞的分配函数或者对同一个锁进行了两次加锁。相比触发崩溃死锁的成功标准更隐蔽——系统不会打印 oops而是表现为所有 CPU 的使用率被打满且长时间无法响应串口终端完全无输出任何输入都没有反应在 QEMU 调试环境中gdb 连接后看到所有 CPU 都停在自旋循环中。值得注意的是由于死锁过程不产生崩溃日志这类 DoS 在 CTF 自动判题环境中通常不会被当作拿到了 flag更多是作为理解内核并发原语与锁序lock ordering的知识点出现。内核自带的 lockdepCONFIG_LOCKDEP与软锁检测CONFIG_SOFTLOCKUP_DETECTOR机制会在死锁或软锁发生时输出警告信息这也是逆向分析驱动代码时判断其是否存在死锁型 DoS 漏洞的重要线索。路径三大量内存申请与内核内存泄漏第三种 DoS 方式是触发大量的内核内存泄漏即存在大量的内存被申请但是没有被释放。它有两种形态真正的泄漏leak驱动或内核代码路径中存在缺陷每次操作都会申请内存但永远不释放长时间运行后内核内存被一点点蚕食殆尽。主动耗尽exhaustion攻击者利用可无限申请内存的接口如 packet socket 的 ring buffer一次性申请大量内存直接把系统物理内存打光。与触发崩溃的精准攻击不同内存型 DoS 更像一场消耗战攻击者不需要精确利用任何漏洞只需要找到一个能够在内核态分配大量内存、且不受或较少受进程内存限制约束的通道。OOM Killer 与内存耗尽的行为边界当系统物理内存被耗尽时内核会唤醒OOM KillerOut-Of-Memory Killer来挑选进程杀死以回收内存。OOM Killer 依据每个进程的OOM Score决策分数越高越容易被杀进程权限越高越不容易被杀。我们可以通过/proc/[pid]/oom_score查看任意进程当前的分数。仓库中的 利用内存溢出触发 OOM Killer 提供 root shell 一文展示了一个极端的边界案例在 CTF 的 kernel pwn 环境中虚拟机内存通常只有 128MB用户进程很容易分配光全部物理内存唤醒 OOM Killer。若出题环境遵循 BusyBox 默认的/etc/inittab配置::askfirst:/bin/sh当 OOM Killer 把除 1 号进程/sbin/init以外的所有用户态进程rcS、sh、exploit都杀死后空闲的 tty 会触发 init 以 root 权限重新拉起一个 shell——内存耗尽型 DoS 就意外地变成了提权。但该文同时强调了重要的边界直接大量分配内存并不保证成功因为分配过程本身会推高 exploit 进程的OOM Score使其在杀戮队列中首当其冲一旦 exploit 先被杀分配动作停止OOM Killer 就不会继续清理其他进程。真正可行的做法是在不增加自身OOM Score的前提下完成内核态内存分配例如利用 packet socket 的 ring bufferPACKET_TX_RING进行非记录型页面分配其最小化 POC 结构如下完整实现见上述文档void unintended_exploit(void) { int errno; prepare_pgv_system(); for (int i 0; i 1000; i) { if ((errno create_pgv_socket(i)) 0) { err_exit(FAILED to allocate socket!); } if ((errno alloc_page(i, 0x1000 * 64, 64)) 0) { err_exit(FAILED to alloc pages on socket!); } printf([*] No.%d times\n, i); fflush(stdout); } puts(Done!?); }对应的底层实现基于socket(AF_PACKET, SOCK_RAW, PF_PACKET)配合setsockopt(SOL_PACKET, PACKET_TX_RING, ...)在内核中分配tpacket_req描述的环形缓冲区页面同一思路的页面喷射封装create_socket_and_alloc_pages()等也出现在 内核利用常用代码模板 kernelpwn.h 中可作为参考。同时该文档明确指出这种做法并不能保证一定成功更常见的结局恰恰是System is deadlocked on memory或Out-of-memory导致 kernel panic——也就是说内存耗尽型 DoS 的终局往往又回到了路径一的内核崩溃。这也解释了为什么原文将大量内存申请但不释放列为 DoS 的一种独立手段它不一定需要利用具体漏洞只需要一个可被滥用的分配接口。与其它 DoS 手段的关系从防御与排障的角度看内存型 DoS 还有若干变体内核态 kmalloc 恶意占用利用 UAF 漏洞制造大量不可回收的对象例如 SLUB freelist 劫持 讨论的分配原语虽以提权为目标但失败或滥用同样会造成分配器状态被破坏而 panic。kmemleak 场景在内核开启了CONFIG_DEBUG_KMEMLEAK的调试环境里可以借助 kmemleak 报告定位申请未释放的具体调用链——这是从检测侧研究内存泄漏 DoS 的工具实际利用中我们关心的则是反过来找到可无限申请、不释放、且不增加自身 OOM 惩罚的接口。如何在实际环境中验证一次内核 DoS结合仓库的 QEMU 环境搭建 文档验证 DoS 的完整闭环如下编译带漏洞的内核模块.ko将其放入基于 BusyBox 构建的文件系统并在/etc/init.d/rcS启动脚本中通过insmod加载使用带oopspanic panic1 consolettyS0参数的 QEMU 启动脚本运行内核在虚拟机内执行触发程序崩溃触发或内存喷射观察串口输出若看到 oops 信息寄存器、调用栈且系统随即重启说明漏洞路径被命中、内核已崩溃若终端完全无响应、CPU 空转则可能陷入了死锁或软锁若系统输出Out-of-memory相关告警或直接进入System is deadlocked on memory则是内存耗尽型 DoS 生效。配合-s即-gdb tcp::1234参数可在另一终端用gdb vmlinux连接定位崩溃现场与死锁位置。由于 DoS 攻击不依赖精确的内核符号与地址尤其在 KASLR 开启时它天然是三种内核攻击目标中受防护影响最小的一种也正因如此理解 DoS 是实现稳定利用之前的低门槛起点——先让内核死掉再研究如何让它按我们的意愿活着。小结对 Linux 内核实施 DoS 的三种主要路径——触发漏洞崩溃、触发死锁、造成大量内存申请未释放——分别对应了内核的异常处理、并发同步与内存管理三大子系统。它们从易到难、从必然发生到看天吃饭共同构成了内核攻击面中最基础也最容易被低估的一环。在 CTF-Wiki 的 kernel pwn 知识体系中利用目标 章节将其定位为与提权、信息泄露并列的第三目标而 OOM Killer 技巧 则进一步展示了内存耗尽与提权之间的意外交集。掌握这三种路径你既能快速判断 exploit 失败时的内核状态也能在需要打掉服务的攻防场景中有的放矢。赞分享文档网络安全教程【免费下载链接】ctf-wikiCome and join us, we need you!项目地址https://gitcode.com/gh_mirrors/ct/ctf-wiki点击查看免费下载相关推荐CTF 内核利用中的 KASLR原理、QEMU 开关实战与绕过思路ctf-wiki 内核防护篇CTF 内核利用中的 KASLR原理、QEMU 开关实战与绕过思路ctf wiki 内核防护篇 导读 KASLRKernel Address Space文档网络安全教程CTF-Wiki 内核利用实战利用 ldt_struct 在内核内存中直接搜索 initramfs 中的 flagCTF Wiki 内核利用实战利用 ldt_struct 在内核内存中直接搜索 initramfs 中的 flag 在多数 CTF 内核Kernel Pwn文档网络安全教程CTF-Wiki 内核 Pwn 专题userfaultfd 在 Linux 内核条件竞争利用中的原理与实战CTF Wiki 内核 Pwn 专题userfaultfd 在 Linux 内核条件竞争利用中的原理与实战 导读 本文以 ctf wiki 仓库 https:文档网络安全教程上一篇Loop 实战指南用径向菜单 3 招搞定 macOS 窗口管理告别手动拖拽下一篇VMware Unlocker5分钟解锁Windows/Linux上的macOS虚拟机支持创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表