
文档网络安全教程【免费下载链接】ctf-wikiCome and join us, we need you!项目地址https://gitcode.com/gh_mirrors/ct/ctf-wiki点击查看免费下载内核日志dmesg与符号表/proc/kallsyms是 kernel pwn 中攻击者获取内核地址信息的两个核心情报源前者可能直接打印出内核地址或敏感数据后者则直接暴露 commit_creds、prepare_kernel_cred 等关键符号的加载地址。本文以 ctf-wiki 仓库中 信息泄漏防护文档 为主体系统讲解 Linux 内核针对这两类信息泄漏途径的内核级访问控制机制——dmesg_restrict与kptr_restrict的语义、配置方法、在内核源码中的底层实现以及在 CTF 内核题环境中的实际影响与实战应对。背景为什么内核要限制信息输出在 Linux kernel pwn 中攻击者最常用的提权手段是执行commit_creds(prepare_kernel_cred(init_task))将当前进程的凭证cred替换为 root 权限的凭证。正如仓库的 基础知识文档 所述这两个函数与init_cred等关键符号的地址传统上都可以通过/proc/kallsyms查看较老的内核版本中是/proc/ksyms例如$ 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与此同时内核函数printk()的输出虽然不一定显示在终端上但一定会写入内核日志缓冲区可以通过dmesg命令查看。驱动在printk中泄漏的地址、flag 加载地址等信息都可能成为攻击链条上的关键拼图。因此内核提供了一系列访问控制手段对这些对象的信息输出施加不可读限制。这正属于仓库中 访问控制Access Control专题 的范畴通过给内核对象添加访问控制使其具备不可写或不可读等约束。其中针对信息泄漏的两个核心开关就是dmesg_restrict与kptr_restrict。dmesg_restrict限制内核日志的读取选项语义dmesg_restrict用于控制是否允许使用dmesg命令查看内核日志缓冲区kernels log buffer中的消息。内核文档给出的精确定义如下dmesg_restrict: This toggle indicates whether unprivileged users are prevented from using dmesg(8) to view messages from the kernels log buffer. When dmesg_restrict is set to (0) there are no restrictions. When dmesg_restrict is set set to (1), users must have CAP_SYSLOG to use dmesg(8). The kernel config option CONFIG_SECURITY_DMESG_RESTRICT sets the default value of dmesg_restrict.可以归纳为0默认无任何限制任何用户都可以通过dmesg查看内核日志。1只有拥有CAP_SYSLOG权限的用户才可以通过dmesg查看内核日志。其中CAP_SYSLOG是 Linux capability 中的一项通常只有 root 用户或具备该 capability 的进程持有。这一设计的动机在于内核日志中可能包含地址信息或敏感信息研究者和内核维护者因此提出需要限制对内核日志的访问。默认值来源CONFIG_SECURITY_DMESG_RESTRICT值得注意的一点是dmesg_restrict的默认值由内核编译选项CONFIG_SECURITY_DMESG_RESTRICT决定。也就是说出题者在编译内核时就可以决定题目环境默认是否开启该保护。在 CTF 内核题目中除了编译期默认值外启动脚本init也可以动态写入该开关进行覆盖二者协同决定最终环境状态。运行时配置方法dmesg_restrict作为一个 sysctl 内核参数可以通过/proc/sys/kernel/dmesg_restrict在运行时动态开启或关闭# 开启限制非特权用户读取内核日志 echo 1 /proc/sys/kernel/dmesg_restrict # 关闭允许任意用户读取内核日志 echo 0 /proc/sys/kernel/dmesg_restrict在 CTF 题目中这一开关通常被写入文件系统的启动脚本init中。仓库的 内核 ROP 实战文档 展示了一个典型的内核题启动脚本其中echo 1 /proc/sys/kernel/dmesg_restrict与echo 1 /proc/sys/kernel/kptr_restrict成对出现#!/bin/sh mount -t proc proc /proc mount -t sysfs sysfs /sys mount -t devtmpfs none /dev /sbin/mdev -s mkdir -p /dev/pts mount -vt devpts -o gid4,mode620 none /dev/pts chmod 666 /dev/ptmx cat /proc/kallsyms /tmp/kallsyms echo 1 /proc/sys/kernel/kptr_restrict echo 1 /proc/sys/kernel/dmesg_restrict ifconfig eth0 up udhcpc -i eth0 ifconfig eth0 10.0.2.15 netmask 255.255.255.0 route add default gw 10.0.2.2 insmod /core.ko ...仓库的 qemu 环境搭建文档 中也给出了同样的配置模式即在启动脚本中通过以下两行同时开启两项保护echo 1 /proc/sys/kernel/dmesg_restrict echo 1 /proc/sys/kernel/kptr_restrict从源码结构看这种先保存 kallsyms 快照、再开启限制的写法见上例第 9 行在真实题目中相当常见——出题者在 root 权限下先把符号表内容备份到可读文件再收紧权限从而既保证题目可解借助备份文件又模拟了真实环境中的信息泄漏防护。kptr_restrict限制内核地址的输出选项语义kptr_restrict用于控制输出内核地址时施加的限制主要限制以下接口通过/proc获取的内核地址最典型的是/proc/kallsyms通过其它接口有待研究获取的地址。内核文档给出的精确定义如下kptr_restrict: This toggle indicates whether restrictions are placed on exposing kernel addresses via /proc and other interfaces. When kptr_restrict is set to 0 (the default) the address is hashed before printing. (This is the equivalent to %p.) When kptr_restrict is set to (1), kernel pointers printed using the %pK format specifier will be replaced with 0s unless the user has CAP_SYSLOG and effective user and group ids are equal to the real ids. This is because %pK checks are done at read() time rather than open() time, so if permissions are elevated between the open() and the read() (e.g via a setuid binary) then %pK will not leak kernel pointers to unprivileged users. Note, this is a temporary solution only. The correct long-term solution is to do the permission checks at open() time. Consider removing world read permissions from files that use %pK, and using dmesg_restrict to protect against uses of %pK in dmesg(8) if leaking kernel pointer values to unprivileged users is a concern. When kptr_restrict is set to (2), kernel pointers printed using %pK will be replaced with 0s regardless of privileges.具体输出的内容与该选项配置的值有关0默认没有限制但地址在打印前会进行哈希处理equivalent to%p即等价于使用%p格式化符输出哈希值。1使用%pK输出的内核指针地址将被替换为 0除非用户具有CAP_SYSLOG特权并且有效用户 ID/组 IDeffective user and group ids与真实 IDreal ids相等。2使用%pK输出的内核指针都将被替换为 0即与权限无关任何权限都无法读到真实地址。关键技术细节read() 时校验文档中特别强调了一个实现细节%pK的权限检查是在read() 时进行的而不是在 open() 时进行。这意味着如果一个特权进程在 open() 与 read() 之间提升了权限例如通过 setuid 二进制%pK依然不会把内核指针泄漏给非特权用户。同时内核文档也指出这是一种临时性解决方案temporary solution only正确的长期方案是在 open() 时做权限检查并建议如果担心把内核指针值泄漏给非特权用户应当移除使用%pK的文件的 world 读权限并配合dmesg_restrict来保护 dmesg(8) 中对%pK的使用。运行时配置方法# 级别 0默认地址哈希后打印%p echo 0 /proc/sys/kernel/kptr_restrict # 级别 1非特权用户看到的 %pK 输出被替换为 0 echo 1 /proc/sys/kernel/kptr_restrict # 级别 2所有用户的 %pK 输出都被替换为 0 echo 2 /proc/sys/kernel/kptr_restrict对 /proc/kallsyms 的实际影响当开启kptr_restrict保护后攻击者就不能通过/proc/kallsyms获取内核中某些敏感的地址了如commit_creds、prepare_kernel_cred。这也是 kernel pwn 中 ROP 链构造最依赖的两个符号。开启保护前后/proc/kallsyms的典型差异可以通过仓库 qemu 环境搭建文档 中的示例观察在未开启kptr_restrict时root 用户可以直接查询到符号的真实地址# cat /proc/kallsyms | grep prepare_kernel_cred ffffffffa66d0b90 T __pfx_prepare_kernel_cred ffffffffa66d0ba0 T prepare_kernel_cred ffffffffa8061668 r __ksymtab_prepare_kernel_cred而当kptr_restrict1或 2且当前进程不具备CAP_SYSLOG权限时%pK输出的内核指针将被替换为 0非特权用户看到的内容会退化为全零地址无法直接用于 ROP 计算。需要特别说明的边界情况是kptr_restrict限制的是实时查询。如果题目启动脚本在开启保护之前就已经以 root 权限将/proc/kallsyms的内容备份到了普通用户可读的文件如/tmp/kallsyms那么攻击者依然可以从备份文件中读取符号地址。这正是 内核 ROP 实战文档 中分析过的场景启动脚本第 9 行把kallsyms的内容保存到了/tmp/kallsyms那么就能从/tmp/kallsyms中读取commit_creds、prepare_kernel_cred的地址第 10 行把kptr_restrict设为 1这样就不能通过/proc/kallsyms实时查看函数地址了但第 9 行已经把其中的信息保存到了一个可读的文件中这句就无关紧要了第 11 行把dmesg_restrict设为 1这样就不能通过dmesg查看 kernel 的信息了。这也揭示了 CTF 内核题的一个通用规律信息泄漏防护的强度取决于符号地址泄露渠道是否被彻底封死。若备份文件存在KASLR 之类基于隐藏地址的防护参见仓库 FGKASLR 文档也会被一并削弱。与其它内核防护机制的协同与 KASLR / FGKASLR 的关系kptr_restrict限制的是谁能看到地址而 KASLR内核地址空间布局随机化限制的是地址是否可预测。二者互补KASLR 虽然能在一定程度上缓解攻击但若攻击者通过信息泄漏漏洞获取到内核中的某个地址仍能直接推算出内核加载偏移进而得知整个内核地址布局基础知识文档 中对此有说明。因此kptr_restrict正是为了封堵/proc/kallsyms这条最直接的地址泄漏途径。FGKASLR 更进一步不仅随机化加载基址还在函数粒度重排内核代码并且如仓库 FGKASLR 文档 所述为了隐藏新的内存布局/proc/kallsyms中符号使用随机的顺序排列与kptr_restrict一起增加了从符号表恢复布局的难度。与 KPTI 绕过链的配合在 KPTI 绕过文档 中swapgs_restore_regs_and_return_to_usermode等关键函数的地址也需要从/proc/kallsyms中获得。这些利用链中普遍采用的/tmp/kallsyms备份读取模式见 bypass-smep.md、ret2usr.md 等文档中的fopen(/tmp/kallsyms, r)代码说明即便开启了kptr_restrict只要题目保留了符号表备份信息泄漏防护就形同虚设出题与解题的博弈点往往就落在这个备份文件上。与 dmesg 信息泄漏的关联dmesg_restrict与kptr_restrict常常成对开启因为dmesg输出中也可能包含%pK打印的内核指针。内核文档明确指出可以使用 dmesg_restrict 来保护 dmesg(8) 中对 %pK 的使用即防止通过日志间接泄漏内核指针。在 double-fetch 利用文档 中也能看到反面案例当驱动通过printk输出 flag 的加载地址时攻击者正是通过dmesg读取该地址exp 中system(dmesg | grep flag /tmp/addr.txt)因此解题前置条件之一就是关闭dmesg_restrict否则无法查看 printk 信息具体操作是在启动脚本中加入echo 0 /proc/sys/kernel/dmesg_restrict这从正反两面印证了dmesg_restrict在实战中对信息泄漏链路的决定性影响。实战视角如何分析一道内核题的保护强度综合以上机制拿到一道 CTF 内核题时可以从以下角度评估其信息泄漏防护强度检查启动脚本init搜索dmesg_restrict、kptr_restrict的写入值。若二者均被设为 1 或 2说明题目限制了 dmesg 与 kallsyms 的直接读取。检查符号表备份寻找cat /proc/kallsyms /tmp/kallsyms之类的语句。存在备份则意味着符号地址仍可获取ROP 链可以照常构造。检查 printk 泄漏面逆向驱动中是否有printk输出地址或敏感数据若有需确认dmesg_restrict是否开启以及当前用户是否具备读取权限。结合 KASLR 状态若同时存在符号表备份且未开启nokaslr通常仍需借助泄漏出的单个地址推算基址若符号表不可读且无备份则需依赖其它信息泄漏漏洞如未初始化内存、堆风水来恢复地址。上述检查均基于仓库中真实题目环境rop.md、qemu-emulate.md、writable-root.md 等文档所描述的启动脚本与利用代码可作为可复用的分析方法。小结dmesg_restrict与kptr_restrict是 Linux 内核针对信息泄漏的两道基础访问控制闸门前者以CAP_SYSLOG为门槛限制内核日志的读取后者通过%pK格式化符在输出层面对内核地址进行哈希或清零处理配合 KASLR/FGKASLR、KPTI 等机制共同构筑内核地址空间的保密防线。对 CTF kernel pwn 而言理解这两个开关的语义与配置位置是评估题目难度、选择信息泄漏利用路径的第一步——无论目标是构造commit_creds(prepare_kernel_cred(init_task))提权链还是通过 dmesg 中的 printk 输出定位 flag都必须先厘清这两道闸门的状态与绕过空间。参考信息泄漏本文主体文档访问控制专题索引内核 pwn 基础知识kallsyms 与 commit_creds内核 ROP 实战启动脚本中的防护配置qemu 环境搭建与调试kallsyms 查询示例double-fetch 利用dmesg 读取 printk 信息赞分享文档网络安全教程【免费下载链接】ctf-wikiCome and join us, we need you!项目地址https://gitcode.com/gh_mirrors/ct/ctf-wiki点击查看免费下载相关推荐ctf-wiki 内核 Pwn 防御机制解读dmesg_restrict 与 kptr_restrict 信息泄漏防护详解ctf wiki 内核 Pwn 防御机制解读dmesg_restrict 与 kptr_restrict 信息泄漏防护详解 导读 本文聚焦 ctf wiki文档网络安全教程CTF 内核 pwn 防护系列Linux 内核 SMAPSupervisor Mode Access Protection原理、开关配置与绕过手法详解CTF 内核 pwn 防护系列Linux 内核 SMAPSupervisor Mode Access Protection原理、开关配置与绕过手法详解 在文档网络安全教程CTF 内核利用中的 KASLR原理、QEMU 开关实战与绕过思路ctf-wiki 内核防护篇CTF 内核利用中的 KASLR原理、QEMU 开关实战与绕过思路ctf wiki 内核防护篇 导读 KASLRKernel Address Space文档网络安全教程上一篇react-page 与 ReactAdmin 集成指南用 RaReactPageInput 与 RaSelectReferenceInputField 构建富内容后台下一篇从零到精通Reinstall脚本让VPS系统重装变得前所未有的简单创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考