Skip to content
KitploitKITPLOIT
उपकरणएक्सप्लॉइटब्लॉग
Log in
जमा करें
उपकरणएक्सप्लॉइटब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

फ़ीडसंपर्कगोपनीयता© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
CVE-2026-31413-BPF-Container-Escape — CVE-2026-31413: BPF वेरिफायर साउंडनेस बग - कंटेनर एस्केप | Kitploit
उपकरण/GitHubGitHub/rat5ak/cve-2026-31413-bpf-container-escape
विशेषाधिकार वृद्धिभेद्यता विश्लेषणशोषणपोस्ट-शोषणपेपर और शोधलर्निंग और शिक्षाकंटेनर एस्केपबाइनरी शोषण

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें
GitHub
rat5ak/cve-2026-31413-bpf-container-escape

CVE-2026-31413-BPF-Container-Escape

CVE-2026-31413: BPF वेरिफायर साउंडनेस बग - कंटेनर एस्केप

रिपॉजिटरी देखें
11165 महीने पहलेअभी तक समीक्षित नहीं

CVE-2026-31413: BPF वेरिफायर में एक बाइट से कंटेनर एस्केप तक

मुझे Linux BPF वेरिफायर में एक साउंडनेस बग मिला - एक push_stack() कॉल में + 1, जिसके कारण वेरिफायर फोर्क किए गए पथ पर एक ALU निर्देश को स्किप कर देता है। BPF_OR के लिए, इसका मतलब है कि वेरिफायर dst = 0 ट्रैक करता है जबकि CPU 0 | K = K की गणना करता है। मैंने एक पूर्ण कंटेनर एस्केप लिखा: BPF मैप से OOB रीड/राइट, vtable हाइजैक, modprobe_path ओवरराइट, होस्ट पर रूट। फिर मैंने दो-पैच श्रृंखला बनाई - एक-अक्षर वाला वेरिफायर फिक्स और 90 लाइनों के selftests - और इसे मुख्यलाइन (mainline) में मर्ज करवाया।

📹 कंटेनर एस्केप डेमो वीडियो

CVECVE-2026-31413
बग वर्गVerifier soundness - रजिस्टर मान विचलन
मूल कारणpush_stack(env, env->insn_idx + 1, ...) फोर्क किए गए पथ पर ALU निर्देश को स्किप करता है
प्रस्तुतbffacdb80b93 - Linux 7.0-rc1 (Jan 14, 2026)
फिक्स्डc845894ebd6f - Linux 7.0-rc5 (Mar 22, 2026)
प्रभावित6.12.75+ (stable backport dea9989a3f) से 7.0-rc4 तक
प्रभावमनमाना kernel R/W → कंटेनर एस्केप → होस्ट रूट
आवश्यकCAP_BPF + CAP_PERFMON + CAP_NET_ADMIN
फिक्सएक अक्षर: insn_idx + 1 → insn_idx

TL;DR

maybe_fork_scalars() जब ARSH + AND/OR को किसी constant के साथ देखता है तो वेरिफायर स्थिति (state) को फोर्क करता है। पुश किए गए पथ को dst = 0 मिलता है और वह ALU निर्देश को स्किप कर देता है। AND के लिए यह ठीक है: 0 & K = 0। OR के लिए यह गलत है: 0 | K = K, न कि 0।

वेरिफायर सोचता है कि रजिस्टर शून्य है। CPU के पास K है। मैंने इसका उपयोग BPF मैप वैल्यू से मनमाना OOB रीड/राइट बनाने, मैप का कर्नेल पता लीक करने, एक नकली bpf_map_ops vtable बनाने, map_push_elem को array_map_get_next_key के माध्यम से मनमाने राइट के लिए रीडायरेक्ट करने, और modprobe_path को ओवरराइट करने के लिए किया। अज्ञात बाइनरी फॉर्मेट ट्रिगर करें, कर्नेल मेरी स्क्रिप्ट को रूट के रूप में चलाता है। कंटेनर में, पूर्ण होस्ट एस्केप।

दो-पैच श्रृंखला: एक-अक्षर वाला वेरिफायर फिक्स और 90 लाइनों के BPF selftests जो OR बनाम AND फोर्किंग को कवर करते हैं। 22 मार्च को Alexei Starovoitov द्वारा मर्ज किया गया। CVE-2026-31413 12 अप्रैल को Greg Kroah-Hartman द्वारा निर्धारित किया गया।


पृष्ठभूमि: BPF वेरिफायर

eBPF आपको कर्नेल में छोटे प्रोग्राम लोड करने देता है - पैकेट फिल्टर, ट्रेसिंग हुक, सुरक्षा नीतियां - बिना कर्नेल मॉड्यूल कंपाइल किए। पकड़ यह है कि आप ring 0 में कोड इंजेक्ट कर रहे हैं। अगर उस कोड में बग है, तो वह कर्नेल बग है।

इसलिए किसी भी BPF प्रोग्राम के चलने से पहले, कर्नेल का वेरिफायर हर संभव निष्पादन पथ का अनुकरण करता है। यह ट्रैक करता है कि प्रत्येक रजिस्टर में क्या है (एक पॉइंटर? एक स्केलर? कौन सी रेंज?), हर मेमोरी एक्सेस को मैप बाउंड्स के विरुद्ध जांचता है, और किसी भी चीज़ को अस्वीकार करता है जो बाउंड्स से बाहर पढ़ या लिख सकती है। यदि वेरिफायर कहता है कि प्रोग्राम सुरक्षित है, तो JIT इसे नेटिव मशीन कोड में कंपाइल करता है और पूर्ण कर्नेल विशेषाधिकार के साथ चलाता है। उस बिंदु के बाद कोई रनटाइम बाउंड्स जांच नहीं होती। वेरिफायर ही सुरक्षा सीमा है।

इसीलिए वेरिफायर साउंडनेस बग सामान्य मेमोरी करप्शन से अलग होते हैं। हीप ओवरफ्लो या UAF के साथ, आपको एक करप्शन प्रिमिटिव मिलता है और वहाँ से काम करना होता है - हीप स्प्रे करें, ऑब्जेक्ट्स को ग्रूम करें, एक विंडो के लिए रेस करें। वेरिफायर बग के साथ, आप कर्नेल को रजिस्टर के मान के बारे में झूठ पर विश्वास करवाते हैं। हर बाउंड्स जांच जो उस रजिस्टर पर निर्भर करती है, पास हो जाती है। कर्नेल ने आपकी OOB एक्सेस को मंजूरी दे दी। वह इसे बिना प्रश्न के चलाता है। यदि आप रजिस्टर स्थिति को सही ढंग से संरेखित कर सकते हैं, तो आपको इससे एक स्वच्छ और विश्वसनीय प्रिमिटिव मिलता है।

मैंने इसे कैसे पाया

मैं maybe_fork_scalars() का ऑडिट कर रहा था - नया कोड, जनवरी 2026 में bffacdb80b93 में जोड़ा गया। स्टेट फोर्किंग हमेशा दिलचस्प होती है क्योंकि यहीं वेरिफायर समानांतर अन्वेषण पथों में विभाजित होता है, और यदि कोई पथ गलत मान ट्रैक करता है, तो उस पथ के नीचे की हर चीज़ असाउंड (unsound) होती है।

फ़ंक्शन तब फोर्क करता है जब वह किसी constant स्रोत के साथ ARSH + AND/OR देखता है। पुश किए गए पथ को dst = 0 मिलता है, और वह ALU निर्देश को स्किप कर देता है। मैं push_stack(env, env->insn_idx + 1, ...) लाइन पढ़ रहा था और यह तुरंत समझ में आ गया - + 1 का मतलब है कि पुश किया गया पथ ALU ऑप को कभी निष्पादित नहीं करता। AND के लिए, 0 & K = 0, इसलिए स्किप करना ठीक है। OR के लिए, 0 | K = K। पुश किए गए पथ को लगता है कि परिणाम 0 है जबकि वास्तव में यह K है।

मैंने उसी शाम एक BPF प्रोग्राम लिखा। {0, -1} पाने के लिए ARSH 63, एक constant के साथ OR, वेरिफायर पथों को अलग करने के लिए सशर्त शाखा, फिर "शून्य" रजिस्टर को एक मैप पॉइंटर में जोड़ा। वेरिफायर ने map_value + 0 को मंजूरी दी। CPU ने map_value + K तक पहुँच बनाई। KASAN ने परीक्षण में आउट-ऑफ-बाउंड्स एक्सेस की पुष्टि की।

अगली सुबह तक OOB रीड/राइट। अगली रात तक कंटेनर एस्केप। मैंने पूरे समय Claude (Opus 4.5) का उपयोग किया - वेरिफायर की स्टेट फोर्किंग लॉजिक को समझने, एक्सप्लॉइटेशन प्रिमिटिव्स पर विचार-मंथन करने, और OOB को पूर्ण एस्केप चेन में बदलने के लिए। vtable हाइजैक दृष्टिकोण एक विचार-विमर्श से उभरा, जिसमें Claude ने bpf_map_ops फंक्शन पॉइंटर्स की समीक्षा की, कॉल करने योग्य गैजेट्स की तलाश में।

बग पेश करने वाला कमिट

कमिट bffacdb80b93 ("bpf: Recognize special arithmetic shift in the verifier") 14 जनवरी, 2026 को 7.0-rc1 में आया। Alexei Starovoitov, Puranjay Mohan द्वारा सह-विकसित। इसने एक LLVM DAGCombiner पैटर्न को संभालने के लिए maybe_fork_scalars() जोड़ा:``` w2 s>>= 31 // arithmetic shift right: w2 becomes 0 or -1 w2 &= -134 // AND with constant K

LLVM `select_cc setlt X, 0, A, 0` को `sra + and` में बदलता है। अंकगणितीय
दायाँ शिफ्ट के बाद, रजिस्टर या तो `0` (गैर-ऋणात्मक इनपुट) या `-1` (सभी एक) होता है।
एक स्थिरांक के साथ AND देता है `0` या `K`।

वेरिफायर एकल `bpf_reg_state` में `{0, K}` को ट्रैक नहीं कर सकता - इसकी साइन्ड रेंज
`[0, K]` अति-अनुमानित करती है, और इसी कारण यह मान्य Cilium
प्रोग्रामों को अस्वीकार कर रहा था। समाधान: वेरिफायर स्थिति को फोर्क करें। एक पथ `dst = 0` का अन्वेषण करता है, दूसरा
`dst = -1`, प्रत्येक सटीक मान का ट्रैक रखता है।

कार्यान्वयन:```c
static int maybe_fork_scalars(struct bpf_verifier_env *env,
                              struct bpf_insn *insn,
                              struct bpf_reg_state *dst_reg)
{
    // ... condition check: dst range is [-1, 0], src is constant ...

    branch = push_stack(env, env->insn_idx + 1, env->insn_idx, false);
    //                             ^^^^^^^^^^^^
    //                    pushed path resumes AFTER the ALU insn
    if (IS_ERR(branch))
        return PTR_ERR(branch);

    regs = branch->frame[branch->curframe]->regs;
    __mark_reg_known(&regs[insn->dst_reg], 0);   // pushed: dst = 0
    __mark_reg_known(dst_reg, -1ull);             // current: dst = -1
    return 0;
}

पुश किए गए पथ पर दो चीज़ें होती हैं:

  1. गंतव्य रजिस्टर 0 पर सेट हो जाता है
  2. निष्पादन insn_idx + 1 पर फिर से शुरू होता है - ALU op के बाद वाला निर्देश

BPF_AND के लिए: dst = 0, AND को छोड़ें। रनटाइम: 0 & K = 0। मेल खाता है। सुदृढ़।

BPF_OR के लिए: dst = 0, OR को छोड़ें। रनटाइम: 0 | K = K। बेमेल। वेरिफ़ायर 0 देखता है। CPU के पास K है। असुदृढ़।

फ़ंक्शन opcode की जाँच नहीं करता। इसे AND के लिए लिखा गया था - जहाँ निर्देश को छोड़ना उसे dst = 0 के साथ निष्पादित करने के समान है - और इसे OR पर भी लागू कर दिया गया। OR के लिए, यह समतुल्यता मान्य नहीं है।

विचलन को ट्रिगर करना

ट्रिगर पैटर्न पाँच निर्देशों का है:``` r6 = (u64)(map_value + 0) // load a positive value (guaranteed by map init) r6 s>>= 63 // arithmetic shift: r6 = 0 (positive input) r6 |= K // BUG: verifier forks, pushed path gets r6=0 if r6 s< 0 goto exit // steers verifier paths r9 += r6 // verifier: r9 += 0 (in-bounds) // runtime: r9 += K (OOB)

वेरिफायर दो पथों का अन्वेषण करता है:
टूल डाउनलोड करें