kernel exploit Vs user land exploitation
Kernel exploits are used for privilege escalation, whereas user-land exploits aim to access a system and arbitrary execute a command. The privilege of the spawned shell or executed command totally depends to the privilege of the target vulnerable application and in a hardened environment it is minimal. If an administrator does not do his homework correctly and set the root credential for a vulnerable web server then the root privilege after successfully running an exploit against the web server is a bonus! On the other hand, the mere goal of a kernel exploit is privilege escalation. As a matter of fact, a kernel exploit is run after some sort of access to the system exists already, a remote kernel exploit is an exception though. For example an attacker may attack a vulnerable web server that is running on a limited user account using a buffer overflow exploit and receives a limited spawned shell. The attacker now wants to install a keylogger and since a keylogger is basically a driver the attacker should have the root privileges or at least the privilege to load a driver. To achieve that privilege, he needs to run a kernel exploit and elevate the privilege of the spawned shell.
Kernel vulnerability is not different than user-land vulnerability but the method of triggering operating system exploits is different! Kernel is composed of scheduler, memory manager, drivers and etc. A user-land application communicates with the operating system thorough system calls. Moreover a user-land program may communicate with a driver using IO calls. Kernels also communicate with the user through the hardware via drivers. For example, to connect to a webserver, a client should send a packet to the network card of the host. This packet arrives to the network card of the web server’s host and it is processed by the network driver which is kernel path. Except the network drivers, most of the vulnerable kernel paths are just accessible through a system call by a local program. Triggering exploits by a local program gives you some degree of control. For example bypassing ASLR and Non executable stacks is simple because you can place your shellcode in the executable and read its address!
Exploiting operating system kernel definitely introduces new challenges. Triggering kernel vulnerability is equal to tampering the operating system. Messing around with the operating system is not without extra costs; you should always have a recovery phase in your kernel exploits to remedy your mess. Furthermore leveraging kernel vulnerability needs more knowledge. There are lots of factors involved in determining the status of the operating system. Exploit writing for kernel cannot be successfully done without knowing the effects of other processes on the kernel and also the effect of your exploit on other processes. For example as you will see in the privilege escalation shellcode tutorial, one method of transferring the execution to your shellcode is modifying the system call table. Assume that your shellcode is placed in the user-land virtual addresses as part of your program executable. To execute the shellcode you update a system call to points to your shellcode. Now what happens if another process calls the system call even before your shellcode has a chance to recover the state of the system call table? The system probably crashes because other processes do not see the virtual addresses of your process and a critical page fault arises. To avoid this you probably want to modify the local descriptor tables entries, which is different for each process, or choosing an infrequent used system call instead of using a high demanded system call.
It should come as no surprise that remote kernel exploits are even more challenging. Not only you have the aforementioned challenges of local kernel exploit but also you face ASLR, non-executable stack and stack canaries protections. Because of all of these problems most people believe that arbitrary memory overwrite is the only exploitable vector in case of kernel remote exploits. It should be also mentioned that this type of vulnerability is also very common in drivers. For example UserSharedData in windows and Vsyscall page in Linux are perfect places to overwrite the shellcode. These places have fixed addresses and they have double mappings. Their mapping from a kernel path is writable so you don’t worry about being non-executable.
In kernel shellcode article you will see how a kernel exploit elevates privilege of a process.
The reference of this article like other kernel exploit materials in this website is A Guide to Kernel Exploitation book.