8

How to detect if KASLR is enabled or disabled in runtime?

0
3

To answer the question:

$ 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
2

Check your kernel command line. (example on debian 8)

$ cat /proc/cmdline
BOOT_IMAGE=/vmlinuz-`uname -r` root=/dev/mapper/`hostname`-root ro quiet

kASLR is available starting with Ubuntu 14.10 but it is not enabled by default. Specify the "kaslr" option on the kernel command line to use kASLR.

Note: Enabling kASLR will disable the ability to enter hibernation mode.

source: https://wiki.ubuntu.com/Security/Features

1
  • Now kASLR is enabled by default on Ubuntu. So this check won't work. See @bhass1 or my answer for a better method of kASLR detection.
    – crass
    Aug 20 '20 at 18:11
1

I wasn't satisfied with the prior answers as they really don't get to the meat of validating what KASLR is all about - especially embedded or custom kernels that don't implement the same kernel command-line interface (e.g. ARM64 requires a device-tree chosen node called kaslr-seed to be present when the kernel boots. This is usually implemented by the bootloader using a secure random number generator).

At runtime I know of two things you can check:

  1. the /proc/kallsyms file to see the symbol addresses in virtual memory address space.
  2. lsmod to see the kernel module addresses in virtual memory address space. Note: On some machines, lsmod may not show the addresses. In that case, try using cat /proc/modules as root. If not using root, the addresses may be all zeros (cleared for security reasons). ~~Thanks to user @crass for the comment!~~

Both 1 & 2 are similar checks, but depending on what's available to you on your system, you might need to use one or the other.

1. /proc/kallsyms

To do so, simply look at the first few lines of /proc/kallsyms:

root@device:~# head -n 3 /proc/kallsyms
ffffff8008080000 t _head
ffffff8008080000 T _text
ffffff8008080800 T do_undefinstr

Note that the address for, e.g., _head is ffff ff80 0808 0000.

Now reboot your machine and check again.

root@device:~# head -n 3 /proc/kallsyms
ffffff9fc8c80000 t _head
ffffff9fc8c80000 T _text
ffffff9fc8c80800 T do_undefinstr

Note that the address for, e.g., _head is now ffff ff9f c8c8 0000.
Compare the high-level bytes and find that ffffff80080 != 0xffffff9fc8c so the addresses are being changed across reboots => KASLR is enabled.

2. lsmod

Similar to /proc/kallsyms method above: check lsmod, reboot, check lsmod again, and compare the addresses.

root@device:~# lsmod
iptable_filter 16384 0 - Live 0xffffffa1c49b9000
ip_tables 28672 1 iptable_filter, Live 0xffffffa1c49ad000

Note that the address for, e.g., iptable_filter is ffff ffa1 c49b 9000.

Now reboot your machine and check again.

root@device:~# lsmod
iptable_filter 16384 0 - Live 0xffffff2100716000
ip_tables 28672 1 iptable_filter, Live 0xffffff210070a000

Note that the address for, e.g., iptable_filter is now ffff ff21 0071 6000.
Compare the high-level bytes and find that ffffff2100716 != 0xffffffa1c49b9 so the addresses are being changed across reboots => KASLR is enabled.

You can do these tests iteratively to determine the quality of the randomness. How different are the addresses across reboots? Are there obvious patterns? The security benefit of KASLR is proportional to the quality of randomness, or entropy.

References:
Debugging Linux Kernels with KASL
Linux Kernel Driver Database for RANDOMIZE_BASE

1
  • 1
    On my machine lsmod does not show the module addresses. Using cat /proc/modules as root shows the addresses. If not using root, the addresses may be all zeros (cleared for security reasons).
    – crass
    Aug 20 '20 at 17:55
0

I like @bhass1's answer here, however I didn't want to have to reboot my computer to do the test. So you can perform essentially the same test but in a virtual machine, if that's available to you. I'm using qemu with the -kernel and -initrd options, and here's how I do it:

First, I check which kernel you're running by looking at cat /proc/cmdline

$ cat /proc/cmdline 
BOOT_IMAGE=/boot/vmlinuz-5.2.0-42-generic root=/dev/sda1 ro vt.handoff=7

So I'm using kernel vmlinuz-5.2.0-42-generic.

We need to run the kernel with an initrd just to have a minimal environment to be able to check the addresses. I use the initrd that corresponds to my kernel, to make the simulation more real, but it really should not matter. I also use the kernel commandline of the running kernel, to keep the simulation as close to the running kernel as possible, and add break=top to the kernel commandline to get to a shell as quickly as possible.

Next, I run the qemu virtual machine:

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

When I get to the shell I get the loaded module addresses:

(initramfs) cat /proc/modules
usbhid 57344 0 - Live 0xffffffffc0269000
hid 131072 1 usbhid, Live 0xffffffffc0248000

Now I'll check the running system to see what the module address is for one of the modules to see if its different:

sudo grep hid /proc/modules 
hid_generic 16384 0 - Live 0xffffffffc20ac000
usbhid 57344 0 - Live 0xffffffffc1a09000
hid 131072 2 hid_generic,usbhid, Live 0xffffffffc1c96000

So we can see here that the addresses for the hid module are different (running: 0xffffffffc1c96000 and virtual: 0xffffffffc0248000). So my kernel is running with kASLR, even though its not on the kernel command line (its turned on by default now on some distros).

You can check the module address again in another qemu instance and verify that the module address changes on every qemu run. Also, you can add nokaslr to the kernel commandline (the -append qemu option) and run qemu a couple times to verify that the module addresses do not change.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.