5

Why hide kernel symbols?

Quote

Anyone with basic knowledge of kernel exploitation knows how important information gathering is to reliable exploitation. This protection hides the kernel symbols from various places that an attacker could use during information gathering in pre-exploitation stage. ... This option also prevents leaking of kernel addresses through several /proc entries.

Bug Classes/Kernel pointer leak

Some places are obvious. /proc/kallsyms can be constrained through sysctl kernel.kptr_restrict=2. Access to folder /boot can be restricted through linux file permissions to root only and with apparmor even be hidden from root. AppArmor FullSystemPolicy (apparmor-profile-everything) Also other places such as /lib/modules, system.map, and the kernel source directory.

For the sake of asking a very specific question, please ignore other places where kernel symbols might leak. If want to enumerate them, please ask your own question, wait until I ask or add a comment.

My very specific question is around the following Quote:

The kernel [...] is not precompiled by some distribution

This is because kernel symbols can be extracted from the kernel image. There are Open Source tools for that.

(That quote is about grsecurity but I am asking about non-grsecurity, i.e. the regular kernel from kernel.org here.)

Kernel images from public repositories such as packages.debian.org are well known by attackers. Attackers could simply hardcode the symbols addresses and thereby counter effort such as kernel.kptr_restrict=2.

To prevent kernel pointer leaks, the kernel image cannot be in a public known state. It needs to be unique, private as far as I understand. One needs to compile the kernel oneself.

Reproducible builds are an amazing effort of increasing the security for everyone. However, in this case reproducible builds would result in again ending up with a kernel with symbol addresses well predictable by attackers because the Debian linux kernel is already reproducible, mostly reproducible or in future fully reproducible (I didn't follow up where development is regarding that).

How to hide kernel symbols of the linux kernel image (vmlinux) from an attacker? How to make sure my kernel has unique kernel symbols? Is there a kernel boot parameter for that? Or is it possible to somehow supply the kernel with a random file so it can randomize its symbols? Or is there some way to recompile the kernel in a way it would have unique symbol addresses?

adrelanos
  • 680
  • 7
  • 21
  • I'm not sure what you are asking or maybe your question is too broad. In the title you ask about hiding symbols while in the body you mostly ask about hiding addresses and randomizing addresses. And then you claim to specifically ask about something with grsecurity but immediately you seem to try to generalize away from this again. – Steffen Ullrich Dec 10 '19 at 08:18
  • 1
    "I'm not sure what you are asking" - I am asking "what do I have to hide kernel addresses"? Randomization of kernel addresses might be one way to hide kernel addresses. Recompilation of the kernel might result in randomization and thereby hiding the kernel addresses. I've edited that quote about grsecurity to make my question unspecific to grsecurity. I am really not asking about grsecurity here. My goal here is to reach the same with a kernel form kernel.org. Edited my question to clarify. – adrelanos Dec 10 '19 at 08:33
  • https://forums.whonix.org/t/hide-kernel-symbols-for-better-security-vs-reproducible-builds/8599 – adrelanos Dec 20 '19 at 12:25
  • @SteffenUllrich Kernel symbol information refers to the address of kernel symbols. – forest Dec 20 '19 at 23:10

1 Answers1

2

The layout of a distribution precompiled kernel is public. KASLR attempts to change the base offset of the kernel, changing all the addresses by a secret offset. Unfortunately, leaking even a single symbol will allow the rest to be calculated. Since KASLR is not nearly as secure as it is made out to be, this is a problem. The danger of KASLR bypass through infoleaks can be only slightly reduced by setting the sysctl kernel.dmesg_restrict=1 to mitigate leaks from printk(). Even still, KASLR is such a poor security feature that you can't use it to reliably hide this information from local attackers.

Compiling a kernel manually will ensure that you will be using unique symbol offsets. It is necessary to set the sysctl kernel.kptr_restrict=2 and restrict access to the kernel image itself as well as related files like the map and loadable modules. You can make attacks based on knowledge of kernel structure a bit harder if you use the RANDSTRUCT plugin from grsecurity, now in upstream.

Glorfindel
  • 2,235
  • 6
  • 18
  • 30
forest
  • 64,616
  • 20
  • 206
  • 257