netfilter xt_compat heap OOB null-byte write (CVE-2021-22555)¶
x_tables 32→64-bit compat path'inde 15 yıllık bir heap OOB write, yerel bir kullanıcının bir heap allocation'ının birkaç byte ötesini sıfırlamasına ve buradan tam kernel code execution'a yükseltmesine olanak veriyor ("turning \x00\x00 into $10000").
Mechanism¶
Note
x_tables compat layer'ı, 32-bit userspace rule yapılarını 64-bit kernel formuna dönüştürür. Buradaki invariant şu: dönüştürme sırasında yazılan herhangi bir byte, dönüştürülen entry için boyutlandırılmış allocation'ın içine sığmalıdır. Padding zero-fill, allocation'da hiç hesaba katılmamış bir offset'e yazıyor.
xt_compat_target_from_user() içinde (net/netfilter/x_tables.c):
pad = XT_ALIGN(target->targetsize) - target->targetsize;
if (pad > 0)
memset(t->data + target->targetsize, 0, pad);
memset, allocation boyutuna dahil olmayan target->targetsize offset'ine yazar. 8-byte'a
hizalı olmayan bir target için (örneğin NFLOG), zero-fill buffer'ın dışına taşar —
kontrollü bir OOB zero-write (writeup'a göre bounds dışına ~0x4C byte'a kadar ulaşır).
v2.6.19-rc1'den beri mevcut; 5.11 dahil olmak üzere o sürüme kadar olan kernel'leri etkiler.
Walkthrough¶
IPT_SO_SET_REPLACE / IP6T_SO_SET_REPLACE üzerinden erişilir (raw bir iptables socket'inde
setsockopt), user namespace'ler aracılığıyla unprivileged olarak kullanılabilir.
Andy Nguyen'in public exploitation zinciri:
- Victim'in çevresindeki slab'ı groom etmek için
msgsnd()(GFP_KERNEL_ACCOUNT) ilestruct msg_msgnesnelerini spray et. - Komşu bir
struct msg_msg.next(mlist.next) pointer'ını corrupt etmek için OOB zero-write'ı kullan; bu bir use-after-free / dangling çift reference üretir. - Kernel adreslerini leak etmek için free edilmiş belleği
struct pipe_buffernesneleriyle reclaim et. - Kernel code execution elde etmek için
struct pipe_buf_operations->releaseüzerinden bir function pointer'ı hijack et; kCTF Kubernetes pod izolasyonunu kırmak için kullanıldı (bounty 10.000 dolar).
Warning
Yazılan değer sabittir (sıfır byte'lar) — işin ustalığı, bir pointer'ın düşük byte'(lar)ını tam overflow offset'ine yerleştirmektir; öyle ki onları sıfırlamak kullanışlı, yanlış yönlendirilmiş bir nesne verir.
Detection¶
xt_compat_target_from_user()içinde KASAN slab-out-of-bounds write.- Unprivileged bir process'ten gelen 32-bit-compat iptables
SET_REPLACEanormaldir.
Mitigation¶
b29c457a6511435960115c0f548c4360d5f4801dcommit'iyle düzeltildi; bu commit padding zero-fill'i x_tables compat path'inden kaldırır.- Unprivileged user namespace'leri kısıtlayın; gerekmediği yerde compat netfilter path'ini devre dışı bırakın.