ARTICLE DETAIL

资讯详情

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

ctf-wiki 内核 Pwn 专题:KASLR 内核地址空间随机化原理与绕过实战指南

ctf-wiki 内核 Pwn 专题:KASLR 内核地址空间随机化原理与绕过实战指南 文档网络安全教程【免费下载链接】ctf-wikiCome and join us, we need you!项目地址https://gitcode.com/gh_mirrors/ct/ctf-wiki点击查看免费下载导读KASLRKernel Address Space Layout Randomization内核地址空间布局随机化是现代 Linux 内核中最基础也最常见的防御机制之一它通过在加载时给内核镜像整体叠加一个随机偏移使攻击者无法事先预知内核代码段、数据段的实际加载地址。本文以 ctf-wiki 仓库的 kaslr.md 为主体结合仓库中内核 Pwn 相关文档如 basic-knowledge.md、qemu-emulate.md、fgkaslr.md展开读完本文后你将掌握 KASLR 的偏移模型、在 QEMU 中开启/关闭 KASLR 的完整方法、通过信息泄漏计算内核加载偏移的绕过思路以及 KASLR 与 FGKASLR、KPTI 等机制的相互关系。KASLR 是什么内核镜像的整体随机偏移在开启了 KASLR 的内核中内核的代码段基地址等地址会整体偏移。也就是说内核镜像在映射到实际地址空间时会被加上一个随机的偏移值但内核内部的相对偏移关系保持不变。basic-knowledge.md 给出了更精确的表述KASLR 即内核空间地址随机化kernel address space layout randomize与用户态程序的 ASLR 相类似——在内核镜像映射到实际的地址空间时加上一个偏移值粒度为 256MB但是内核内部的相对偏移其实还是不变的。两个常用的参考基址未开启 KASLR 时内核代码段基址0xffffffff81000000direct mapping area 基址0xffff888000000000因此KASLR 的本质是单个随机偏移 固定内部布局只要攻击者能通过信息泄漏拿到内核中任何一个段的地址就可以反推出整个偏移从而算出该段内所有符号的地址。这正是后面Attack一节的核心逻辑。KASLR 在仓库中的定位内核防御体系的一环在 ctf-wiki 中内核防御机制被划分为隔离、访问控制、异常检测、随机化四类见 defense/readme.md隔离isolation如 KPTIKernel Page Table Isolation将内核态与用户态页表进一步隔离最初目的之一就是缓解 KASLR 被绕过以及 CPU 侧信道攻击访问控制access control如 信息泄漏防护 中的dmesg_restrict与kptr_restrict用于限制内核日志和内核指针的输出异常检测detection如内核栈 canary随机化randomization即本文的 KASLR以及其进阶版 FGKASLR。在 randomization/readme.md 中有句总结性的话我们可以通过增加内核的随机性来提高安全性。KASLR 正是这一思想的基础实现。值得注意的是KASLR 与 KPTI 之间存在紧密关联kpti.md 明确指出 KPTI 机制最初的主要目的是缓解 KASLR 的绕过以及 CPU 侧信道攻击。理解这一点有助于把握内核防御的整体层次KASLR 让地址不可预测KPTI 则进一步在页表层面限制内核内存的可见性。开启与关闭 KASLR在 QEMU 环境中KASLR 通过内核启动参数即-append选项中的内容控制这与仓库中 qemu-emulate.md 描述的启动方式完全一致。开启 KASLR如果是使用 QEMU 启动的内核可以在-append选项中添加kaslr来开启 KASLR。参考 qemu-emulate.md 的完整启动脚本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即为开启内核地址随机化的内核启动参数。CTF 中很多题目的启动脚本start.sh就带有kaslr例如 rop.md 中的示例qemu-system-x86_64 \ -m 64M \ -kernel ./bzImage \ -initrd ./core.cpio \ -append root/dev/ram rw consolettyS0 oopspanic panic1 quiet kaslr \ -s \ -netdev user,idt0, -device e1000,netdevt0,idnic0 \ -nographic关闭 KASLR如果是使用 QEMU 启动的内核可以在-append选项中添加nokaslr来关闭 KASLR。这在调试阶段非常常用——关闭随机化后内核代码段基址固定为0xffffffff81000000符号地址可预期GDB 下断点、定位 gadget 都更方便。qemu-emulate.md 明确给出建议我们还可以在启动时指定内核关闭随机化对应的启动脚本片段为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与其它启动参数配合在 CTF 实战中KASLR 通常与 KPTIption等其它防护一起出现例如 kpti-bypass.md 中的启动参数为... quiet kaslr ption。这意味着即便你成功绕过了 KASLR 拿到内核地址还要面对 KPTI 的页表隔离相关绕过手法如利用swapgs_restore_regs_and_return_to_usermode切换页表并返回用户态可参见 kpti.md 与 kpti-bypass.md。Attack泄漏一个地址推导整个段KASLR 的绕过思路非常直观kaslr.md 原文如下通过泄漏内核某个段的地址就可以得到这个段内的所有地址。比如当我们泄漏了内核的代码段地址就知道内核代码段的所有地址。其数学本质是由于 KASLR 只是给整个镜像加了一个统一偏移内核内部符号之间的相对偏移是固定不变的。因此攻击流程一般是通过某种信息泄漏漏洞如未初始化指针、越界读、dmesg 日志中的地址打印等拿到内核中任意一个已知符号的运行地址用该运行地址减去其在 vmlinux 中的静态地址得到 KASLR 偏移kaslr_offset将 vmlinux 中所有符号的静态地址都加上kaslr_offset即可得到完整的内核地址布局。信息泄漏的入口与防护仓库中 information-disclosure.md 专门讲述了两种限制地址泄露的机制这与 KASLR 的绕过直接相关dmesg_restrict控制是否可以用dmesg查看内核日志。为 0 时无限制为 1 时只有具有CAP_SYSLOG权限的用户才能查看。kptr_restrict控制通过/proc等接口输出的内核指针。值为 0 时默认无限制值为 1 时%pK输出的指针在无CAP_SYSLOG权限时被替换为 0值为 2 时无论权限如何%pK指针一律替换为 0。当开启这些保护后攻击者就不能通过/proc/kallsyms直接获取commit_creds、prepare_kernel_cred等敏感符号的地址了。注意 qemu-emulate.md 中的环境脚本就同时设置了echo 1 /proc/sys/kernel/dmesg_restrict echo 1 /proc/sys/kernel/kptr_restrict这提醒我们真实 CTF 题目的内核环境中/proc/kallsyms往往不可直接利用信息泄漏点只能来自漏洞本身。从 kallsyms 获取符号地址未限制时当kptr_restrict未开启、且拥有足够权限时可以直接从/proc/kallsyms读取符号地址。仓库 basic-knowledge.md 给出了完整示例$ sudo cat /proc/kallsyms | grep T commit_creds ffffffffbb11ab20 T commit_creds $ sudo cat /proc/kallsyms | grep T prepare_kernel_cred ffffffffbb11b080 T prepare_kernel_cred $ sudo cat /proc/kallsyms | grep D init_cred ffffffffbce58840 D init_cred而 qemu-emulate.md 中也演示了类似操作# cat /proc/kallsyms | grep prepare_kernel_cred ffffffffa66d0b90 T __pfx_prepare_kernel_cred ffffffffa66d0ba0 T prepare_kernel_cred ffffffffa8061668 r __ksymtab_prepare_kernel_cred在未开启 KASLR 时commit_creds、prepare_kernel_cred的地址应当与 vmlinux 中的静态地址一致开启 KASLR 后则会整体偏移。这组地址正是后续构造内核 ROP 链提权commit_creds(prepare_kernel_cred(init_task))见 basic-knowledge.md所需的关键输入。计算 KASLR 偏移的实战模式结合仓库中 ROP 章节的示例如 rop.md 中打印的kaslr offset、kpti-bypass.md 中的SUCCESS_MSG( , kaslr offset: )一个典型的计算流程是leaked_addr 从漏洞 / dmesg / 其它泄露点获得的内核地址 static_addr 该符号在 vmlinux 中的静态地址readelf/nm 查得 kaslr_offset leaked_addr - static_addr commit_creds static_commit_creds kaslr_offset prepare_kernel_cred static_prepare_kernel_cred kaslr_offset只要泄漏点足够准确这个偏移一旦算出整个内核的代码段、数据段布局对攻击者而言就完全是透明的——这正是 KASLR 的弱点所在也是其后续演进为 FGKASLR 的直接动机。从 KASLR 到 FGKASLR函数级随机化的演进KASLR 虽然在一定程度上能够缓解攻击但若攻击者通过信息泄露漏洞获取到内核中的某个地址仍能直接得知内核加载地址偏移从而得知整个内核地址布局。因此有研究者基于 KASLR 实现了 FGKASLRFunction Granular KASLR以函数粒度重新排布内核代码相关说明见 basic-knowledge.md 与 fgkaslr.md。两者的核心差异特性KASLRFGKASLR随机化粒度整个内核镜像整体偏移函数粒度.text.* 节区重排相对偏移是否固定固定可推导整个段不固定函数之间相对偏移改变绕过难度泄漏一个地址即可算全段泄漏单个函数地址无法直接推导全部架构支持通用目前仅支持 x86_64FGKASLR 的实现要点详见 fgkaslr.md编译阶段利用 gcc 的-ffunction-sections选项将内核中不同的函数放到不同的 section 中编译后的 vmlinux 保留所有节区头Section Headers以便知道每个函数的地址范围同时还有一个重定位地址的扩展表供内核解压后乱序排列函数加载阶段解压内核后先检查保留的符号信息寻找需要随机化的.text.*节区其中第一个合并节区.text会被跳过系统调用入口等汇编代码位于其中其余节区地址会被随机化但仍与.text相邻随机化条件只有同时满足节区名以.text开头、section flags 包含SHF_ALLOC、SHF_EXECINSTR的节区才会参与随机化因此__ksymtab与.data不参与随机化——这意味着它们相对于内核镜像的偏移仍是固定的攻击者依然可以利用__ksymtab中的kernel_symbol结构value_offset/name_offset/namespace_offset逐项推导出prepare_kernel_cred、commit_creds等符号地址。可见KASLR 是理解后续一切内核随机化攻防的起点掌握了整体偏移模型才能理解 FGKASLR 为什么要打散函数、KPTI 为什么要隔离页表、__ksymtab为什么是绕过随机化的稳定锚点。小结关键点结论KASLR 本质内核镜像整体加上随机偏移粒度 256MB内部相对偏移不变默认基址代码段0xffffffff81000000direct map0xffff888000000000未开启时开启方式QEMU-append中加入kaslr关闭方式QEMU-append中加入nokaslr便于调试绕过原理泄漏内核任意段地址 → 计算偏移 → 推导全段符号地址关键文件/proc/kallsyms受kptr_restrict限制、__ksymtab、vmlinux 静态符号演进方向FGKASLR 函数级随机化、KPTI 页表隔离参考KASLR 文档本文主体FGKASLR 文档内核基础知识KASLR 与符号地址QEMU 内核环境搭建启动参数与 kaslr/nokaslr信息泄漏防护dmesg_restrict 与 kptr_restrictKPTI 与 KASLR 的关系内核 ROPkaslr 场景下的提权示例赞分享文档网络安全教程【免费下载链接】ctf-wikiCome and join us, we need you!项目地址https://gitcode.com/gh_mirrors/ct/ctf-wiki点击查看免费下载相关推荐ctf-wiki 内核 Pwn 防护专题FGKASLR 函数粒度地址随机化的原理、开销与绕过面ctf wiki 内核 Pwn 防护专题FGKASLR 函数粒度地址随机化的原理、开销与绕过面 FGKASLRFunction Granular KASLR文档网络安全教程Linux内核引导过程第六部分内核地址空间随机化KASLRLinux内核引导过程第六部分内核地址空间随机化KASLR 前言 本文是深入解析Linux内核引导过程的第六部分我们将重点探讨内核地址空间随机化Ker文档教程操作系统CTF 内核利用中的 KASLR原理、QEMU 开关实战与绕过思路ctf-wiki 内核防护篇CTF 内核利用中的 KASLR原理、QEMU 开关实战与绕过思路ctf wiki 内核防护篇 导读 KASLRKernel Address Space文档网络安全教程上一篇PromptX开源项目完整指南从零构建AI专家系统下一篇MKS TinyBee智能主板无线控制的3D打印技术突破创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表