Kasld
Kernel Address Space Layout Derandomization (KASLD) - A collection of various techniques to infer the Linux kernel base virtual address as an unprivileged local user, for the purpose of bypassing Kernel Address Space Layout Randomization (KASLR).
Install / Use
/learn @bcoles/KasldREADME
Kernel Address Space Layout Derandomization (KASLD)
A collection of various techniques to infer the Linux kernel base virtual address as an unprivileged local user, for the purpose of bypassing Kernel Address Space Layout Randomization (KASLR).
Supports:
- x86 (i386+, amd64)
- ARM (armv6, armv7, armv8)
- MIPS (mipsbe, mipsel, mips64el)
- PowerPC (ppc, ppc64)
- RISC-V (riscv32, riscv64)
- LoongArch (loongarch64)
Usage
sudo apt install libc-dev make gcc binutils git
git clone https://github.com/bcoles/kasld
cd kasld
./kasld
KASLD is written in C and structured for easy re-use. Each file in the ./src
directory uses a different technique to retrieve or infer kernel addresses
and can be compiled individually.
./kasld is a lazy shell script wrapper which simply builds and executes each
of these files, offering a quick and easy method to check for address leaks
on a target system. This script requires make.
Refer to output.md for example output from various distros.
Building
A compiler which supports the _GNU_SOURCE macro is required due to
use of non-portable code (MAP_ANONYMOUS, getline(), popen(), ...).
KASLD components can be cross-compiled with make by specfying the approriate
compiler (CC) with LDFLAGS=-static. For example:
make CC=aarch64-linux-musl-gcc LDFLAGS=-static
Configuration
Common default kernel config options are defined in kasld.h. The default values should work on most systems, but may need to be tweaked for the target system - especially old kernels, embedded devices (ie, armv7), or systems with a non-default memory layout.
Leaked addresses may need to be bit masked off appropriately for the target kernel, depending on kernel alignment. Once bitmasked, the address may need to be adjusted based on text offset, although on x86_64 and arm64 (since 2020-04-15) the text offset is zero.
The configuration options should be fairly self-explanatory. Refer to the comment headers in kasld.h:
https://github.com/bcoles/kasld/blob/5ae25b8367ac511b1caac6c34666f4c76b3face6/src/include/kasld.h#L5-L25
Function Offsets
As the entire kernel code text is mapped with only the base address randomized, a single kernel pointer leak can be used to infer the location of the kernel virtual address space and offset of the kernel base address.
Offsets to useful kernel functions (commit_creds, prepare_kernel_cred,
native_write_cr4, etc) from the base address can be pre-calculated on other
systems with the same kernel - an easy task for publicly available kernels
(ie, distro kernels).
Offsets may also be retrieved from various file system locations (/proc/kallsyms,
vmlinux, System.map, etc) depending on file system permissions.
jonoberheide/ksymhunter automates
this process.
Function Granular KASLR (FG-KASLR)
Function Granular KASLR (aka "finer grained KASLR") patches for the 5.5.0-rc7 kernel were proposed in February 2020 (but have not been merged as of 2024-01-01).
This optional non-mainline mitigation "rearranges your kernel code at load time on a per-function level granularity" and can be enabled with the CONFIG_FG_KASLR flag.
FG-KASLR ensures the location of kernel and module functions are independently
randomized and no longer located at a constant offset from the kernel .text
base.
On systems which support FG-KASLR patches (x86_64 from 2020, arm64 from 2023), this makes calculating offsets to useful functions more difficult and renders kernel pointer leaks significantly less useful.
However, some regions of the kernel are not randomized (such as symbols before
__startup_secondary_64 on x86_64) and offsets remain consistent across reboots.
Additionally, FG-KASLR randomizes only kernel functions, leaving other useful
kernel data (such as modprobe_path
and core_pattern usermode helpers) unchanged at a static offset.
Addendum
KASLD serves as a non-exhaustive collection and reference for techniques useful in KASLR bypass; however, it is far from complete. There are many additional noteworthy techniques not included for various reasons.
System Logs
Kernel and system logs (dmesg / syslog) offer a wealth of information, including
kernel pointers and the layout of virtual and physical memory.
Several KASLD components search the kernel message ring buffer for kernel addresses.
The following KASLD components read from dmesg and /var/log/dmesg:
- dmesg_android_ion_snapshot.c
- dmesg_backtrace.c
- dmesg_check_for_initrd.c
- dmesg_driver_component_ops.c
- dmesg_early_init_dt_add_memory_arch.c
- dmesg_ex_handler_msr.c
- dmesg_fake_numa_init.c
- dmesg_free_area_init_node.c
- dmesg_free_reserved_area.c
- dmesg_kaslr-disabled.c
- dmesg_mem_init_kernel_layout.c
- dmesg_mmu_idmap.c
- dmesg_riscv_relocation.c
Historically, raw kernel pointers were frequently printed to the system log
without using the %pK printk format.
- https://github.com/torvalds/linux/search?p=1&q=%25pK&type=Commits
Bugs which trigger a kernel oops can be used to leak kernel pointers by reading
the associated backtrace from system logs (on systems with kernel.panic_on_oops = 0).
There are countless examples. A few simple examples are available in the extra directory:
Most modern distros ship with kernel.dmesg_restrict enabled by default to
prevent unprivileged users from accessing the kernel debug log. Similarly,
grsecurity hardened kernels support kernel.grsecurity.dmesg to prevent
unprivileged access.
System log files (ie, /var/log/syslog) are readable only by privileged users
on modern distros. On Debian/Ubuntu systems, users in the adm group also have
read permissions on various system log files in /var/log/:
$ ls -la /var/log/syslog /var/log/kern.log /var/log/dmesg
-rw-r----- 1 root adm 147726 Jan 8 01:43 /var/log/dmesg
-rw-r----- 1 syslog adm 230 Jan 15 00:00 /var/log/kern.log
-rw-r----- 1 syslog adm 8322 Jan 15 04:26 /var/log/syslog
Typically the first user created during installation of an Ubuntu system
is a member of the adm group and will have read access to these files.
Additionally, an initscript bug
present from 2017-2019 caused the /var/log/dmesg log file to be generated
with world-readable permissions (644) and may still be world-readable on
some systems.
DebugFS
Various areas of DebugFS
(/sys/kernel/debug/*) may disclose kernel pointers.
DebugFS is no longer readable by unprivileged users by default
since kernel version v3.7-rc1~174^2~57 on 2012-08-27.
This change pre-dates Linux KASLR by 2 years. However, DebugFS may still be readable in some non-default configurations.
Hardware Bugs
There are a plethora of viable hardware-related attacks which can be used to break KASLR, in particular timing side-channels and transient execution attacks.
KASLD includes the following hardware-related KASLR breaks:
The extra/check-hardware-vulnerabilities script performs rudimentary checks for several known hardware vulnerabilities, but does not implement these techniques.
Refer to the Hardware Side-Channels section for more information.
Weak Entropy
The kernel is loaded at an aligned memory address, usually between PAGE_SIZE (4096 KiB)
and 2MiB on modern systems (see KERNEL_ALIGN definitions in kasld.h.
This limits the number of possible kernel locations. For example, on x86_64 with
RANDOMIZE_BASE_MAX_OFFSET of 1GiB and 2MiB alignment, this limited the kernel load
address to 0x4000_0000 / 0x20_0000 = 512 possible locations.
Weaknesses in randomisation can decrease entropy, further limiting the possible kernel locations in memory and making the kernel easier to locate.
KASLR may be disabled if insufficient randomness is generated during boot
(for example, if get_kaslr_seed() fails on ARM64).
Refer to the Weak Entropy section for more information.
Additional References
Linux KASLR History and Implementation
- grsecurity - KASLR: An Exercise in Cargo Cult Security (grsecurity, 2013)
- An Info-Leak Resistant Kernel Randomization for Virtualized Systems | IEEE Journals & Magazine | IEEE Xplore (Fernando Vano-Garcia, Hector Marco-Gisbert, 2020)
- Kernel Address Space Layout Randomization (LWN.net)
- Kernel address space layout randomization [LWN.net]
- [Randomize kernel base address on boot [LWN.net]](https://lwn.net/Arti
