
DirtyFrag Linux LPE श्रृंखला (CVE-2026-43284 / CVE-2026-43500) को Cilium Tetragon TracingPolicy के साथ रनटाइम पर अवरुद्ध करना
Cilium Tetragon TracingPolicy के साथ रनटाइम पर DirtyFrag Linux विशेषाधिकार-वृद्धि श्रृंखला (CVE-2026-43284 / CVE-2026-43500) को अवरुद्ध करना। नीति सार्वजनिक प्रूफ-ऑफ-कॉन्सेप्ट को उसके सॉकेट-सेटअप चरण पर SIGKILL करती है, इससे पहले कि वह पेज-कैश राइट तक पहुँचे जो इसे रूट देगा।
यह क्या है। एक प्रयोगशाला रिपोर्ट। मैंने पहली बार Tetragon सेट किया और देखना चाहता था कि क्या यह वास्तव में एक वास्तविक, वर्तमान कर्नेल LPE को रोक सकता है। यह कर सकता है। यह दस्तावेज़ करता है कि मैंने वास्तव में क्या चलाया, क्या हुआ, और उतना ही महत्वपूर्ण, यह क्या साबित करता है इसकी सीमाएँ। यह पैचिंग का विकल्प नहीं है।
फ़ाइलें: यह README (स्व-निहित, साक्ष्य इनलाइन) · block-dirtyfrag.yaml (नीति)
| शोषण | DirtyFrag - सार्वजनिक PoC: V4bel/dirtyfrag |
| CVE | CVE-2026-43284 (xfrm-ESP पेज-कैश राइट), CVE-2026-43500 (RxRPC पेज-कैश राइट) |
| होस्ट | Ubuntu 24.04.4 LTS, Tetragon v1.7.0 (स्टैंडअलोन, systemd) |
आधार रेखा - कोई नीति नहीं, कर्नेल 6.8.0-88 (असुरक्षित) | PoC → uid=0(root) |
नीति के साथ - कर्नेल 6.8.0-88 | PoC SIGKILL socket(AF_RXRPC) पर; उपयोगकर्ता uid=1000 रहता है |
पैच किया गया कर्नेल 6.8.0-134 | PoC अपने आप विफल हो जाता है (rc=4); सॉकेट हुक अभी भी चालू होता है, पहचान, शमन नहीं (नोट) |
| नियंत्रण की प्रकृति | प्रतिपूरक नियंत्रण / वर्चुअल पैच, कर्नेल फिक्स नहीं है |
DirtyFrag एक स्थानीय विशेषाधिकार-वृद्धि श्रृंखला है जो लिनक्स कर्नेल में दो स्वतंत्र पेज-कैश राइट प्रिमिटिव से बनी है: एक xfrm/ESP (IPsec) इन-प्लेस डिक्रिप्शन पथ में (CVE-2026-43284), और एक RxRPC पथ में (CVE-2026-43500)। प्रत्येक एक अविशेषाधिकार प्राप्त स्थानीय उपयोगकर्ता को रीड-ओनली पेज-कैश पृष्ठों में हमलावर-नियंत्रित बाइट्स लिखने की अनुमति देता है, उदाहरण के लिए एक setuid-root बाइनरी जैसे /bin/su की कैश की गई छवि - और वहाँ से रूट प्राप्त करता है। राइट केवल मेमोरी में होता है; डिस्क पर फ़ाइल कभी संशोधित नहीं होती है, इसलिए फ़ाइल-अखंडता निगरानी कुछ नहीं देखती है। यह डर्टी पाइप और कॉपी फेल के समान बग वर्ग है। दोनों CVE जानबूझकर श्रृंखलाबद्ध हैं: यदि एक पथ किसी दिए गए वातावरण में अनुपलब्ध है, तो दूसरा अभी भी काम करता है।
इस होस्ट पर, अविशेषाधिकार प्राप्त उपयोगकर्ता नामस्थान AppArmor द्वारा प्रतिबंधित हैं (kernel.apparmor_restrict_unprivileged_userns = 1), जो श्रृंखला के ESP आधे को अवरुद्ध करता है। यह RxRPC पथ छोड़ता है, जो एक AF_RXRPC सॉकेट (पता परिवार 33) खोलता है - और यह वह कदम है जो यह नीति मारती है।
असली फिक्स एक पैच किया गया कर्नेल है। यहाँ सब कुछ एक होस्ट के लिए अस्थायी उपाय है जिसे आप अभी तक पैच नहीं कर सकते। Ubuntu ने इस परीक्षण से कुछ समय पहले DirtyFrag फिक्स जारी किए, इसलिए यह एक ज्ञात N-day है, लाइव 0-day नहीं - बिंदु यह दिखाना है कि एक रनटाइम नियंत्रण एक होस्ट पर क्या कर सकता है जो अभी भी, किसी भी कारण से, एक असुरक्षित कर्नेल चला रहा है।
पूर्ण नीति: block-dirtyfrag.yaml। यह दो kprobes स्थापित करता है।
हुक 1 - सॉकेट्स को ग्रूम करना (sys_socket). भार-वहन नियंत्रण। शोषण का RxRPC पथ हर बार socket(AF_RXRPC, …) को कॉल करना चाहिए, चाहे कोई कर्नेल मॉड्यूल पहले से लोड हो या न हो। नीति पता परिवार पर मेल खाती है:
AF_RXRPC) → Sigkill. किसी भी होस्ट पर जो AFS क्लाइंट नहीं है, प्रभावी रूप से कुछ भी वैध AF_RXRPC सॉकेट नहीं खोलता है, इसलिए यहाँ एक सामान्य हत्या सुरक्षित और उच्च-विश्वास है।AF_ALG) → Post (केवल ऑडिट, कोई हत्या नहीं)। AF_ALG उपयोगकर्तास्पेस कर्नेल-क्रिप्टो API है और इसके वैध उपयोगकर्ता हैं (cryptsetup, libkcapi टूलिंग, कुछ FIPS वर्कफ़्लोज़)। केवल परिवार के आधार पर हत्या गलत सकारात्मकता का कारण बनेगी, इसलिए यह चरण केवल लॉग करता है। प्रवर्तन का मार्ग है: कुछ समय के लिए ऑडिट करें, वास्तव में देखी गई बाइनरी से NotIn अनुमति सूची बनाएं, फिर Sigkill में अपग्रेड करने पर विचार करें।हुक 2 - असुरक्षित मॉड्यूल ऑटोलोड (security_kernel_module_request). गहराई में रक्षा। तब सक्रिय होता है जब कर्नेल को एक असुरक्षित मॉड्यूल परिवार को ऑटो-लोड करने के लिए कहा जाता है (esp4, esp6, rxrpc, net-pf-33/net-pf-38 सॉकेट उपनाम, pcbc/fcrypt क्रिप्टो टेम्पलेट्स)। सीमा: यह केवल तब सक्रिय होता है जब मॉड्यूल पहले से मौजूद नहीं है — बूट में पहले शोषण रन के बाद, वे मॉड्यूल लोड हो जाते हैं और यह हुक खामोश हो जाता है। यह एक कोल्ड-बूट परत है, प्राथमिक नियंत्रण नहीं।
एक साथ: हुक 1 शोषण को पकड़ता है चाहे मॉड्यूल गर्म हों या ठंडे; हुक 2 एक ठंडे होस्ट पर पहले, अधिक विशिष्ट ट्रिप जोड़ता है।
6.8.0-88-generic पर है, जो असुरक्षित है (आधार रेखा रूट तक पहुँचती है)। बॉक्स में 6.8.0-134-generic भी स्थापित है — पैच किया गया कर्नेल — और इसकी सीधे पुष्टि की गई: -134 में रिबूट करने पर PoC अपने आप विफल हो जाता है (rc=4, कोई रूट नहीं), नीति के साथ या बिना (नीचे नोट देखें)। शमन डेमो को पुन: पेश करने के लिए, GRUB से 6.8.0-88 बूट करें (यह अभी भी स्थापित है) — किसी भी पैच किए गए कर्नेल पर शमन करने के लिए कुछ नहीं है।AF_ALG चरण।lockdown,capability,landlock,yama,apparmor — कोई bpf नहीं)। इसलिए प्रवर्तन kprobe से Sigkill का उपयोग करता है, इन-कर्नेल LSM अस्वीकार नहीं। हत्या socket() सिस्कॉल पर होती है — राइट प्रिमिटिव से पहले — इसलिए यह प्रक्रिया को अनिवार्य प्रारंभिक चरण में समाप्त करता है न कि "भेद्यता को अवरुद्ध" करके।चरण 1–5 सभी एक ही 6.8.0-88 बूट से हैं (असुरक्षित कर्नेल)।
1. वातावरण - Ubuntu 24.04.4, कर्नेल 6.8.0-88-generic, Tetragon v1.7.0 systemd के तहत सक्रिय, अविशेषाधिकार प्राप्त userns प्रतिबंधित।
$ uname -r
6.8.0-88-generic
$ tetra version
CLI version: v1.7.0
$ systemctl is-active tetragon
active
2. पूर्व शर्तें (नीति बंद) - स्वच्छ प्रारंभ बिंदु: कोई असुरक्षित मॉड्यूल मौजूद नहीं, कोई xfrm स्थिति नहीं, कोई नीति लोड नहीं।
$ lsmod | grep -E 'esp4|esp6|rxrpc' || echo "(none loaded)"
(none loaded)
$ sudo ip xfrm state # (empty)
$ sudo tetra tp list
ID NAME STATE FILTERID NAMESPACE SENSORS KERNELMEMORY MODE NPOST NENFORCE NMONITOR
3. आधार रेखा (नीति बंद) - शोषण काम करता है। यह साबित करता है कि कर्नेल वास्तव में असुरक्षित है; पूरी रिपोर्ट इसी पर टिकी है।
$ ./exp ; id
uid=0(root) gid=0(root) groups=0(root)
4. नीति लोड करें।
$ sudo tetra tp add /etc/tetragon/tetragon.tp.d/block-dirtyfrag.yaml
tracing policy "…/block-dirtyfrag.yaml" added
5. प्रवर्तित (नीति चालू) - हत्या। शोषण socket() कॉल पर सिग्नल द्वारा समाप्त हो जाता है और su तक कभी नहीं पहुँचता:
🚀 process /home/…/dirtyfrag/exp
❓ syscall /home/…/dirtyfrag/exp __x64_sys_socket
Kernel:
0x0: __x64_sys_socket+0x5
0x0: do_syscall_64+0x7f
0x0: entry_SYSCALL_64_after_hwframe+0x78
💥 exit /home/…/dirtyfrag/exp SIGKILL
संरचित घटना मैच और हत्या दोनों की पुष्टि करती है - सॉकेट सिस्कॉल पर एक process_kprobe, फिर उसी PID के लिए सिग्नल द्वारा process_exit:
// process_kprobe — AF_RXRPC मैच
{ "process_kprobe": {
"process": { "pid": 24083, "uid": 1000, "binary": ".../dirtyfrag/exp" },
"function_name": "__x64_sys_socket",
"args": [ { "int_arg": 33, "label": "family" } ],
"policy_name": "block-dirtyfrag",
"action": "KPROBE_ACTION_POST"
} }
// process_exit — वही PID, सिग्नल द्वारा मारा गया
{ "process_exit": {
"process": { "pid": 24083, "binary": ".../dirtyfrag/exp" },
"signal": "SIGKILL"
} }