Featured image of post Intro To Kernel Exploitation - CVE-2024-0193_cos

Intro To Kernel Exploitation - CVE-2024-0193_cos

Learning to pop kernels thru CVE-2024-0193_cos

Setup

Link to the original vulnerability report can be found here.a

Setting up environment

To get up and running as quick as possible, setup your environment as follows:

1
2
3
4
5
6
7
8
sudo apt update
sudo apt install -y \
python3 python3-pip python3-venv \
bc binutils bison dwarves flex gcc git gnupg2 gzip libelf-dev libncurses5-dev libssl-dev make openssl dwarves perl-base rsync tar xz-utils \
libguestfs-tools \
tmux \
gdb \
qemu qemu-kvm bridge-utils

Then download the most recent affected version:

Building

Make a default config with:

1
make defconfig

and then nf_tables support with:

1
2
CONFIG_NETFILTER=y
CONFIG_NF_TABLES=y

I also have a working config here (will add soon once post is finished).

Then build the kernel with:

1
make -j$(nproc)

Then we also need to setup directories for libguestfs to work properly.

1
2
make modules
make modules_install

Then

1
2
cp arch/x86/boot/bzImage /lib/modules/6.7.0-rc8/vmlinuz
sudo chmod +r /lib/modules/6.7.0-rc8/vmlinuz

Then run this script:

1
2
3
4
5
6
virt-customize -a ubuntu-24.04-minimal-cloudimg-amd64.img \
       --root-password password:root \
       --ssh-inject pwn:file:/home/jp3g/.ssh/id_rsa.pub \
       --run-command 'useradd -m -s /bin/bash pwn' \
       --password pwn:password:abc123 \
       --ssh-inject root:file:/home/jp3g/.ssh/id_rsa.pub

This will create an unprivileged user as well as set passwords.

Getting Exploit

Download Google’s security-research repo into your host, and modify pocs/linux/kernelctf/CVE-2024-0193_cos/exploit/cos-105-17412.226.52/Makefile by adding -g to CFLAGS and removing the -s flag. Then copy it over to your qemu container with:

1
2
virt-customize -a ubuntu-20.04-minimal-cloudimg-amd64.img \
--copy-in /path/to/security-research/pocs/linux/kernelctf/CVE-2024-0193_cos/exploit/cos-105-17412.226.52/:/home/pwn/exploit

GDB and QEMU

Follow this guide to create a bridged network between qemu and your host.

In order to connect GDB to this container, run the following command and login as root:

1
2
3
4
5
6
7
8
qemu-system-x86_64 -m 3.5G -nographic -no-reboot \
	-enable-kvm -cpu host -smp cores=2 \
	-kernel bzImage \
	-drive file=./ubuntu-24.04-minimal-cloudimg-amd64.img \
	-nic bridge,br=br0
	-nographic \
	-append "root=/dev/sda1 rw console=ttyS0" \
    -s

Once inside, run:

1
2
ip link set enp0s3 up
dhclient enp0s3

This should give you an IP address. Now we have to install gdb for debugging userspace code.

1
2
3
4
5
apt install \
    binutils \
    gdb \
    build-essential \
    pkg-config

Then build the exploit from whatever directory you copied it into:

1
2
make prerequisites
make exploit

Then run gdb:

1
2
gdb
(gdb) remote target localhost:1234

Getting load address

Next, we have load the symbols from vmlinux into gdb at the correct address. After you have gotten a shell in qemu as root, run:

1
cat /proc/kallsyms | grep strncpy_from_user

This will give you the address of the strncpy_from_user function. You can of course use any function, but this is the one I chose for my example. You will see the address at which the function is loaded. I know from my own testing and calculations that strncpy_from_user is 0x548170 bytes from the load address. So whatever address you got from kallsyms, just subtract this amount from it, and you will get your load address.

Then you can load in the symbols file with:

1
(gdb) add-symbols-file ./vmlinux <load address>

Background

So I will be using the following versions:

pipapo

“Pipelined Adaptive Packet Process”, and a pipapo set refers to a specific data struct used for efficiently storing and looking up elements. It provides fast lookup and is built for handling large sets of elements.

nftnl_table

ntfnl_table_set_str

1
2
3
4
5
EXPORT_SYMBOL(nftnl_table_set_str);
int nftnl_table_set_str(struct nftnl_table *t, uint16_t attr, const char *str)
{
	return nftnl_table_set_data(t, attr, str, strlen(str) + 1);
}

Vulnerability

In the exploit given, the creates sets set1 and set2, with catchall elements set1_elem and set2_elem respectively. They are then deleted by building and sending a NFT_MSG_DELSET type Netlink message, which deactivates the data of the set elements. Then the catchall element should be GC’d (garbage collected), which deactivates its data again, resulting ins a double free.

This is achieved by setting a short timeout on a set element. Timeouts determine how long that element needs to stay in the set before it gets automatically removed. Then create the delay. Then delete the vulnerable pipapo set. We can break it down in GDB to match the sections in the original disclosure.

Triggering:

Set breakpoints at nftnl_set_alloc.

Exploitation

comments powered by Disqus