In 2023, a major vulnerability was discovered in the Linux kernel’s Netfilter nf_tables subsystem. Tracked as CVE-2023-32233, this vulnerability affects all Linux kernels up to version 6.3.1 and can let an unprivileged local user gain root access to the system.
This post will explain the vulnerability using simple language, walk you through how attackers can exploit it, and show some sample code. We’ll also reference sources and further reading for those who want to dive deeper.
Attack vector: Local, unprivileged user
- Impact: Arbitrary read/write in kernel memory → root privileges
Short explanation:
The bug lives in how Netfilter’s nf_tables handles anonymous sets in batch requests. If batch requests are crafted in a certain way, they can cause freed memory to be used again (UAF). This lets an attacker read or write arbitrary kernel memory, which can be abused to escalate privileges, even to root.
What is Netfilter and nf_tables?
Netfilter is the subsystem in the Linux kernel that handles packet filtering, NAT, and related network operations. The nf_tables framework is its current rule engine, replacing legacy implementations like iptables.
Where’s the Bug?
The bug happens when the kernel processes batches of operations on Netfilter tables, specifically with anonymous sets (sets without a name). Under certain conditions, deleting an anonymous set and then accessing it without enough checks causes the kernel to use dangling pointers — that is, to operate on freed memory.
Why Do Anonymous Sets Matter?
Anonymous sets should have their memory handled strictly. If you remove one, its memory should be considered unsafe. But due to this bug, references to deleted anonymous sets can still exist and be used. An attacker can exploit this flaw.
Exploit Outline
Goal:
Achieve arbitrary read/write in kernel memory, escalate privileges to root.
Here’s a simplified code flow
// Pseudocode: Using Netlink to communicate with nf_tables
// Step 1: Create an anonymous set
send_netlink_message({CREATE_ANON_SET});
// Step 2: Delete the set in the same batch
send_netlink_message({DELETE_SET});
// Step 3: Use-after-free: Try to access the same set
send_netlink_message({MODIFY_SET});
// Step 4: Heap spray to reallocate set struct with attacker-controlled data
// Step 5: Overwrite kernel memory, escalate privileges
Real-world exploits are more complicated, but this is the core idea.
Here’s a simplified Python snippet showing how to use Netlink sockets with nfnetlink
import socket
# Craft a Netlink message (simplified!)
nl_sock = socket.socket(socket.AF_NETLINK, socket.SOCK_DGRAM, 12) # NETLINK_NETFILTER = 12
def make_nft_batch():
# This is overly simplified, see links below for full PoCs
batch = b"<netlink header>"
batch += b"<create anon set>"
batch += b"<delete set>"
batch += b"<use set>"
return batch
nl_sock.send(make_nft_batch())
response = nl_sock.recv(4096)
print(response)
Real exploits are more complex
- See HackerFantastic’s PoC
- Or Jann Horn’s writeup
Links to References
- Kernel Patch & Discussion (oss-sec)
- Original Report and Patch
- Exploit Writeup - SecLists
- PoC Code - hackerfantastic on GitHub
- NVD CVE Detail
Conclusion
CVE-2023-32233 is a perfect example of how a subtle use-after-free in core Linux networking code can have huge consequences, letting attackers get root on systems with only local, unprivileged access. If you operate Linux machines, patch your kernel immediately.
For researchers and sysadmins, read the full references for a deeper dive. And as always, keep your systems up-to-date!
*Written with clarity for all security-minded readers — stay safe out there!*
Timeline
Published on: 05/08/2023 20:15:00 UTC
Last modified on: 05/15/2023 18:27:00 UTC