Patching Really Is Necessary

There are certain things in the tech world that go from Myth A to Myth B. The “ghz” myth is one of these things – a CPU’s clockspeed is measured in ghz and people used to use this as the go-to benchmark for determining performance and they’d ignore everything else. Now people go around saying that “ghz” doesn’t matter at all, which is equally stupid.

I see this with patching. Patching used to be the go-to practice for keeping an application secure. A program that was quick to patch was more secure and that was a way to measure security. Now people pretend that patching doesn’t matter – that if you use techniques like ASLR/DEP and you sandbox your applications you don’t need to worry. I see this all over.

This is incorrect. Patching is an invaluable layer in any security setup and I think the latest Chrome exploit shows why.

Google Chrome makes use of ASLR (very strong ASLR), DEP, and SEHOP. It has a fairly finely grained sandbox for each process on Windows. It’s a nice mixture of policy and technology.

And yet it’s still hackable. No matter how much policy you have it will have flaws. No matter how many memory techniques you implement there will be backdoors. Do those methods make things way more secure? Absolutely – there’s never been a single exploit in the wild that bypasses Chrome’s sandbox, even their relatively weak Flash sandbox.

But if you’re looking for security in depth you’d better patch because if you’re running Chrome 14 there’s been a thousand holes since then and it’s simply a matter of chaining the right ones together.

And this applies to everything. In Linux I’m running Chrome, which implements an incredibly secure sandbox, which is highly reinforced by the patches I make to my kernel. But if I’m running a super old unpatched version of Chrome all an attacker has to do is google for some exploits and chain it all together.

The cost of attacking a user is drastically lower when the exploit code is already available and there’s documentation on the vulnerability. By patching you force the attacker to find a new vulnerability, and in the case of a program like Chrome you actually end up forcing them to come up with a dozen vulnerabilities.

There is one simple reason why the entire threat landscape would have to change if Linux were suddenly the most popular OS. It’s not some magic memory technique or sandbox, it’s patching. All of my applications are always up to date on Linux, on Windows they aren’t. And hackers take huge advantage of that.

So do yourself a favor. Keep your system up to date.

Compile And Patch Your Own Secure Linux Kernel With PaX and Grsecurity

The reason why Linux and open source will always be more secure than Windows is because you can build advanced security right in. This guide’s going to show you how to do that. I’ll be explaining how to compile your own kernel with PaX and Grsecurity patches. (I’m actually compiling 3.3.6 for myself but this guide covers 3.2.18.)

First let’s explain a few things…

What Is A Kernel?

Well, if you don’t know what a kernel is this guide is probably a bit too advanced but far be it from me to turn you away. The kernel is essentially the core of the operating system. It is the lowest level of software on the system running with the highest rights. Linux runs on “The Linux Kernel” and that kernel is common to all Linux distributions.

What Is PaX?

PaX is a series of patches that can be applied to the Linux kernel. These patches provide functionality and improvements to built in features such as ASLR (Address Space Layout Randomization), which help mitigate and deter exploits.

PaX features can be daunting so for a per-feature explanation see this link. I highly suggest you take a look at these features and research both PaX and Grsecurity so you can fully understand what they provide.

What Is Grsecurity?

Grsecurity is another series of patches that can be applied to the Linux kernel. These patches will allow changes to policy, provide a tool for RBAC, and add new policies. Grsecurity and PaX are built to work together and reinforce one another.

Why Are We Doing This?

Well, to get the most secure system that you can possibly get you’re going to want to start compiling your own kernel. The kernel is, for various reasons, where security belongs (more on this in future posts.) Now, on a default install of some distro like, say, Ubuntu you’re fairly secure and the tools already provided can be used to really lock the system down (think AppArmor) but if you’re looking to secure your system against sophisticated and targeted attacks PAX and Grsecurity are the way to go.

Keep in mind that the settings I use are for my own system. A server would be able to use more settings because it wouldn’t have to worry about, for example, the sound working.

You will also need to do this for new updates from kernel.org in order to get the latest security patches, among other things. Not even Grsecurity will keep an unpatched system safe.

So, since we’re done with the intro…

Setting Up Our System

Before we even download source code we need to make sure we have everything necessary to actually compile and configure our kernel. Let’s start by installing some software: (I’ll assume sudo/root for this guide.)

# apt-get install patch bin86 kernel-package build-essential libncurses5-dev gcc-*-plugin-dev

That’s (hopefully) everything you need to compile, package, and configure the kernel. (You may need to install gcc and plugins.)

Now let’s set up a working folder and cd to it.

# mkdir /usr/src/linux/

# cd /usr/src/linux/

That’s it for now.

Downloading The Linux Kernel And Patches

In this example I’ll be using the Linux Kernel 3.2.18 (the same steps will work for any kernel, just change the patches) and the Grsecurity patch that goes along with it. I’m assuming you’re still in /usr/src/linux/.

# wget https://grsecurity.net/stable/grsecurity-2.9-3.2.18-201205301835.patch

# wget https://www.kernel.org/pub/linux/kernel/v3.0/linux-3.2.18.tar.bz2

Once the download has completed you can extract linux-3.2.18.tar.bz2 to ./linux-3.2.18.

Patching The Kernel

This part is fairly simple, move to your new linux-3.2.18 folder and patch.

# cd ./linux-3.2.18

# patch -p1 < /usr/src/linux/grsecurity-2.9-3.2.18-201205301835.patch

This should patch the kernel without any interaction necessary.

Configuring The Kernel

(note: I am taking screenshots of a 3.3.6 kernel with my own configuration, yours may vary. Once size does not fit all – do research!)

#make menuconfig

You’ll be brought to this screen:

Note: If you want to enable KERNEXEC you must go to Processor Features and disable Xen/Paravirtualization.

Navigate (arrow keys) to Security Options and hit ‘Enter’ and…:

Configuring Grsecurity:

As you can see there are many options here. You can use preconfigured options (Low, Medium, High) or, as I suggest, Custom.

The following settings are suggestions that work for me. They can make or break systems depending on usage. A server might need completely different settings, for example. You’ll probably be compiling a few kernels just to see what breaks when.

Memory Protections:

[*] Deny reading/writing to /dev/kmem, /dev/mem, and /dev/port
[  ] Disable privileged I/O
[*] Harden ASLR against information leaks and entropy reduction
[*] Deter exploit bruteforcing
[*] Harden module auto-loading
[*] Hide kernel symbols
[*] Active kernel exploit response

Role Based Access Control (RBAC): I’ll post later about configuring RBAC.

[  ] Disable RBAC system
[*] Hide kernel processes
(3) Maximum tries before password lockout
(30) Time to wait after max password tries, in seconds

Filesystem Protections:

[*] Proc restrictions
[*] Restrict /proc to user only
[*] Additional restrictions
[*] Linking restrictions
[*] FIFO restrictions
[  ] Sysfs/debugfs restriction     -Breaks Sound on Ubuntu
[  ] Runtime read-only mount protection   -For servers, not users.
[*] Chroot jail restrictions
[*] Deny mounts
[*] Deny double-chroots

[*] Deny pivot_root in chroot

[*] Enforce chdir(“/”) on all chroots
[*] Deny (f)chmod +s
[*] Deny fchdir out of chroot
[*] Deny mknod
[*] Deny shmat() out of chroot
[*] Deny access to abstract AF_UNIX sockets out of chroot
[*] Protect outside processes
[*] Restrict priority changes
[*] Deny sysctl writes

[*] Capability restrictions

Kernel Auditing:

Your choice, this is more useful for servers. As a user I don’t need any of this.

Executable Protections:

[*] Dmesg(8) restriction
[*] Deter ptrace-based process snooping
[*] Require read access to ptrace sensitive binaries
[*] Enforce consistent multithreaded privileges
[*] Trusted Path Execution (TPE)
[*] Partially restrict all non-root users -This is one option that I use. It may break things and it’s not a critical feature so you may consider removing it.

Network Protections:

[*] Larger entropy pools
[*] TCP/UDP blackhole and LAST_ACK DoS prevention
[  ] Socket restrictions

SysCtl Support:

[  ] Sysctl support
[  ] Turn on features by default

Configuring PAX:

As with Grsecurity we’re presented with quite a few options. PAX settings can very easily break things so my settings will likely vary from what your settings could be. I will note specific areas where there are known conflicts.

For details on PaX features see this link.

PaX Control:

[  ] Support soft mode By leaving this off we have PaX system wide.
[  ] Use legacy ELF header marking
[  ] Use ELF program header marking
[  ] Use filesystem extended attributes marking

Non-Executable Pages:

[*] Enforce non-executable pages
[*] Paging based non-executable pages
[*] Emulate trampolines
[*] Restrict mprotect() This will break X.
[  ] Use legacy/compat protection demoting (read help)
[  ] Allow ELF text relocations (read help)

[*] Enforce non-executable kernel pages (Requires  you disabled Xen)
Return Address Instrumentation Method (bts) —>

Address Space Layout Randomization:

[*] Address Space Layout Randomization
[*] Randomize kernel stack base
[*] Randomize user stack base
[*] Randomize mmap() base

Miscellaneous Hardening Features: (Note: Users of ATI SPUs must use my settings here. Users with other GPUs should enable all ** settings.)

[*] Sanitize all freed memory
[*] Sanitize kernel stack
[*] Prevent various kernel object reference counter overflows  **
[*] Harden heap object copies between kernel and userland  **
[*] Prevent various integer overflows in function size parameters

**As of version 12.8 the closed source ATI FGLRX drivers are compatible with the above. Earlier versions will NOT work.

Other Security Settings

Exit your PaX options and go back to the security settings.

Set ” Low address space for LSM to protect from user allocation” to 65536 or 32768:

This is the portion of low virtual memory which should be protected
from userspace allocation. Keeping a user from writing to low pages
can help reduce the impact of kernel NULL pointer bugs.

For most ia64, ppc64 and x86 users with lots of address space
a value of 65536 is reasonable and should cause no problems.
On arm and other archs it should not be higher than 32768.
Programs which use vm86 functionality or have some need to map
this low address space will need the permission specific to the
systems running LSM.

Time To Compile And Install

(Note: You may want to see the last section ‘Other Tips’ before you compile.)

# make-kpkg clean

# make-kpkg --initrd --append-to-version "grsec1.0" kernel_image

The above command might give you an error in which case you’ll need to type it out. It’s a wordpress issue where it combines the –‘s.

Compiling will take a while. Probably a half hour, potentially multiple hours depending on the hardware. When you’re done there will be a package in /usr/src/linux.

# cd /usr/src/linux

# dpkg -i ./<name.of.deb>

Reboot into the new kernel and that’s it.

It’s a lot of work to set it up but it should only take you a few minutes after the first time. Compiling is what takes the longest but it can be done in the background.

If something breaks just boot into the last kernel you used. Simple.

Other Tips

Since you’re taking the time to compile this thing you may as well get the most out of it. I suggest you go through the settings and disable any drivers not related/ enable or disable features.

You should also open /usr/src/linux/linux-3.2.18/makefile and find the line:

# Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments

And have the following line as: (add the -march=native -pipe -mtune=native)

KBUILD_CPPFLAGS += $(KCPPFLAGS) -march=native -pipe -mtune=native

pipe will speed up compile time significantly for systems with lots of RAM. march=native will optimize the kernel for your specific CPU. Don’t use -march=native if you are compiling for another system with a different CPU (same for mtune).

Take the time to disable drivers that you won’t use. It’ll speed up compile time and produce a smaller kernel.

Highlights

The highlights of this new kernel are:

1) Improved ASLR

2) RBAC

3) Hardened Chroots (if you use Chromium or Google Chrome the sandbox makes use of Chroots so you’ve just made it more secure.)

4) Exploit bruteforcing is much harder

5) A generally more secure system with stricter policies and checks

6) Optimized kernel if you followed the “notes.”

This was a long post so if I’ve left anything out or misrepresented something leave a comment and let me know. RBAC is worth its own full post so I’ll get to that later (setting it up on any user-oriented OS is difficult.) For now you can see this wiki page to learn how to set RBAC up, but it’s not so simple.

Sources:

http://www.howtoforge.com/hardening-the-linux-kernel-with-grsecurity-debian

http://www.gentoo.org/proj/en/hardened/pax-quickstart.xml

https://en.wikibooks.org/wiki/Grsecurity/Print_version