Exploit & Debug Looney Tunables CVE-2023-4911 Local Privilege Escalation in the glibc's ld.so
Hoi, let's try to debug and explain CVE-2023-4911 which is a buffer overflow in the glibc loader my debugging and exploit tested on Ubuntu 22.04.2 (Jammy Jellyfish), you can read the analysis and more information from the Qualys Security writeup.
POC to check if you are vulnerable or not
env -i "GLIBC_TUNABLES=glibc.malloc.mxfast=glibc.malloc.mxfast=A" "Z=`printf '%08192x' 1`" /usr/bin/su --help
My exploit POC video takes 5m but I speeded up the video
Preparing
let's disable ASLR and debug our exploit
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
you have to know (from qualys security):
On Linux, the stack is randomized in a 16GB region, and our environment strings can occupy up to 6MB (_STK_LIM / 4 * 3, in the kernel's bprm_stack_limits()): after 16GB / 6MB = 2730 tries we have a good chance of guessing the address of our environment strings.
using the buffer overflow vulnerability in the tunables we will overflow the link_map struct which has an important section l_info because it has DT_RPATH the "Library search path" if successfully replace this path we will add a new name for a directory which will be trusted and the loader will load the libc from it so we can add a vulnerable libc to this directory.
we have to know the offset of the string that we will use as a trusted directory from the SUID-root binary that we will use, we will show it with /usr/bin/su we have to know the offset of the .dnystr section using the command objdump -h /usr/bin/su | grep dynstr it will be ff0 we can use this command to show the hexdump of the binary with the offset hexdump -C -s 0xfc0 /usr/bin/su | head note that I decreased the offset to show bytes before the .dynstr section we can find the string (") before the start of .dynstr by 20 so our offset will be -20 (0xffffffffffffec).
l_info[DT_RPATH] should point to a stack address that points to the address of the trusted domain string which is (") with offset -20 (0xffffffffffffec).
What should our exploit do?
First will take a copy of the libc.so.6 and write a shellcode in it at offset 171456 which is the _libc_main offset and add the new vulnerable version to directory called (") which will be trusted soon.
we will send a normal GLIBC Tunable after that we will call the vulnerable GLIBC Tunable format GLIBC_TUNABLES=glibc.malloc.mxfast=glibc.malloc.mxfast=AAA this will trigger the overflow which will reach the link_map struct that we need to correct the syntax of the struct we will fill it with NULLs until we reach the l_info[DT_RPATH] and after it too, after setting up the struct we have to send another tunable that will make the struct syntax right.
Now we have to setup the stack with the string offset value which is -20 and we will add after it 7 values for example "0x41" to make the alignment right for the address and add it in the right format if we didn't add this padding the address will be in this format (0xecffffffffffff) and this is wrong, last thing we will send more 4 nulls to correct the alignment for string offset into the stack
let's breakpoint at _dl_new_object+115 directly after calloc call at _dl_new_object+109 to see the link_map stuct value
this is the address that we should brute force, in debugging mode it is fixed because we disabled the ASLR, now this address points somewhere into the stack which contains the offset of the trusted domain string which is (22->")
when we continue running it will open the directory and load the libc.so.6 from it which is injected with our shellcode that will run as root and give us a shell.
what address we will brute force? we can use the address from Qualys Security writeup but we also can calculate it by taking the top of the stack (0x800000000000) and subtracting it from a value (0x2000000) got from (1 << 30) this 30 is the bits of entropy table for the main stack at Linux 64 (check here) and I removed a zero to be (0x7fffe0000000) I replaced nulls with 10 but the LSB I make it 20 I got it by trying to change the LSB of the address and it works with (0x7ffffe101020)
we can get it using gdb too
reenable the ASLR, compile the exploit code, and run it after a few minutes you will be a root
Summary
Thanks for reading, see you later.
Comments
Post a Comment