
Exploit du sous-système TLS du noyau Linux pour CVE-2024-58239, réalisant une escalade de privilèges via une vulnérabilité de double libération dans tcp_rcv_state_process. Inclut une architecture client-serveur et des scripts de test local.
Ceci est mon premier exploit 1-day.
Correctif : tls: stop recv() if initial process_rx_list gave us non-DATA
J'ai vu exp407 sur le tableur kernelCTF et j'ai essayé de reproduire l'exploit.
J'ai réussi à exécuter l'exploit dans l'environnement kernelCTF et obtenir le flag :

J'écrirai un write-up détaillé pour cela plus tard.
Le journal de l'exploit est assez long, à cause d'un WARNING du noyau au milieu. Cependant, un avertissement n'est pas une erreur et il ne tue pas mon exploit ;)

J'ai retiré de nombreux fichiers lourds de ce dossier.
./rootfs_v3.img./ramdisk_v1.img./releases/mitigation-v4-6.6/bzImage./releases/mitigation-v4-6.6/vmlinuxVous pouvez obtenir les 3 premiers fichiers en exécutant original local_runner.sh
Pour le quatrième et le code source, vous pouvez vous connecter au serveur kernelCTF et obtenir des liens de téléchargement.
Mais pour votre commodité, voici les informations de l'instance mitigation-v4-6.6 :
Kernel image (bzImage): https://storage.googleapis.com/kernelctf-build/releases/mitigation-v4-6.6/bzImage
Kernel image (vmlinux): https://storage.googleapis.com/kernelctf-build/releases/mitigation-v4-6.6/vmlinux.gz
Kernel config: https://storage.googleapis.com/kernelctf-build/releases/mitigation-v4-6.6/.config
-> derived from COS config: https://storage.googleapis.com/kernelctf-build/releases/mitigation-v4-6.6/lakitu_defconfig
Source code info: https://storage.googleapis.com/kernelctf-build/releases/mitigation-v4-6.6/COMMIT_INFO
De plus, les commandes pour télécharger les fichiers .img :
wget https://storage.googleapis.com/kernelctf-build/files/rootfs_v3.img.gz
gzip -d rootfs_v3.img.gz
wget https://storage.googleapis.com/kernelctf-build/files/ramdisk_v1.img
cd ./exploit/mitigation-v4-6.6/
make
Cet exploit est divisé en 2 parties :
Serveur :
./server --port <port>
Client :
./client --ip <server_ip> --port <port>
J'ai écrit 2 scripts pour tester l'exploit en local :
Celui-ci démarre le serveur en arrière-plan, puis exécute le client dans la VM qemu.
D'abord, allez dans exploit/mitigation-v4-6.6, et démarrez un serveur http sur le port 3000, pour télécharger l'exploit vers la VM qemu plus tard
cd exploit/mitigation-v4-6.6
python3 -m http.server 3000
Ensuite, dans un autre terminal, lancez le script :
python3 test.py <your_ip> <port>
<your_ip> est l'IP de votre carte réseau. Pour moi, je lance le tout dans WSL, j'exécute ip a, et j'obtiens l'IP de l'interface eth0, 172.30.248.93➜ CVE-2024-58239 git:(main) ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet 10.255.255.254/32 brd 10.255.255.254 scope global lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:15:5d:22:a0:d1 brd ff:ff:ff:ff:ff:ff
inet 172.30.248.93/20 brd 172.30.255.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::215:5dff:fe22:a0d1/64 scope link
valid_lft forever preferred_lft forever
<port> est un port inutilisé sur votre machine locale. Il sert à la connexion TLS entre le client et le serveur.Celui-ci exécute l'exploit un certain nombre de fois et mesure son taux de réussite.
Comme pour l'utilisation de test.py, allez dans exploit/mitigation-v4-6.6, et démarrez un serveur http sur le port 3000, pour télécharger l'exploit vers la VM qemu plus tard
cd exploit/mitigation-v4-6.6
python3 -m http.server 3000
python3 calc_AC_rate.py <your_ip> <port> <number_of_time_to_run>
Par exemple, sur mon WSL, je l'exécute comme python3 calc_AC_rate.py 172.30.248.93 1118 100.
Je travaille encore sur le taux de réussite, car pour l'instant il est un peu instable.
J'exécute calc_AC_rate.py pour tester l'exploit 100 fois, et le résultat est 50/100.
Pour les tentatives échouées, c'est à cause de common_interrupt qui survient en cours de route, déclenchant une détection naïve de double libération dans le slab du noyau, comme le montre cette backtrace.
Je trouverai un moyen de la désactiver.
[ 4.050330] ? die+0x32/0x80
[ 4.050809] ? do_trap+0xd6/0x100
[ 4.051365] ? __slab_free+0x16c/0x380
[ 4.052198] ? do_error_trap+0x6a/0x90
[ 4.052767] ? __slab_free+0x16c/0x380
[ 4.053350] ? exc_invalid_op+0x4c/0x60
[ 4.053916] ? __slab_free+0x16c/0x380
[ 4.055031] ? asm_exc_invalid_op+0x16/0x20
[ 4.055675] ? tcp_rcv_state_process+0x791/0xef0
[ 4.056527] ? __slab_free+0x16c/0x380
[ 4.057097] ? lock_timer_base+0x61/0x80
[ 4.057795] ? tcp_get_metrics+0x142/0x380
[ 4.058560] ? tcp_rcv_state_process+0x791/0xef0
[ 4.059265] kmem_cache_free+0x599/0x5e0
[ 4.059915] tcp_rcv_state_process+0x791/0xef0
[ 4.060918] ? security_sock_rcv_skb+0x31/0x50
[ 4.061857] ? sk_filter_trim_cap+0x11a/0x290
[ 4.062558] tcp_v4_do_rcv+0xcd/0x280
[ 4.063281] tcp_v4_rcv+0xf81/0x1010
[ 4.063832] ? raw_local_deliver+0xcd/0x250
[ 4.064668] ip_protocol_deliver_rcu+0x32/0x320
[ 4.065355] ip_local_deliver_finish+0x7a/0xa0
[ 4.066455] ip_sublist_rcv_finish+0x7e/0x90
[ 4.067231] ip_sublist_rcv+0x1e1/0x220
[ 4.067919] ? __netif_receive_skb_core.constprop.0+0xbf/0x1080
[ 4.068822] ip_list_rcv+0x139/0x170
[ 4.069362] __netif_receive_skb_list_core+0x29d/0x2c0
[ 4.070173] ? __pfx_csum_block_add_ext+0x10/0x10
[ 4.071054] netif_receive_skb_list_internal+0x1e1/0x310
[ 4.072068] napi_complete_done+0x6e/0x1a0
[ 4.072752] virtnet_poll+0x40d/0x5a0
[ 4.073313] __napi_poll+0x28/0x1c0
[ 4.073854] net_rx_action+0x14c/0x2d0
[ 4.074622] ? vp_vring_interrupt+0x73/0x90
[ 4.075746] __do_softirq+0xf6/0x30f
[ 4.076379] __irq_exit_rcu+0x79/0xc0
[ 4.077356] common_interrupt+0xb9/0xd0