ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

CTF 内核利用中的 KASLR:原理、QEMU 开关实战与绕过思路(ctf-wiki 内核防护篇)

2026/9/25 13:17:46 拓冰建站 浏览量
CTF 内核利用中的 KASLR:原理、QEMU 开关实战与绕过思路(ctf-wiki 内核防护篇) 文档网络安全教程【免费下载链接】ctf-wikiCome and join us, we need you!项目地址https://gitcode.com/gh_mirrors/ct/ctf-wiki点击查看免费下载导读KASLRKernel Address Space Layout Randomization内核地址空间布局随机化是 Linux 内核中最重要的一道地址随机化防线它会在内核启动时把内核代码段基地址等关键地址做整体偏移直接抬高内核利用ROP、ret2usr、ret2dir 等对绝对地址的依赖门槛。本文以 ctf-wiki 仓库中docs/zh-tw/docs/pwn/linux/kernel-mode/defense/randomization/kaslr.md为骨架系统讲解 KASLR 的防御原理、在 QEMU 内核调试环境中的开启与关闭方法并梳理 CTF 内核题目中最核心的对抗思路——泄漏一段即得全段同时给出仓库内 FGKASLR、QEMU 环境搭建、System.map 等关联文档的延伸阅读路径。读完本文你将能在自己的内核调试环境中自如控制随机化开关并理解内核利用中先泄漏、后计算基址的标准打法。KASLR 是什么内核地址整体偏移正如原文档所述在开启了 KASLR 的内核中内核的代码段基地址等地址会整体偏移。这里的整体偏移是理解 KASLR 的关键偏移的单位是整个内核镜像包括代码段、数据段等而不是单个函数偏移量由内核在启动早期根据随机数生成器决定每次启动都不一样偏移后内核各段之间的相对布局保持不变——这正是攻击者可以利用的地方只要拿到段内任意一个地址就能推算出整个段乃至整个内核镜像的基址。从 CTF 内核题的角度看KASLR 直接破坏了两种常见假设直接使用从vmlinux/bzImage中静态分析得到的固定地址进行 ROP 或提权调用例如commit_creds(prepare_kernel_cred(NULL))中的两个函数地址在内核态漏洞利用中硬编码 gadget 地址。因此在开启 KASLR 的题目中利用链的第一步几乎总是先泄漏某个内核地址再据此重算其它地址。这与用户态 ASLR 的对抗思路同源但内核的泄漏手段更依赖漏洞本身如未初始化指针、UAF 读、/proc接口信息泄露等详见仓库中的 信息泄漏篇。发展历史从 KASLR 到 FGKASLR原文档中发展历史一节标注为 TODO这里补充公认的内核背景知识并结合仓库内文档梳理其演进脉络KASLR 的雏形最早可以追溯到 2005 年前后针对 x86 的随机化补丁面向 x86_64 的 KASLR 由 Kees Cook 等人持续推动最终随 Linux 4.22015 年合入主线成为CONFIG_RANDOMIZE_BASE选项控制的默认开启特性。KASLR 的粒度是整个内核镜像整体偏移存在明显的弱点段内所有地址的相对关系固定一旦泄漏段内任意地址整段地址全部暴露。这正是原文档 Attack 一节的核心结论。针对这一不足研究者进一步实现了FGKASLRFunction Granular KASLR在 KASLR 基地址随机化的基础上于加载时刻以函数粒度重新排布内核代码从而让泄漏一个地址推算出其它地址变得困难得多。仓库中 FGKASLR 文档 对这项演进的实现细节做了完整记录编译期通过-ffunction-sections将函数拆分为独立节区、加载期在layout_randomized_image中收集并乱序排布.text.*节区等是阅读本文后继续深入 KASLR 对抗的最佳下一站。实现要点原文档中实现一节同样标注为 TODO。结合 Linux 内核的公开实现与仓库内 FGKASLR 文档可以把 KASLR 的实现机制归纳为以下几个层面下文带推断性质的内容均已注明1. 编译期开关KASLR 由内核编译选项CONFIG_RANDOMIZE_BASE控制。只有编译时启用了该选项启动参数中的kaslr才真正生效。从源码结构看这一选项主要影响 x86 架构下内核解压与重定位相关代码的编译。2. 启动早期随机化内核镜像在启动早期decompressor 阶段通过重定位机制被整体搬移到某个随机选择的虚拟地址/物理地址上随后内核以该地址为基址继续运行。由于是整体偏移vmlinux中静态定义的符号相对地址在偏移后依然成立——只需加上同一个滑动值slide。3. 符号信息与kallsyms开启 KASLR 后/proc/kallsyms中导出的符号地址即为随机化后的运行时地址。这也意味着内核默认不向低权限用户暴露这些地址通常需要配合kptr_restrict等内核参数收紧访问。仓库的 QEMU 环境脚本中就有echo 1 /proc/sys/kernel/kptr_restrict与echo 1 /proc/sys/kernel/dmesg_restrict的配置详见 QEMU 环境搭建文档。4. FGKASLR 的节区级增强关于函数粒度的实现仓库 FGKASLR 文档 给出了可直接验证的源码片段layout_randomized_image遍历节区头只有同时满足以下条件的节区才会参与随机化节区名以.text开头section flags 中包含SHF_ALLOCsection flags 中包含SHF_EXECINSTR。并给出了对应的readelf --section-headers -W vmlinux输出可据此确认__ksymtab、.data等关键节区不参与函数级随机化——这正是后文绕过思路的重要依据。开启与关闭QEMU 实战原文档给出了最直接的开关方法这也是 CTF 内核调试中最常用的操作如果是使用 qemu 启动的内核我们可以在-append选项中添加kaslr来开启 KASLR添加nokaslr来关闭 KASLR。-append是 QEMU 向内核传递启动参数的选项。仓库的 QEMU 环境搭建文档 提供了完整可用的启动脚本开启 KASLR 的典型形态如下#!/bin/sh 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对应参数说明参数含义-append中的kaslr开启内核地址随机化改成nokaslr即关闭-append中的nokaslr关闭随机偏移便于静态地址调试root/dev/sda rw指定根文件系统所在设备配合-hda挂载为 SATA 硬盘rdinit/sbin/init指定初始进程consolettyS0配合-nographic将内核输出重定向到当前终端-s等价于-gdb tcp::1234在 1234 端口开启 gdbserver若使用 cpioinitramfs文件系统则按仓库文档将-hda换为-initrd、root/dev/sda换为root/dev/ram#!/bin/sh qemu-system-x86_64 \ -m 128M \ -kernel ./bzImage \ -initrd ./rootfs.cpio \ -monitor /dev/null \ -append root/dev/ram rdinit/sbin/init consolettyS0 oopspanic panic1 loglevel3 quiet kaslr \ -cpu kvm64,smep \ -smp cores2,threads1 \ -nographic \ -snapshot \ -s调试建议复现/调试内核题时通常直接关闭随机化方便以vmlinux中的静态地址下断点、比对符号#!/bin/sh qemu-system-x86_64 \ -m 128M \ -kernel ./bzImage \ -hda ./rootfs.img \ -monitor /dev/null \ -append root/dev/sda rw rdinit/sbin/init consolettyS0 oopspanic panic1 loglevel3 quiet nokaslr \ -cpu kvm64,smep \ -smp cores2,threads1 \ -nographic \ -s两点实用提醒kaslr/nokaslr是内核启动参数只对本次启动生效是否真正开启还取决于内核编译时是否启用了CONFIG_RANDOMIZE_BASE若题目环境刻意保留了dmesg_restrict/kptr_restrict低权限用户无法直接读取符号地址这会显著影响直接查 kallsyms的路径需要借助漏洞本身来泄漏内核地址。Attack泄漏一段即得全段原文档的 Attack 一节给出了 KASLR 对抗的核心结论通过泄漏内核某个段的地址就可以得到这个段内的所有地址。比如当我们泄漏了内核的代码段地址就知道内核代码段的所有地址。这是因为 KASLR 只做整体滑动段内相对偏移保持不变。据此可以总结出通用攻击流程泄漏利用漏洞UAF 读、未初始化栈/堆变量、信息泄露接口等获得内核某段通常是代码段或数据段内一个已知符号/对象的运行时地址计算基址用泄漏地址减去该符号在vmlinux中的静态偏移得到内核镜像基址或代码段基址推算全段基于基址 静态偏移计算commit_creds、prepare_kernel_cred、modprobe_path等目标的运行时地址利用将算出的地址用于 ROP、ret2usr 或修改modprobe_path提权。仓库内与之配套的工具与资料包括System.map 文档当拿到的vmlinux被 stripped 时用System.map恢复符号-地址映射其行格式为地址 类型 符号名QEMU 环境搭建文档介绍通过/proc/kallsyms获取prepare_kernel_cred、commit_creds等符号运行时地址以及用/sys/module/xxx/sections/.text获取驱动基地址的方法ROP 利用文档、ret2usr 文档展示拿到地址后如何组织内核态利用链。FGKASLR 下的绕过补充仓库 FGKASLR 文档 还记录了针对 KASLR/FGKASLR 的进阶绕过思路其根本依据依然是相对偏移固定__ksymtab相对内核镜像的偏移固定只要泄露了内核镜像地址就可以定位__ksymtab进而通过符号记录项struct kernel_symbol的value_offset字段解析出prepare_kernel_cred、commit_creds等导出符号的运行时地址数据段相对内核镜像的偏移固定在获得内核镜像基址后即可计算数据区地址重点关注modprobe_path等可写目标直接改写后触发提权由于.text合并且不参与函数级随机化系统调用入口多为汇编代码等位于该节区的地址仍是相对可预测的。这些内容与本篇 KASLR 文档互为补充建议一并阅读 FGKASLR 文档。延伸阅读原文档的参考一节约束下不宜直接给出外部链接这里列出仓库内可直接深入的相关文档随机化防御目录KASLR 与 FGKASLR 的概览FGKASLR 详解函数级随机化的实现、性能/内存开销、开启方式CONFIG_FG_KASLR与攻击面QEMU 内核调试环境搭建kaslr/nokaslr的实际使用场景与 gdb 调试流程KPTI 隔离与 KASLR 常一同出现的内核态/用户态隔离防护内核基础概念阅读上述内容前的预备知识。小结KASLR 是 CTF 内核题中最常见的地址随机化防护整体偏移、段内不变是它的防御模型也是它的最大弱点。实战层面-append kaslr/-append nokaslr是 QEMU 环境中一行即可控制的开关对抗层面泄漏一段即得全段是所有 KASLR 题目利用链的起点而 FGKASLR 文档记录的__ksymtab固定偏移、数据段固定偏移等细节则为在更严格的随机化下完成地址解析提供了可复用的方法论。赞分享文档网络安全教程【免费下载链接】ctf-wikiCome and join us, we need you!项目地址https://gitcode.com/gh_mirrors/ct/ctf-wiki点击查看免费下载相关推荐ctf-wiki 内核 PwnSMEP/SMAP 防护原理与 ROP 绕过实战强网杯 2018 corectf wiki 内核 PwnSMEP/SMAP 防护原理与 ROP 绕过实战强网杯 2018 core 本文是 ctf wiki 内核 ROP 系列文章文档网络安全教程CTF 内核 pwn 防护系列Linux 内核 SMAPSupervisor Mode Access Protection原理、开关配置与绕过手法详解CTF 内核 pwn 防护系列Linux 内核 SMAPSupervisor Mode Access Protection原理、开关配置与绕过手法详解 在文档网络安全教程CTF-Wiki 内核 Pwn 专题userfaultfd 在 Linux 内核条件竞争利用中的原理与实战CTF Wiki 内核 Pwn 专题userfaultfd 在 Linux 内核条件竞争利用中的原理与实战 导读 本文以 ctf wiki 仓库 https:文档网络安全教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考