Exploitation

Here comes the part you have been waiting for, now that you are familiar with the basics of the kernel (for exploitation) we will finally see the main subject of this article

I want to say that the exploitation in pwn are often very contextual and that the example that I am going to show you does not apply necessarily for all but I am going to try to globalize a maximum this part so that you can exploit other cases

For this part I will use a challenge of a ctf of an exploitation of a kernel I will show you the different exploitation techniques

First approach

As said before we will exploit a custom kernel module vulnerable to a buffer overflow vulnerability (in our case a stack overflow based )

Note: in this first case no protection is activated and the source code is not provided (it is possible that the source code of the module is provided with the challenge)

So in this part we are going to see a basic and very efficient technique in the exploitation of a kernel

But first let's just try to find the entrypoint

Wait, this is your first kernel operation, you have arrived on an environment and you don't understand anything? Don't worry, I'll explain it to you quickly

In most cases, the module will be given along with some files that ultimately use qemu as the emulator for a Linux system or image from vmware or virtualbox

Kernel stack layout

On Linux, every thread on your system has a corresponding kernel stack allocated in kernel memory. Linux kernel stacks on x86 are either 4096 or 8192 bytes in size, depending on your distribution. While this size may seem small to contain a full call chain and associated local stack variables, in reality the kernel call chains are relatively shallow and kernel functions are discouraged from abusing the precious space with large local stack variables when efficient allocators such as the SLUB are available.

The stack shares the 4k/8k total size with the thread_info structure, which contains some metadata about the current thread, as seen in include/linux/sched.h:

union thread_union {
 struct thread_info thread_info;
 unsigned long stack[THREAD_SIZE/sizeof(long)];
};

The thread_info structure has the following definition on x86 from arch/x86/include/asm/thread_info.h:

struct thread_info {
 struct task_struct *task;
 struct exec_domain *exec_domain;
 __u32 flags;
 __u32 status;
 __u32 cpu;
 int preempt_count;
 mm_segment_t addr_limit;
 struct restart_block restart_block;
 void __user *sysenter_return;
#ifdef CONFIG_X86_32
 unsigned long previous_esp;
 __u8 supervisor_stack[0];
#endif
 int uaccess_err;
};

Visualising kernel stack

fz1.png