Search This Blog

Showing posts with label Kernel. Show all posts
Showing posts with label Kernel. Show all posts

Saturday, February 3, 2024

Kernel pwn basics for CTF - GETTING MY HANDS DIRTY (Part 1) -- [hxpctf 2020 'kernel-rop']

For a while, i've been keen to try and learn about kernel pwn. Kernel pwn or Linux kernel exploitation is essentially vulnerability research and exploitation of the Linux kernel. This includes source code auditing to understand program behaviour, debugging & fuzzing for dynamic analysis, vulnerability discovery and exploit development. I'm writing this not having a 360 degree full-fledged understanding of Kernel pwn, but writing this so drill in the info in my head first, and then in yours (hopefully!). This used to look like such a strange and elite type of knowledge but since I've immersed myself a bit into it and just generally got my feet wet, It would'nt be so bad to share the one or two things I've learnt.
If you don't know what a Kernel is, then let this serve as a chilled way to start. The Kernel is hands down the most important part of a computer. It goes as far as handling all the communication between hardware and software in a system as well as manage all the syscalls (system calls) that the system needs to execute just for it to run well and smooth without any issues. Since this is particularly important, and you know this blog is all about hacking and learning more about computer security, then you already know what time it is!

I'm going to be diving in to kernel pwn and understanding all the exploit techniques used as well as how to bypass the relevant mitigations. Keep in mind that this series will be split up into different posts so get your mind ready for that too. As opposed to userland pwn, this series will be somewhat of an advanced topic, especially with regards to the background knowledge so just keep that in mind. Obviously, hacking into a system you have no permission to can result in serious repercussions that can potentially ruin your future in an instant, so I will preface this post with this:

***DO NOT HACK INTO A SYSTEM YOU HAVE NO EXPLICIT PERMISSION TO. IT IS ILLEGAL AND ENGAGING IN SUCH WILL LAND YOU IN JAIL. 

Got it? cool.

Let's start off.

In Linux, there are different types of kernel modules. There are 'char', 'block' and 'network' kernel modules and usually end with .ko extension (which stands for kernel object), while originally are written in C. 

In a typical kernel pwn CTF challenge, the task is essentially to achieve local privilege escalation by exploiting a vulnerable kernel module which is installed on boot. It is actually quite similar to userland pwn (normal pwnable binaries), except to what I know and seen, userland pwn exploit scripts are written in python but kernel pwn exploits are written in C. 

To go in depth, i'll go over the kernel-rop CTF challenge, that deals with how a typical linux kernel pwn challenge would look like and go over ways I've learnt to approach these challenges. Let's have a look at some key challenge files that we will be focusing on.


There are quite a bit of files here, but the following are the most important for qemu to use for emulation of the challenge:

vmlinuz - This is the actual linux kernel, except it has been compressed to make the size of the file smaller (sometimes, it is also named bzImage.

initramfs.cpio.gz - This is the linux file system (compressed with gzip and cpio) where the /bin, /etc and many other important linux file directories are found. The vulnerable kernel module is also located somewhere in the file system as well.

run.sh - This shell script actually contains the qemu boot configuration. (qemu is simply just a system emulation tool)

Now that we're aware of the important files needed to take on the challenge, the next thing we have to do is to use the extract-image.sh script, to extract the kernel ELF File (yes, the linux kernel is an ELF executable file). We do this because, as the name of the challenge assumes, "kernel-rop", we will be dealing with ROP chains, just as we would when exploiting userland pwn challenges. we can use the following command to extract the kernel ELF file like so:

Now that we have the kernel ELF file extracted into the name 'vmlinux', the next thing we have to do is to extract all the ROP Gadgets from kernel ELF file. If you're not caught up to speed with what ROP gadgets are then i'll do you a favour and give an overview. ROP gadgets are gadgets located within an ELF file, assembly instructions specifically that end with a RET instruction. ROP gadgets can be used within an exploit payload to setup the stack in such a way to achieve code execution, especially if the non-executable bit is enabled. 

since the Kernel ELF file is quite big, ill execute this command to extract all the ROP Gadgets:



p.s make sure you have ROPGadget installed or even ropper as well. Like i said, the kernel ELF file is a big boy so i'll leave this to run in the background. Could take a good while. 

Now we deal with the compressed initramfs file which contains the linux file system. To have the entire file system exposed to us we have to make use of the decompress.sh script. Let's go into it deeper.




Thes script basically creates a new directory called initramfs, navigates to it, copy the initramfs.cpio.gz in the previous directory into the current working directory, uses gunzip & cpio to extract with gunzip and cpio. Let's quickly run the script.


The result of decompress.sh file. It has extracted the file system and here we see an interesting file called 'hackme.ko'. That is because that is the vulnerable module we are to exploit. 

When we run the decompress.sh script, we do it, not only to have a hold of the vulnerable kernel module to analyze, but also to do a file modification that will be very important. firstly, we will have a look at what exactly this file is.


within the /etc directory in the file system is the inittab file. This file basically tells us that when we finally run the run.sh qemu boot script, it sets the user ID and group ID to 1000 instead of 0. we cannot proceed with debugging the kernel. So we have to change the 1000 to 0 to achieve the capability to boot the kernel in qemu as root to enable debugging and overall supply ease to the exploitation process. Like so:

setuidgid from '1000' to '0'

Once this is done, we just have to use the compress.sh to recompress it to save the configurations before booting it with qemu.


Compressed. 

the run.sh script (qemu)

Now that we have that done, before I round up, let's look at the run.sh script.



some of these flags get all the info we need to get started with the challenge.

-m -> This is showing the memory size
-kernel -> This specifies the compressed kernel image
-initrd -> specifies the local file system.
- the script also contains protective cases like kaslr, smep and smap, which are exploitation mitigations enabled when the image boots up when we finally run the script.

So we've gone through a good number of things to setup the environment to finally get pwning the kernel. Remember, I am no pro at this. i just have a fundamental understanding of userspace pwn challenges that's helped me along the time I've been actively engaging in pwn ctf challenges enough to have got me started. In the next blog post, we'll go into actually running the run.sh qemu shell script, attaching the challenge to gdb as well as doing some reversing and establishing the attack strategy.