Hello I am Arsalan. Offensive Security Engineer, I blog about Cyber security, CTF writeup, Programming, Blockchain and more about tech. born and raised in indonesia, currently living in indonesia
The ret2usr attack exploits the user space of the user space to access the kernel space, but the kernel space can access the user space** This feature directs the kernel code or data stream to the user control, and performs the userspace code completion with the ring 0 privilege. ~CTF Wiki
The ret2usr is pretty similar to ret2shellcode, since we can control things on user-land
we can put shellcode somewhere on the stack then overwrite the return address of the
current function with our shellcode address.
In order to make this technique work, we have to make sure there’s no kaslr, smep, smap
and pti is enabled.
for example I will use challenge from https://w3challs.com/challenges/pwn/knoob
Save state registers
Firstly, before going into kernel-mode we have to save the state of these registers. then
reload them after gaining root privileges. This is because normally kernel will return to user-land
using 1 instruction either it is sysretq or iretq. Most people will use iretq because as far I know sysretq
is more complicated. The iretq instruction requires the stack to be setup with 5 user-land register values
in this order RIP|CS|RFLAGS|SP|SS
the function to save the state can be look like below
Open the device
We have to open the device in order to interact with the kernel module, the function to
open the device will look like this:
Overwrite return address
We can use command like echo "AAAAAAAAAAAAAAAAAA" > /dev/vuln to determine how long the offset to overwrite %rip
then we can make a function to overwrite the current %rip on the kernel-space:
In order to get privilege escalation, we need to perform commit_creds(prepare_kernel_cred(0)) to
get root permission from kernel-space, since kaslr is disabled we can find the address from /proc/kallsyms
Now we can craft the exploit and reload all the registers to achieve root privileges. Since we want a shell to be popped, you need to return to user-land. the reason is because after running the exploit we are still in kernel-mode so in order to get a root shell we need to return to user-land. the code to achieve root privileges and reload 5 register values can be written as follows