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
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
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;
};