nftables nft_byteorder OOB (CVE-2023-35001)¶
"overlayfs" etiketine rağmen bu slug CVE-2023-35001'i belgeler: nftables jumpstack'ine bir netfilter
nft_byteorder_eval()out-of-bounds read/write'ı; Synacktiv bunu Pwn2Own Vancouver 2023'te Ubuntu'yu root'lamak için kullandı.
Adlandırma notu
Alias'lar (nft_byteorder OOB, "StackRot-adjacent") gerçek konunun bir overlayfs
kusuru değil, Synacktiv'in Pwn2Own 2023'te exploit ettiği nftables nft_byteorder
bug'ı olan CVE-2023-35001 olduğunu açıkça gösterir. Bu not, gerçek CVE'yi anlatır.
Mechanism¶
Bir u32/u16 union'ının register array'i jumpstack'e doğru neden over-read ettiği
nftables, küçük bir per-packet register file'ını okuyup yazan expression'ları
dolaşarak bir rule'u evaluate eder. nft_byteorder, bir register değerini
byte-swap eden (host<->network order) expression'dır. Evaluator'ı, source ve
destination register'larını alias'lamak için bir union deklare eder:
static void nft_byteorder_eval(const struct nft_expr *expr,
struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
...
union { u32 u32; u16 u16; } *s, *d;
s = (void *)®s->data[priv->sreg];
d = (void *)®s->data[priv->dreg];
...
case 2: /* 2-byte elements */
for (i = 0; i < priv->len / 2; i++)
d[i].u16 = ntohs((__force __be16)s[i].u16);
}
Bug şu: sizeof(union {...}), en büyük üyesinin boyutudur (4 byte), bu
yüzden s[i] / d[i], 2-byte (u16) durumunda bile index başına 4 byte
ilerler. len/2 iterasyonu register array'in sonunu aşacak şekilde seçilen bir
len ile, loop regs->data[]'nin out of bounds'una read ve write yapar.
Stack'te register'ların hemen ardında yatan şey rule-evaluation context'idir —
özellikle de kaydedilmiş rule / last_rule pointer'larını tutan
struct nft_jumpstack jumpstack[NFT_JUMP_STACK_SIZE]. Bozuk stride dolayısıyla
o kernel-stack pointer'ları üzerinde controlled bir OOB read/write verir.
İhlal edilen invariant şu: bir expression yalnızca fixed-size register file'a dokunmalıdır. 2-byte'lık bir operasyonu 4-byte'lık bir stride ile ele alarak, evaluator in-bounds bir register index'ini out-of-bounds bir stack erişimine çevirir.
Walkthrough¶
Bug, nftables'ı configure edebilen herhangi bir kullanıcı tarafından erişilebilir.
Ubuntu'da unprivileged_userns_clone varsayılan olarak açıktır, bu yüzden unprivileged
bir kullanıcı bir user namespace'e girip private bir net namespace üzerinde
CAP_NET_ADMIN kazanabilir.
# Conceptually: from an unprivileged user namespace + net namespace,
# install an nft table/chain and an nft_byteorder expression in a subchain
# whose source register sits at the top of the register array and whose
# destination is at the bottom (or vice versa) with a 2-byte size and a
# length that makes the 4-byte stride walk into the jumpstack.
unshare - Urn bash # new user + net namespace (Ubuntu default config)
OOB'den primitive'leri inşa etmek (Synacktiv'in zinciri):
- Read primitive. source/destination'ı, misaligned stride jumpstack
pointer'larını (
rule,last_rule) out of bounds okuyacak ve register içeriği üzerinden geri sızdıracak şekilde konumlandır — bir kernel pointer leak verir. - Write primitive. Tersine çevir: register'lara seçilmiş değerler yerleştir ve
misaligned
d[i].u16write'larının bir jumpstack pointer'ının low 16 bit'ini overwrite etmesine izin ver; bu, rule evaluation'ı attacker'ın expression data içine gömdüğü bir fake rule'a yönlendirir. - Module/kernel base leak'le.
nf_tables.kove kernel base'i leak'lemek için corrupted bir rule handle / craftednft_byteorderread'leri kullan. - Code execution. Attacker byte'larını (bir network packet'inde teslim edilen)
stack'lenmiş bir return address üzerine kopyalayan fake bir
nft_payloadexpression'ı üzerinden pivot et; root'a escalate etmek için bir ROP chain çalıştır.
Gereksinimler
nftables'ı programlama yeteneğine ihtiyaç duyar — yani CAP_NET_ADMIN, ki varsayılan
Ubuntu'da unprivileged bir user namespace içinde elde edilebilir. Yayınlanan
exploit, Pwn2Own image kernel 5.19.0-35'i hedefledi.
Detection¶
- Unprivileged user namespace'lerden gelen nftables rule install'ları çoğu sunucuda
anomalidir; namespace creation +
nftnetlink op'larını audit'lemek setup'ı yakalar. - KASAN,
nft_byteorder_eval'de bir stack/global-out-of-bounds raporlar.
Mitigation¶
- Element stride'ını düzelten upstream fix'i uygula; böylece 2-byte byteorder operasyonları 2 byte ilerler ve in bounds kalır.
- Unprivileged kullanıcılara
CAP_NET_ADMIN'i reddetmek içinkernel.unprivileged_userns_clone=0(veyauser.max_user_namespaces=0) ayarla.