RedEyed Asked: 2015-12-02 07:26:31 +0800 CST2015-12-02 07:26:31 +0800 CST 2015-12-02 07:26:31 +0800 CST 如何在运行时检测 KASLR 是启用还是禁用? 772 如何在运行时检测 KASLR 是启用还是禁用? command-line 4 个回答 Voted WinEunuuchs2Unix 2018-04-01T12:38:26+08:002018-04-01T12:38:26+08:00 回答问题: $ cat /proc/cmdline BOOT_IMAGE=/boot/vmlinuz-4.14.27-041427-generic root=UUID=f3f8e7bc-b337-4194-88b8-3a513f6be55b ro quiet splash loglevel=0 vga=current udev.log-priority=3 fastboot kaslr acpiphp.disable=1 crashkernel=384M-2G:128M,2G-:256M vt.handoff=7 Best Answer x4k3p 2016-03-05T12:29:47+08:002016-03-05T12:29:47+08:00 检查你的内核命令行。(debian 8 上的示例) $ cat /proc/cmdline BOOT_IMAGE=/vmlinuz-`uname -r` root=/dev/mapper/`hostname`-root ro quiet kASLR 从 Ubuntu 14.10 开始可用,但默认情况下未启用。在内核命令行上指定“kaslr”选项以使用 kASLR。 注意:启用 kASLR 将禁用进入休眠模式的能力。 来源:https ://wiki.ubuntu.com/Security/Features bhass1 2020-08-07T09:02:48+08:002020-08-07T09:02:48+08:00 我对之前的答案不满意,因为他们真的没有深入验证 KASLR 的全部内容 - 特别是未实现相同内核命令行界面的嵌入式或自定义内核(例如 ARM64 需要一个设备-tree 选择称为 kaslr-seed 的节点在内核启动时出现。这通常由引导加载程序使用安全随机数生成器实现)。 在运行时,我知道您可以检查两件事: /proc/kallsyms文件以查看虚拟内存地址空间中的符号地址。 lsmod查看虚拟内存地址空间中的内核模块地址。注意:在某些机器上,lsmod可能不会显示地址。在这种情况下,请尝试cat /proc/modules以 root 身份使用。如果不使用 root,地址可能全为零(出于安全原因清除)。~~感谢网友@crass的点评!~~ 1 和 2 都是类似的检查,但根据您的系统上可用的内容,您可能需要使用一个或另一个。 1. /proc/kallsyms 为此,只需查看 的前几行/proc/kallsyms: root@device:~# head -n 3 /proc/kallsyms ffffff8008080000 t _head ffffff8008080000 T _text ffffff8008080800 T do_undefinstr 请注意,例如,的地址_head是ffff ff80 0808 0000。 现在重新启动您的机器并再次检查。 root@device:~# head -n 3 /proc/kallsyms ffffff9fc8c80000 t _head ffffff9fc8c80000 T _text ffffff9fc8c80800 T do_undefinstr 请注意,例如,的地址_head是 now ffff ff9f c8c8 0000。 比较高级字节,发现ffffff80080 != 0xffffff9fc8c地址在重新启动时发生变化 => KASLR 已启用。 2. lsmod 与/proc/kallsyms上述方法类似:检查 lsmod,重新启动,再次检查 lsmod,然后比较地址。 root@device:~# lsmod iptable_filter 16384 0 - Live 0xffffffa1c49b9000 ip_tables 28672 1 iptable_filter, Live 0xffffffa1c49ad000 请注意,例如,的地址iptable_filter是ffff ffa1 c49b 9000。 现在重新启动您的机器并再次检查。 root@device:~# lsmod iptable_filter 16384 0 - Live 0xffffff2100716000 ip_tables 28672 1 iptable_filter, Live 0xffffff210070a000 请注意,例如,的地址iptable_filter是 now ffff ff21 0071 6000。 比较高级字节,发现ffffff2100716 != 0xffffffa1c49b9地址在重新启动时发生变化 => KASLR 已启用。 您可以迭代地进行这些测试以确定随机性的质量。重新启动后的地址有何不同?有明显的模式吗?KASLR 的安全优势与随机性或熵的质量成正比。 参考资料:使用 RANDOMIZE_BASE 的 KASL Linux 内核驱动程序数据库调试 Linux 内核 crass 2020-08-21T10:52:19+08:002020-08-21T10:52:19+08:00 我喜欢 @bhass1 在这里的回答,但是我不想重新启动计算机来进行测试。因此,如果您可以的话,您可以在虚拟机中执行基本相同的测试。我正在使用qemu和-kernel选项-initrd,这是我的操作方式: 首先,我通过查看来检查您正在运行的内核cat /proc/cmdline $ cat /proc/cmdline BOOT_IMAGE=/boot/vmlinuz-5.2.0-42-generic root=/dev/sda1 ro vt.handoff=7 所以我正在使用内核 vmlinuz-5.2.0-42-generic。 我们需要使用 initrd 运行内核,以便拥有一个能够检查地址的最小环境。我使用与我的内核对应的 initrd,以使模拟更真实,但这真的应该无关紧要。我还使用正在运行的内核的内核命令行,以使模拟尽可能接近正在运行的内核,并添加break=top到内核命令行以尽快进入 shell。 接下来,我运行qemu虚拟机: sudo qemu-system-x86_64 -m 1024 -kernel /boot/vmlinuz-5.2.0-42-generic \ -append "$(cat /proc/cmdline) break=top" -initrd /boot/initrd.img-5.2.0-42-generic 当我到达 shell 时,我得到了加载的模块地址: (initramfs) cat /proc/modules usbhid 57344 0 - Live 0xffffffffc0269000 hid 131072 1 usbhid, Live 0xffffffffc0248000 现在我将检查正在运行的系统以查看其中一个模块的模块地址是什么,看看它是否不同: sudo grep hid /proc/modules hid_generic 16384 0 - Live 0xffffffffc20ac000 usbhid 57344 0 - Live 0xffffffffc1a09000 hid 131072 2 hid_generic,usbhid, Live 0xffffffffc1c96000 所以我们可以在这里看到hid模块的地址是不同的(running:0xffffffffc1c96000和 virtual: 0xffffffffc0248000)。所以我的内核使用 kASLR 运行,即使它不在内核命令行上(现在在某些发行版中默认打开)。 您可以在另一个qemu实例中再次检查模块地址,并验证模块地址在每次 qemu 运行时都会发生变化。此外,您可以添加nokaslr到内核命令行(-append qemu选项)并运行qemu几次以验证模块地址没有改变。
回答问题:
检查你的内核命令行。(debian 8 上的示例)
来源:https ://wiki.ubuntu.com/Security/Features
我对之前的答案不满意,因为他们真的没有深入验证 KASLR 的全部内容 - 特别是未实现相同内核命令行界面的嵌入式或自定义内核(例如 ARM64 需要一个设备-tree 选择称为 kaslr-seed 的节点在内核启动时出现。这通常由引导加载程序使用安全随机数生成器实现)。
在运行时,我知道您可以检查两件事:
/proc/kallsyms
文件以查看虚拟内存地址空间中的符号地址。lsmod
查看虚拟内存地址空间中的内核模块地址。注意:在某些机器上,lsmod
可能不会显示地址。在这种情况下,请尝试cat /proc/modules
以 root 身份使用。如果不使用 root,地址可能全为零(出于安全原因清除)。~~感谢网友@crass的点评!~~1 和 2 都是类似的检查,但根据您的系统上可用的内容,您可能需要使用一个或另一个。
1. /proc/kallsyms
为此,只需查看 的前几行
/proc/kallsyms
:请注意,例如,的地址
_head
是ffff ff80 0808 0000
。现在重新启动您的机器并再次检查。
请注意,例如,的地址
_head
是 nowffff ff9f c8c8 0000
。比较高级字节,发现
ffffff80080 != 0xffffff9fc8c
地址在重新启动时发生变化 => KASLR 已启用。2. lsmod
与
/proc/kallsyms
上述方法类似:检查 lsmod,重新启动,再次检查 lsmod,然后比较地址。请注意,例如,的地址
iptable_filter
是ffff ffa1 c49b 9000
。现在重新启动您的机器并再次检查。
请注意,例如,的地址
iptable_filter
是 nowffff ff21 0071 6000
。比较高级字节,发现
ffffff2100716 != 0xffffffa1c49b9
地址在重新启动时发生变化 => KASLR 已启用。您可以迭代地进行这些测试以确定随机性的质量。重新启动后的地址有何不同?有明显的模式吗?KASLR 的安全优势与随机性或熵的质量成正比。
参考资料:使用 RANDOMIZE_BASE
的 KASL
Linux 内核驱动程序数据库调试 Linux 内核
我喜欢 @bhass1 在这里的回答,但是我不想重新启动计算机来进行测试。因此,如果您可以的话,您可以在虚拟机中执行基本相同的测试。我正在使用
qemu
和-kernel
选项-initrd
,这是我的操作方式:首先,我通过查看来检查您正在运行的内核
cat /proc/cmdline
所以我正在使用内核
vmlinuz-5.2.0-42-generic
。我们需要使用 initrd 运行内核,以便拥有一个能够检查地址的最小环境。我使用与我的内核对应的 initrd,以使模拟更真实,但这真的应该无关紧要。我还使用正在运行的内核的内核命令行,以使模拟尽可能接近正在运行的内核,并添加
break=top
到内核命令行以尽快进入 shell。接下来,我运行
qemu
虚拟机:当我到达 shell 时,我得到了加载的模块地址:
现在我将检查正在运行的系统以查看其中一个模块的模块地址是什么,看看它是否不同:
所以我们可以在这里看到hid模块的地址是不同的(running:
0xffffffffc1c96000
和 virtual:0xffffffffc0248000
)。所以我的内核使用 kASLR 运行,即使它不在内核命令行上(现在在某些发行版中默认打开)。您可以在另一个
qemu
实例中再次检查模块地址,并验证模块地址在每次 qemu 运行时都会发生变化。此外,您可以添加nokaslr
到内核命令行(-append
qemu
选项)并运行qemu
几次以验证模块地址没有改变。