ENPM809V
Linux Kernel Hijacking Part 2
What we will cover
- Rooting/Privilege Escalation
- Review of Kernel Memory Management
- Intro to Attacking Kernel Memory
- Truly Escaping Seccomp
Rooting/Privilege Escalation
What does it mean?
- It means we are at a privileged level that gives us access to most of the system.
- Generally this has meant being UID 0 (the root UID)
- This has expanded greatly in modern systems.
- Virtualization, Hardware secure Enclaves
- Sandboxing
- Other capabilities
What could this look like?
- Become root for all ID types
- Grant all capabilities
- Break out of sandboxing
- Disable SELinux
What could this look like?
- Become root for all ID types
- Grant all capabilities
- Break out of sandboxing
- Disable SELinux
How this look (high level)
- We need to write our exploit somehow
- Recall copy_to_user/copy_from_user
- Find a task_struct that you can control
- Find the cred structure
- Modify the IDs so we are a higher privileged user.
Why?
-
task_struct tracks everything about the running process
- Includes user, privileges, and a lot of other data
- Will show how to get it at the end of today
- One of those is the cred structure which has information about the user and their privileges
- This structure is immutable
How to modify the cred
-
commit_creds(struct cred*)
replaces the currently active credentials - We can use the kernel to help us make a fresh one
struct cred *prepare_kernel_cred(struct task_struct *referenced_task_struct)
- If we pass NULL for referenced_task_struct, it'll give us a cred struct with root access and full privileges!
What would this end up looking like to get root?
commit_creds(prepare_kernel_cred(0))
Issues
- Where does commit_creds and prepare_kernel_creds even exist (might need to find the address for them)
- Without KASLR, this is easy and predictable, otherwise..
- /proc/kallsyms can help (if we can see it)
- If enabled, GDB can help
Kernel Memory Management
Computer Architecture
Process Architecture
Every process contains virtual memory which includes:
- The binary
- Heap/Stack
- Memory Mappings
- Kernel Code in the upper half of Kernel Memory
Virtual vs. Physical Memory
Physical Memory 0x0000000000 - 0xffffffff
Physical Memory is all memory for the entire system and its exact location.
Virtual Memory is an allocated chunk of memory on the physical system for the process. It has its own addressing.
Virtual vs. Physical Memory
Physical Memory 0x0000000000 - 0xffffffff
Physical Memory is all memory for the entire system and its exact location.
Virtual Memory is an allocated chunk of memory on the physical system for the process. It has its own addressing.
Page Table & Page Directory
- Virtual Memory is allocated via pages on physical memory.
- Page Table tracks non-contiguous virtual memory. This allows processes to have multiple pages in non-contiguous spaces. Support up to 512 entries
- Page Directories Page Tables, are page tables that track locations of other pages.
- Recall that this can be multiple levels deep
Page Table & Page Directory
- Virtual Memory is allocated via pages on physical memory.
- Page Table tracks non-contiguous virtual memory. This allows processes to have multiple pages in non-contiguous spaces. Support up to 512 entries
- Page Directories Page Tables, are page tables that track locations of other pages.
- Recall that this can be multiple levels deep
Addressing
From pwn.college
Controlling Top Page Table
- In intel, top page table is also known as PLM4
- Location stored in cr3 register
- Only accessible at ring 0
-
Other Control Registers exist, setting processor options, and lots of other craziness.
For the interested: https://wiki.osdev.org/CPU_Registers_x86
What if I want to access physical memory directly?
How to do it
- Old Linux Kernels /dev/mem
- Now, you have to do it from the kernel!
- Mapped to kernel virtual address space
-
Useful Macros:
- phys_to_virt() converts a physical address into a (kernel) virtual address.
- virt_to_phys() converts a (kernel) virtual address into a physical address.
Intro to Attacking Kernel Memory
Recall The Task Struct
- Lots of different members for all different purposes.
- We were just looking at it for credentials
- There is the
mm_struct
within it called mm- If the process is running as an annonymous process, might be located at
active_mm
- If the process is running as an annonymous process, might be located at
Recall The Task Struct
-
mm or active_mm has a member called mmap
- Ordered double linked list/rb tree containing information about the underlying memory
- Can be operated on via the vm_ops table/member
What does this all mean?
- Bugs in the way operations (including vm_ops/file_operations) handle mmap can lead to exploits
Attacking the Allocator
- To attack SLUB you must have a deep understanding of it.
- One basic way that you can attack it though is through freelist of the slab's object.
- The freelist is the list of free points from the allocator
What can happen?
- Control over the freelist can cause an "allocation" to happen in attacker controlled memory
- Gives control of the contents to the attacker
- Since similar caches can be combined into one, other systems using their own cache can be co-located with other objects.
- We will go into more depth with this next week
Truly Escaping Seccomp
Recall Seccomp
- Seccomp restricts system calls that can be made by a process
- If correctly configured, attacker can't do anything useful
- Incorrectly configured can lead to many exploits...
Recall The Cred Struct
- We just talked about it, what does it contain?
- There is also the thread_struct as well.
- Contains a field called flags: a bit field that many bits including a bit named TIF_SECCOMP.
the task struct: https://elixir.bootlin.com/linux/latest/source/include/linux/sched.h#L632
the flags: https://elixir.bootlin.com/linux/latest/source/arch/x86/include/asm/thread_info.h#L85
Lets Dig In a little
- https://elixir.bootlin.com/linux/latest/source/arch/x86/entry/vsyscall/vsyscall_64.c#L217 - Calling secure_computing via the vsyscall
- https://elixir.bootlin.com/linux/latest/source/include/linux/seccomp.h#L43 - The actual function call
We can attack it!
- If we set
current_task_struct->thread_info.flags &= ~(1 << TIF_SECCOMP),
we can break out of seccomp! - How can we get the current_task structure?
Get the current task
- The gs segment register holds the currently running process' task_struct.
- Shorthand macro to this called current
To successfully attack:
-
What do we need to do:
-
Access current->thread_info.flags via the gs register
-
Clear the TIF_SECCOMP flag.
-
Profit
-
-
Caveat: our children will still be seccomped (that's stored elsewhere).
Kernel Hijacking Part 2
By Ragnar Security
Kernel Hijacking Part 2
This slide deck continues to cover Linux Kernel Hacking and System Hijacking concepts.
- 73