
CVE-2023-32233 का पुनरुत्पादन और मूल कारण विश्लेषण, जो एक Linux kernel nf_tables use-after-free है जो स्थानीय विशेषाधिकार वृद्धि को सक्षम बनाता है, PoC और शोषण नोट्स के साथ।
यह रेपो क्या है: CVE-2023-32233 का मेरा प्रत्यक्ष पुनरुत्पादन और अध्ययन, जो Linux kernel Netfilter nf_tables सबसिस्टम में एक use-after-free है जो स्थानीय विशेषाधिकार वृद्धि (local privilege escalation) की अनुमति देता है, जिसे मई 2023 में Patryk Sondej और Piotr Krysiuk द्वारा सार्वजनिक रूप से प्रकट किया गया था।
श्रेय: PoC (exploit.c) और मूल लेख @Liuk3r द्वारा हैं। इस रेपो में मेरा कार्य अपनी प्रयोगशाला (Ubuntu 23.04, kernel 6.2.0-20) में exploit का पुनरुत्पादन करना और नीचे मूल कारण तथा exploitation श्रृंखला का दस्तावेजीकरण करना है। सभी परीक्षण समर्पित प्रयोगशाला मशीनों पर किए गए थे।
nf_tables कॉन्फ़िगरेशन अपडेट को एक परमाणु बैच (atomic batch) के रूप में संसाधित करता है। एक ही बैच में पिछले ऑपरेशनों के स्थिति परिवर्तनों के विरुद्ध प्रत्येक ऑपरेशन का सत्यापन अपर्याप्त है। विशेष रूप से:
nft_rule से शुरू करें जिसमें कुछ तत्वों वाले एक अनाम nft_set पर एक lookup एक्सप्रेशन हो।NFT_MSG_DELRULE — नियम को हटाता है, जो अंतर्निहित रूप से lookup एक्सप्रेशन और अनाम nft_set को हटा देता है;NFT_MSG_DELSETELEM — पहले से हटाए गए अनाम सेट के एक तत्व को हटाता है।nf_tables_commit_release() संसाधनों को nf_tables_destroy_list पर कतारबद्ध करता है, जिसे बाद में nf_tables_trans_destroy_work() द्वारा संसाधित किया जाता है:
पहले nft_commit_release() → nf_tables_rule_destroy() → nft_lookup_destroy() → nft_set_destroy() → kvfree() nft_set को मुक्त करता है;
फिर, NFT_MSG_DELSETELEM के लिए, nf_tables_set_elem_destroy() nft_set_elem_ext() को कॉल करता है जो मुक्त किए गए nft_set को डीरेफरेंस करता है:
static inline struct nft_set_ext *nft_set_elem_ext(const struct nft_set *set,
void *elem)
{
return elem + set->ops->elemsize;
}
यदि set->ops->elemsize भ्रष्ट (corrupted) हो जाता है, तो हमलावर द्वारा चुना गया मेमोरी स्थान nft_set_ext के रूप में व्याख्यायित किया जाता है — यही वह आदिम (primitive) है जिस पर बाकी सब कुछ आधारित है।
nf_tables_trans_destroy_work() के विरुद्ध रेस जीतें: एक नियंत्रित विलंब के रूप में एक बड़ा set-destroy ऑपरेशन डालें, अन्य CPUs को व्यस्त रखें, और उसी CPU से मुक्त किए गए nft_set चंक को भिन्न प्रकार के nft_set (भिन्न elemsize) के साथ पुनःआवंटित करें → प्रकार भ्रम (type confusion)।nft_set_ext हेडर तैयार करें जिनमें सीमा से बाहर के ऑफ़सेट हों ताकि nf_tables_set_elem_destroy() आसन्न चंक्स को नष्ट करने के लिए nft_expr की सूची के रूप में चले।NFTA_LOG_PREFIX के साथ nft_log एक्सप्रेशन स्प्रे करें; nft_log_destroy() priv->prefix को मुक्त करता है, जिससे kmalloc-{8..192} में एक अतिव्यापी आवंटन आदिम (overlapping allocation primitive) मिलता है (पहले NULL-बाइट-सीमित)।nft_object->udata के साथ पुनःदावा करें ताकि डैंगलिंग रीड पर NULL-बाइट प्रतिबंध हट जाए।nft_dynset तत्व स्प्रे:
nft_counter — nft_counter_ops लीक करता है → nf_tables.ko का आधार (मॉड्यूल के लिए KASLR को विफल करता है);nft_quota — consumed पॉइंटर मनमाना रीड (NFT_MSG_GETSETELEM → nft_quota_do_dump() → NFTA_QUOTA_CONSUMED) और मनमाना राइट (nft_overquota() लूपबैक ट्रैफ़िक पर *priv->consumed में skb->len जोड़ता है) देता है।modprobe_path को अधिलेखित करें ("/sbin/modprobe" → "//tmp/modprobe") → हमलावर-नियंत्रित सामग्री के साथ रूट प्रक्रिया निष्पादन।उल्लेखनीय है कि चुने गए आदिम (primitives) किसी भी ऐसी चीज़ से बचते हैं जिसे CFI अवरुद्ध करेगा — किसी भी चरण में अप्रत्यक्ष-कॉल हाइजैकिंग की आवश्यकता नहीं है।
SLAB_FREELIST_HARDENED), INIT_ON_FREE, और प्रति-CPU slab पुनःउपयोग प्रतिबंध सभी चरण 1 पर हमला करते हैं; CFI (जहाँ मौजूद हो) चरण 3+ को सीमित करता है।nf_tables बैच netlink संदेशों पर ऑडिट नियम; स्टैक में nft_set_elem_ext / nf_tables_trans_destroy_work के लिए क्रैश ट्राइएज।nftables को CAP_NET_ADMIN की आवश्यकता होती है, लेकिन अविशेषाधिकार प्राप्त उपयोगकर्ता नेमस्पेस इसे प्रदान करते हैं — यही कारण है कि kernel.unprivileged_userns_clone=0 एक सार्थक हार्डनिंग नॉब है।Ubuntu 23.04 (Lunar Lobster), kernel 6.2.0-20-generic के अंतर्गत परीक्षण किया गया।
sudo apt install gcc libmnl-dev libnftnl-dev
gcc -Wall -o exploit exploit.c -lmnl -lnftnl
अंतर्निहित प्रोफ़ाइल Ubuntu 23.04 बाइनरी कर्नेल (linux-image-6.2.0-20-generic 6.2.0-20.20) को लक्षित करती है। अन्य कर्नेल का परीक्षण करने के लिए, प्रतीकों को एक profile फ़ाइल में निकालें:
modprobe nf_tables
egrep ' (nft_counter_ops|nft_counter_destroy|free_percpu|modprobe_path)(\s|$)' /proc/kallsyms > profile
nft_counter_destroy() का मशीन-कोड लेआउट कंपाइलर और विकल्पों के साथ बदलता है; पूर्ण पैरामीटर संदर्भ (nft_counter_destroy_call_offset/mask/check) और रेस-ट्यूनिंग नॉब (race_lead_sleep आदि) के लिए ORIGIN.md देखें। निष्क्रिय बेयर-मेटल Intel सिस्टम पर रिपोर्ट की गई सफलता की संभावना ≥80% है; कुछ माइक्रोआर्किटेक्चर (जैसे Alder Lake) को अतिरिक्त ट्यूनिंग की आवश्यकता होती है।
सफल रन के बाद PoC कर्नेल को भ्रष्ट मेमोरी के साथ अस्थिर स्थिति में छोड़ देता है। केवल एक समर्पित, डिस्पोज़ेबल सिस्टम या VM स्नैपशॉट पर परीक्षण करें — कभी भी उस चीज़ पर नहीं जिसमें आपके लिए महत्वपूर्ण डेटा हो।
exploit.c — PoC स्रोत (@Liuk3r द्वारा)ORIGIN.md — मूल भेद्यता और exploitation लेख (Liuk3r द्वारा)README.md — यह फ़ाइल: पुनरुत्पादन + मेरे विश्लेषण नोट्सअनुसंधान एक पृथक प्रयोगशाला वातावरण में रक्षात्मक/शैक्षिक उद्देश्यों के लिए किया गया।