
लिनक्स से संबंधित एक भेद्यता
यह रिपॉजिटरी क्या है: CVE-2023-32233 का मेरा व्यावहारिक पुनरुत्पादन और अध्ययन — Linux कर्नेल Netfilter nf_tables सबसिस्टम में एक use-after-free जो स्थानीय विशेषाधिकार वृद्धि (local privilege escalation) की अनुमति देता है, जिसे मई 2023 में Patryk Sondej और Piotr Krysiuk द्वारा सार्वजनिक रूप से प्रकट किया गया था।
श्रेय: PoC (exploit.c) और मूल write-up @Liuk3r द्वारा हैं। इस रिपॉजिटरी में मेरा कार्य exploit को अपनी प्रयोगशाला (Ubuntu 23.04, kernel 6.2.0-20) में पुनरुत्पादित करना तथा नीचे मूल कारण और 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 को dereference करता है: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 दूषित कर दिया जाए, तो हमलावर द्वारा चुनी गई मेमोरी लोकेशन को nft_set_ext के रूप में व्याख्यायित किया जाता है — यह वह primitive है जिस पर बाकी सब कुछ निर्मित होता है।
nf_tables_trans_destroy_work() के विरुद्ध: एक बड़े set-destroy संचालन को नियंत्रित विलंब के रूप में डालें, अन्य CPUs को व्यस्त रखें, और मुक्त किए गए nft_set चंक को उसी CPU से भिन्न प्रकार (अलग elemsize) वाले nft_set के साथ पुनः आवंटित करें → type confusion।nft_set_ext हेडर तैयार करें out-of-range ऑफसेट के साथ, ताकि nf_tables_set_elem_destroy() आसन्न चंकों को नष्ट किए जाने वाले nft_expr की सूची के रूप में पार कर सके।NFTA_LOG_PREFIX के साथ nft_log एक्सप्रेशन स्प्रे करें; nft_log_destroy() priv->prefix को मुक्त करता है, जिससे kmalloc-{8..192} में एक ओवरलैपिंग आवंटन primitive प्राप्त होता है (शुरुआत में NULL-बाइट-सीमित)।nft_object->udata के साथ पुनः प्राप्त करें।विशेष रूप से, चुने गए primitives ऐसी किसी भी चीज़ से बचते हैं जिसे CFI अवरुद्ध करेगा — किसी भी चरण में indirect-call अपहरण की आवश्यकता नहीं है।
SLAB_FREELIST_HARDENED), INIT_ON_FREE, और per-CPU slab पुन:उपयोग प्रतिबंध सभी चरण 1 पर आक्रमण करते हैं; CFI (जहाँ मौजूद है) चरण 3+ को सीमित करता है।nf_tables बैच netlink संदेशों के लिए ऑडिट नियम; स्टैक में nft_set_elem_ext / nf_tables_trans_destroy_work के लिए crash triage।nftables को CAP_NET_ADMIN की आवश्यकता होती है, लेकिन अनविशेषाधिकृत user namespaces इसे प्रदान करते हैं — यही कारण है कि kernel.unprivileged_userns_clone=0 एक सार्थक hardening विकल्प है।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 देखें। निष्क्रिय bare-metal Intel प्रणालियों पर रिपोर्ट की गई सफलता संभावना ≥80% है; कुछ माइक्रोआर्किटेक्चर (जैसे Alder Lake) को अतिरिक्त ट्यूनिंग की आवश्यकता होती है।
सफल रन के बाद PoC कर्नेल को दूषित मेमोरी के साथ अस्थिर स्थिति में छोड़ देता है। केवल समर्पित, डिस्पोजेबल सिस्टम या VM स्नैपशॉट पर परीक्षण करें — कभी भी ऐसी किसी चीज़ पर नहीं जिसमें आपका महत्वपूर्ण डेटा हो।
exploit.c — PoC स्रोत (@Liuk3r द्वारा)ORIGIN.md — मूल भेद्यता और exploitation write-up (Liuk3r द्वारा)README.md — यह फ़ाइल: पुनरुत्पादन + मेरे विश्लेषण नोट्सशोध एक पृथक प्रयोगशाला वातावरण में रक्षात्मक/शैक्षिक प्रयोजनों के लिए किया गया।
nft_dynset एलिमेंट स्प्रे:
nft_counter — nft_counter_ops को लीक करता है → nf_tables.ko का आधार (मॉड्यूल के लिए KASLR को पराजित करता है);nft_quota — consumed पॉइंटर मनमाना read (NFT_MSG_GETSETELEM → nft_quota_do_dump() → NFTA_QUOTA_CONSUMED) और मनमाना write (nft_overquota() लूपबैक ट्रैफ़िक पर skb->len को *priv->consumed में जोड़ता है) प्रदान करता है।modprobe_path को ओवरराइट करें ("/sbin/modprobe" → "//tmp/modprobe") → हमलावर-नियंत्रित सामग्री के साथ root प्रक्रिया निष्पादन।