0% found this document useful (0 votes)
7 views

Linux Kernel Exploitation

The document outlines methods for exploiting the Linux kernel to achieve privilege escalation, detailing the setup of the environment, kernel memory corruption techniques, and various methods to gain root privileges. It discusses common vulnerabilities, kernel mitigations, and strategies to bypass these mitigations, including the use of arbitrary code execution and address writes. Additionally, it emphasizes the importance of kernel hardening and the potential for leveraging specific kernel structures during exploitation.

Uploaded by

bảo ngô
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

Linux Kernel Exploitation

The document outlines methods for exploiting the Linux kernel to achieve privilege escalation, detailing the setup of the environment, kernel memory corruption techniques, and various methods to gain root privileges. It discusses common vulnerabilities, kernel mitigations, and strategies to bypass these mitigations, including the use of arbitrary code execution and address writes. Additionally, it emphasizes the importance of kernel hardening and the potential for leveraging specific kernel structures during exploitation.

Uploaded by

bảo ngô
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 83

Exploiting the Linux Kernel for

Privilege Escalation
Pietro Borrello
Who am I

Ph.D. Student at Sapienza University of Rome


Working on:
• Microarchitectural Attacks
• Side Channels
• Program Analysis
• Fuzzing

TRX
Our Journey
1. Setting up the environment

2. First Steps in Kernel Memory


Corruption

3. Gaining Root Privileges

4. Linux Kernel Mitigations

5. Bypassing Linux Kernel


Mitigations
Setting Up the
Environment
1 2 3
Fetch & Build Run the Kernel Debug the
the Linux Kernel in qemu kernel
Fetch & Build the Linux Kernel

1. Get in touch with Kernel source code on bootlin


Fetch & Build the Linux Kernel

1. Get in touch with Kernel source code on bootlin


2. Use buildroot to configure and build the kernel
Fetch & Build the Linux Kernel

1. Get in touch with Kernel source code on bootlin


2. Use buildroot to configure and build the kernel
3. Collect the output files
Debug the Kernel

see:

• https://github.com/hugsy/gef

• https://github.com/martinradev/gdb-pt-dump
First Steps in
Kernel Memory
Corruption
1 2 3
Kernel Attack Common Bugs Arbitrary Code
Surface Execution: is it
necessary?
Linux Kernel Attack Surface

OEM
Customizations Device
Loadable Drivers
Kernel
Modules

syscall
interface
Coprocessors
Common bugs

• Read out of bounds


• Writes out of bounds
• Type confusions
• Use After Free
• Uninitialized memory
• Integer Overflows
Common bugs

• Read out of bounds


• Writes out of bounds
• Type confusions
• Use After Free
• Uninitialized memory
• Integer Overflows
Common More Interesting bugs

• Direct userspace pointer usage


• TOCTOUs / Double Fetches
• Race Conditions
• Improper Permissions
Direct userspace pointer usage

The kernel has to deal with pointers from userspace that are untrusted
What if ptr or ptr->data points to kernel space?
Direct userspace pointer usage

The kernel has to deal with pointers from userspace that are untrusted
What if ptr or ptr->data points to kernel space?
-> Add check to verify
Double Fetches

Let’s assume you need to copy content from userspace


Double Fetches
Let’s assume you need to copy content from userspace
Ok maybe this is secure…
Double Fetches
Let’s assume you need to copy content from userspace
Arbitrary Code Execution: is it
necessary?

ring0
FREE

root

user
Gaining Root
Privileges
1 2 3
The ACE way The AAW way The 1337 way
ACE: Arbitrary Code Execution

AAW: Arbitrary Address Write


AAR: Arbitrary Address Read

1337: 1337
The ACE way - ret2usr

Let’s start easy:


• controlled function pointer
• no kernel mitigations in place

…but what should we do?


The ACE way - ret2usr
The goal is to achieve root privileges in the system.
• The kernel holds privilege information in the task_struct
The ACE way - ret2usr
The goal is to achieve root privileges in the system.
• The kernel holds credentials information in the task_struct
• uses functions to update them
The ACE way - ret2usr
The goal is to achieve root privileges in the system.
• The kernel holds credentials information in the task_struct
• uses functions to update them
• and to generate new ones
The ACE way - ret2usr

1. Leverage the same kernel functions to change credentials to root ones.


• how to find the location of these functions?
/proc/kallsyms: list of the addresses of all symbols loaded in the kernel
• without KASLR: get the address directly

• with KASLR: get the offset w.r.t. kernel .text base


The ACE way - ret2usr

1. Leverage the same kernel functions to change credentials to root ones


The ACE way - ret2usr

1. Leverage the same kernel functions to change credentials to root ones

Now we are root! But how to safely return to userspace to spawn a shell?
The ACE way - ret2usr

1. Leverage the same kernel functions to change credentials to root ones


2. Return to userspace by restoring the right context
The ACE way - ret2usr

1. Leverage the same kernel functions to change credentials to root ones


2. Return to userspace by restoring the right context
3. Enjoy root
The AAW way

What if we don’t have kernel arbitrary code execution?


Let’s assume an Arbitrary Address Write primitive
The AAW way

What if we don’t have kernel arbitrary code execution?


Let’s assume an Arbitrary Address Write primitive

… but what and where to write?


The AAW way
We already know some interesting pointers to overwrite…
commit_creds just overwrites them
The AAW way
We already know some interesting pointers to overwrite…
commit_creds just overwrites them
The AAW way

Overwrite real_cred and cred in current_task with root credentials


The AAW way

Overwrite real_cred and cred in current_task with root credentials


A few details:
• how to find current_task
• how to generate/find root credentials
The AAW way

• how to find current_task


The AAW way

• how to find current_task


• how to generate/find root credentials
there already exists init_cred as a global variable in the kernel data
The AAW way

1. Overwrite current_task ->real_cred and current_task ->cred with init_cred


2. Enjoy root
The 1337 way - modprobe_path

modprobe is used to add a loadable kernel module to the Linux kernel

• the kernel can automatically load


modules executing modprobe as root
when needed. e.g., using different
network protocols, unknown files
• the path to modprobe binary is stored
in the modprobe_path global var
• modprobe_path is in a RW kernel
page by default
The 1337 way - modprobe_path

1. overwrite modprobe_path using a kernel AAW primitive with the path


of a binary that we control
2. trigger modprobe_path execution, .e.g., executing unknown binary format
3. Enjoy root
Linux Kernel
Mitigations
1 2 3
Prevent KASLR & Friends Kernel Hardening
code/data
hijacking
Prevent hijacking - SMEP

We saw how controlling a code pointer may just allow us to jump back to
userspace, and execute arbitrary code at ring0
Supervisor Mode Execution Protection:
• prevent executing from userland pages when in kernel mode
• controlled by 20th bit of cr4

jmp

ring0 ring3
kernel userspace
Prevent hijacking - SMEP

• controlled by 20th bit of cr4


Can we bypass it?
1. jump to native_write_cr4 and reset the bit
2. jump to userspace

jmp

ring0 ring3
kernel userspace
Prevent hijacking - SMEP

• controlled by 20th bit of cr4


Can we bypass it?
1. jump to native_write_cr4 and reset the bit
the kernel explicitly prevents writes to sensitive cr4 bits

jmp

ring0 ring3
kernel userspace
Prevent hijacking - SMEP

Can we disable it? NO


What if we ROP on kernel code?
1. find pivoting gadget in kernel code mov rsp, 0x1337000; ret;

2. pivot to ropchain from user data

prepare_kernel_cred(0);
commit_creds();
swapgs; ret;
iret;
Prevent hijacking - SMAP

We saw how controlling a pointer may allow us to ROP from userspace, and
execute arbitrary code at ring0
Supervisor Mode Access Prevention:
• prevent accessing data from userland pages when in kernel mode
• controlled by 21st bit of cr4 (pinned bit)

access

ring0 ring3
kernel userspace
Prevent hijacking - SMAP

Supervisor Mode Access Prevention:


• prevent accessing data from userland pages when in kernel mode
Wait… how do you pass data to the kernel then?
syscall: write(1, buffer, 0x100);

access

ring0 ring3
kernel userspace
Prevent hijacking - SMAP

Supervisor Mode Access Prevention:


• prevent accessing data from userland pages when in kernel mode
• Fast way to disable SMAP through kernel EFLAGS.AC
Prevent hijacking - KPTI

Kernel Page Table Isolation


prevent attacks on the shared user/kernel address space, with two sets of
pages:
1. userspace page tables with minimal amount of kernel pages
2. kernel page tables with user pages mapped as NX
Mitigation with an prepare_kernel_cred(0); prepare_kernel_cred(0);
effect similar to
SMEP for exploitation commit_creds(); commit_creds();
swapgs; ret; KPTI trampoline
iret;
KASLR

Kernel Address Space Layout Randomization


Randomize different sections of the kernel independently:
• text segment
• modules
• direct physical map
• …
Lower entropy than userspace ASLR, but here a crash means system crash
-> need to leak KASLR addresses using an AAR primitive/side-channels
FG-KASLR

Function Granular Kernel Address Space Layout Randomization


Random shuffle of kernel code on a per-function granularity at every boot
-> a single leak is no more sufficient to derandomize the entire kernel
address space

prepare_kernel_cred commit_creds do_mmap


commit_creds do_mmap prepare_kernel_cred
copy_from_user prepare_kernel_cred copy_from_user
do_mmap copy_from_user commit_creds
FG-KASLR

However…
Certain regions of the kernel cannot be randomized.
• initial _text region
• KPTI trampoline
• kernel symbol table ksymtab
FG-KASLR
Wait what? ksymtab
It is needed to export symbols so that they could be used by kernel modules
FG-KASLR
Wait what? ksymtab
It is needed to export symbols so that they could be used by kernel modules
FG-KASLR
Wait what? ksymtab
It is needed to export symbols so that they could be used by kernel modules

Bypass:
1. Leak _text image base address using an AAR
2. Compute the address of _ ksymtab_<func> from _ text base
3. Leak the value_offset entry from _ ksymtab_<func>
Structure Layout Randomization

Usually fields in a C structure are laid out by the compiler in order of their
declaration.

field1
field2
field3
field4
Structure Layout Randomization

Usually fields in a C structure are laid out by the compiler in order of their
declaration.
Randomly rearrange fields at compilation time, using a random seed.

field4
field1
field3
field2
Structure Layout Randomization
task_struct may have their layout randomized. How can we overwrite creds?
Structure Layout Randomization
task_struct may have their layout randomized. How can we overwrite creds?
-> need to reverse engineer the vmlinux binary to recover the field offsets
Kernel Hardening

Build the kernel with different security options to harden its attack surface
• Attack surface reduction
• Enable security features
Kernel Hardening

Build the kernel with different security options to harden its attack surface
• Attack surface reduction
• INIT_STACK_ALL: initialize all stack variables
• SECURITY_DMESG_RESTRICT: avoid leaks of kernel pointers in dmesg
• PANIC_ON_OOPS: panic on kernel oops
• MODULE_SIG_FORCE: force modules to be signed
• BPF_JIT=n: disable BPF jitter
Kernel Hardening

Build the kernel with different security options to harden its attack surface
• Enable security features
• STACKPROTECTOR_STRONG: improve stack canary coverage
• DEBUG_CREDENTIALS: keep track of pointers to cred struct
• HARDENED_USERCOPY: validate memory regions of user pointers
• SLAB_FREELIST_RANDOM/HARDENED: randomize/fortify allocators
• RANDOMIZE_KSTACK_OFFSET: randomize stack offset at each syscall
Kernel Hardening - USERMODEHELPER

The modprobe_path technique is so powerful that it has his own mitigation


CONFIG_STATIC_USERMODEHELPER:
Force all usermode helper calls through a single binary
Kernel Hardening - SELINUX

SELinux defines access controls for every resource in a system.


• mandatory access control decisions made based on security policies
• every process and system resource has a SELinux context
• whitelist of the possible interactions between the SELinux contexts
Bypassing
Linux Kernel
Mitigations
1 2
kROP on Leveraging
physmap Useful Structures
kROP - SMAP

SMAP prevents accessing data from userland pages when in kernel mode
Is Kernel ropping dead then?

access

ring0 ring3
kernel userspace
kROP - SMAP

SMAP prevents accessing data from userland pages when in kernel mode
Is Kernel ropping dead then?
• directly place the chain in kernel land if you have control over some data
• indirectly place the chain in kernel land

access

ring0 ring3
kernel userspace
kROP - SMAP

SMAP prevents accessing data from userland pages when in kernel mode
Is Kernel ropping dead then?
• directly place the chain in kernel land if you have control over some data
• indirectly place the chain in kernel land
T LY?
IR EC
IND
access

ring0 ring3
kernel userspace
kROP - physmap

The kernel has a view of the whole physical memory mapped in physmap
-> This means userspace pages are aliased in kernel memory!
kROP - physmap

The kernel has a view of the whole physical memory mapped in physmap
-> This means userspace pages are aliased in kernel memory!

access

ring0 ring3
kernel userspace

userspace
alias
kROP - physmap

The kernel has a view of the whole physical memory mapped in physmap
-> This means userspace pages are aliased in kernel memory!
• originally the mapping was RWX! access
(now fixed)
ring0 ring3
• SMAP bypass: kernel userspace
1. spray ropchain pages in userspace
2. locate the page in physmap using AAR
3. ROP to physmap userspace
alias
Leveraging useful structures

During kernel exploitation you have a lot of control on the objects that are
allocated as consequence of actions performed in userspace.
Often you have bugs that give you limited capabilities during exploitation
and want to:
• promote an out-of-bound read/write to AAR/W
• promote AAR/W to RIP control
• RIP control to ACE

Let’s look at some useful structures the kernel uses and that we can leverage
Useful structures - tty_struct

Created in kernel heap for each open(“/dev/ptmx”) syscall


-> useful for leaks and RIP control

Leak kernel heap address

Leak kernel base + RIP control


Useful structures - msg_msg

Created in kernel heap for each msgsnd() syscall


-> Variable in size + up to 4048 bytes of arbitrary data

Leak kernel heap address


Copy of user data
Useful functions - userfaultfd

userfaultfd lets you handle page faults on userspace, by defining a handler


that will be called to manage virtual memory.

But why is it useful?


-> we can make the kernel hang on user data access, while waiting for the
handler execution
-> deterministically enlarge race condition windows
Useful functions - setxattr

For each setxattr syscall the kernel allocates a buffer in heap with data
completely controlled by userspace. Couple with userfaultfd to avoid dealloc

Copy of user data in


kernel heap
Takeaway

With strong enough exploitation primitives, any mitigation can be bypassed.


Are we doomed?
• coverage guided kernel fuzzing to find bugs:
https://github.com/google/syzkaller
• secure programming to avoid bugs:
https://github.com/Rust-for-Linux
Thanks
Do you have any questions?
[email protected]
@borrello_pietro

CREDITS: This presentation template was created by


Slidesgo, including icons by Flaticon, infographics &
images by Freepik
Resources (1)

● GET IN THE MOOD: https://www.youtube.com/watch?v=G1IbRujko-A

● https://github.com/smallkirby/kernelpwn

● https://github.com/pr0cf5/kernel-exploit-practice

● https://lkmidas.github.io/posts/20210123-linux-kernel-pwn-part-1/

● https://lkmidas.github.io/posts/20210223-linux-kernel-pwn-modprobe/

● https://devilinside.me/blogs/small-steps-kernel-exploitation

● https://duasynt.com/blog/linux-kernel-heap-spray
Resources (2)

● https://ptr-yudai.hatenablog.com/entry/2020/03/16/165628

● https://googleprojectzero.blogspot.com/2020/02/mitigations-are-attack-surface-too.html

● https://blog.lexfo.fr/cve-2017-11176-linux-kernel-exploitation-part1.html

● https://meowmeowxw.gitlab.io/ctf/3k-2021-klibrary/

● https://google.github.io/security-research/pocs/linux/cve-2021-22555/writeup.html

● https://akulpillai.com/posts/learning_through_challenges1/

● https://github.com/R3x/How2Kernel
Resources (3)

● https://pr0cf5.github.io/ctf/2020/03/09/the-plight-of-tty-in-the-linux-kernel.html

● https://www.graplsecurity.com/post/kernel-pwning-with-ebpf-a-love-story

You might also like