
शैक्षिक प्रूफ-ऑफ-कॉन्सेप्ट CVE-2024-4947 के लिए, जो एक V8 Maglev टाइप कन्फ्यूजन है, जो गैर-सैंडबॉक्स्ड d8 बिल्ड पर ट्रिगर से मनमाने कोड निष्पादन (arbitrary code execution) तक की पूरी श्रृंखला प्रदर्शित करता है।
CVE-2024-4947 (V8 Maglev टाइप कन्फ्यूज़न) के लिए एक पूर्ण, स्व-निहित शोषण श्रृंखला, प्रारंभिक टाइप-कन्फ्यूज़न ट्रिगर से लेकर मनमाना कोड निष्पादन तक। यह PoC एक गैर-सैंडबॉक्स्ड d8 बिल्ड के विरुद्ध चलता है और कोड निष्पादन के प्रमाण के रूप में CVE-2024-4947-PWNED को stdout पर प्रिंट करता है।
⚠️ यह एक पैच किए गए, सार्वजनिक भेद्यता के लिए शोध / शैक्षिक PoC है। यह V8 शेल (
d8 --allow-natives-syntax) के डेवलपमेंट बिल्ड को लक्षित करता है — न कि वास्तविक Chrome ब्राउज़र को। अस्वीकरण देखें।
$ ./v8-build-nosandbox.sh # build the vulnerable d8 (WSL2 Ubuntu, ~10-20 min)
$ d8 --allow-natives-syntax --module exploit/exploit_rce.mjs
[engine] dblData0=0004f470 class=0
[inst] addr=0x001dc274 trusted_data(tagged)=0x00202bd5 td=0x00202bd4
[jt] jump_table_start = 0x00000967426cd000 (external code space)
[bridge] memory0_start -> jt, memory0_size -> huge (r/w reach jt+off)
[slot0] before: e9 3b 08 00 00
[shell] wrote 52 bytes @ jt+0x0100: VERIFIED
CVE-2024-4947-PWNED
$ echo $? # 0
52-बाइट शेलकोड write(1, "CVE-2024-4947-PWNED\n", 20); exit_group(0) है।
CVE-2024-4947, V8 Maglev JIT कंपाइलर में एक टाइप कन्फ्यूज़न है, जिसे Chrome 125.0.6422.60 (कमिट b3c01ac1e60a) में ठीक किया गया था। इसका वास्तविक दुनिया में Lazarus APT समूह द्वारा शोषण किया गया था। जब Maglev किसी मॉड्यूल नेमस्पेस ऑब्जेक्ट (JSModuleNamespace) पर स्टोर कंपाइल करता है, तो वह एक गलत AccessInfo का उपयोग करता है — स्टोर को एक साधारण mov [[obj + 4], rax] के रूप में कंपाइल किया जाता है जो उचित प्रॉपर्टी-स्टोर पथ से गुज़रने के बजाय एक आसन्न ऑब्जेक्ट के map फ़ील्ड में नियंत्रित मान लिखता है।
शोषण निम्न प्रकार से आगे बढ़ता है:
NAME_DICTIONARY_TYPE (0xB2) map में भ्रष्ट करना, जिससे V8 ऑब्जेक्ट का हैश कहाँ संग्रहीत करता है, बदल जाता है।new WeakRef(...) को ट्रिगर करना ताकि हैश राइट आसन्न ऑब्जेक्ट के length स्लॉट में पहुँचे → आउट-ऑफ-बाउंड्स एक्सेस।वहाँ से हमें क्लासिक V8 टूलकिट मिलता है: addrOf/fakeObj, फिर केज के भीतर मनमाना read/write।
CVE-2024-4947 trigger (fake NAME_DICTIONARY map + WeakRef hash write)
└─► OOB write ─► corrupt doubleArray length
└─► in-cage 4/8-byte arbitrary R/W (the "engine")
└─► overwrite WasmTrustedInstanceData.memory0_start (+0x18)
& memory0_size (+0x20) → huge
└─► wasm load8_u / store8 = clean 64-bit R/W bridge
(no software bounds check in compiled code)
└─► read jump_table_start (+0x38) — external code space
└─► jump table region is RWX (this build)
└─► write shellcode into the slack (jt+0x100)
└─► repoint func0's `e9 rel32` slot at it
└─► call func0 → shellcode → RCE
| # | चरण | विवरण |
|---|---|---|
| 1 | ट्रिगर | opt() भ्रमित स्टोर के माध्यम से एक नकली map लिखता है; new WeakRef(m) corruptArray.length को OOB करता है। |
| 2 | इंजन | addrOf/fakeObj; doubleArray की length भ्रष्ट करें → किसी भी 4-संरेखित केज पते पर मनमाना 4-बाइट R/W। |
| 3 | 64-बिट ब्रिज | WasmTrustedInstanceData.memory0_start (+0x18) एक रॉ 64-बिट पॉइंटर है जिसका उपयोग कंपाइल किए गए wasm i32.load8_u/i32.store8 बिना किसी सॉफ़्टवेयर बाउंड्स चेक के करते हैं (सीमा से बाहर जाने पर गार्ड पेज हिट होता है → SIGSEGV → wasm ट्रैप)। इसे किसी भी पते पर पुनर्निर्देशित करें + memory0_size (+0x20) को विशाल सेट करें → मनमाना 64-बिट R/W। |
| 4 | कोड स्पेस खोजें | jump_table_start (+0x38) बाहरी कोड स्पेस (4 GB केज के बाहर) में एक रॉ 64-बिट पॉइंटर है। |
| 5 | शेलकोड लिखें | इस बिल्ड पर जंप-टेबल क्षेत्र RWX है (V8 रनटाइम पर एंट्रीज़ पैच करता है): 52-बाइट शेलकोड को jt+0x100 पर स्लैक में लिखें। |
| 6 | स्लॉट पुनर्निर्देशित करें | func0 का जंप-टेबल स्लॉट एक 5-बाइट e9 <rel32> है (लक्ष्य = स्लॉट + 5 + rel32)। rel32 → jt+0x100 सेट करें। |
| 7 | डिस्पैच ट्रिगर करें | inst.exports.r(0) → JSToWasmWrapper स्लॉट 0 के माध्यम से डिस्पैच करता है → शेलकोड निष्पादित होता है। |
अधिकांश सार्वजनिक CVE-2024-4947 PoCs सैंडबॉक्स्ड d8 या वास्तविक Chrome रेंडरर (v8_enable_sandbox=true) को लक्षित करते हैं और टाइप-कन्फ्यूज़न / OOB प्रिमिटिव पर रुक जाते हैं। यह PoC एक नो-सैंडबॉक्स d8 को लक्षित करता है और श्रृंखला को कोड निष्पादन तक पूरी तरह ले जाता है। जो अंतर मायने रखते हैं:
| आयाम | सामान्य सार्वजनिक-PoC दृष्टिकोण | यह PoC |
|---|---|---|
| लक्ष्य बिल्ड | सैंडबॉक्स्ड d8 / Chrome रेंडरर | v8_enable_sandbox=false d8 — विश्वसनीय पॉइंटर्स सीधे होते हैं, बाहरी कोड स्पेस चालू है |
| 64-बिट R/W ब्रिज | JSTypedArray.external_pointer अधिलेखित करें | यह पथ कोड रेंज पढ़ते समय क्रैश करता है (अनुभवजन्य रूप से सत्यापित); इसके बजाय memory0_start अधिलेखित करें और रॉ wasm load/store का उपयोग करें |
| अंतिम कोड-निष्पादन मार्ग | कोड स्पेस W^X है → JIT-spray + अप्रत्यक्ष पुनर्निर्देशन | जंप-टेबल क्षेत्र RWX है → सीधा शेलकोड राइट + e9 rel32 स्लॉट पैच |
| जंप-टेबल स्लॉट प्रारूप | दस्तावेज़ आमतौर पर movabs rax, imm64; jmp rax (12 बाइट) मानते हैं | मापा गया: 5-बाइट e9 <rel32>, लक्ष्य = स्लॉट + 5 + rel32 |
| फ़ील्ड ऑफ़सेट्स | सैंडबॉक्स्ड-बिल्ड लेआउट | नो-सैंडबॉक्स WasmTrustedInstanceData: jump_table_start@+0x38, memory0_start@+0x18, memory0_size@+0x20; WasmInstanceObject.trusted_data@+0x0c |
| स्वच्छ निकास | — | d8 मल्टी-थ्रेडेड है: exit (60) नहीं, बल्कि exit_group (231) का उपयोग करना आवश्यक है, अन्यथा प्रक्रिया हैंग हो जाती है |
प्रत्येक पंक्ति के पीछे के अनुभवजन्य निष्कर्षों सहित पूर्ण तकनीकी विवरण के लिए docs/walkthrough.md देखें।
.
├── exploit/
│ ├── Module.mjs # module namespace object corrupted by the trigger
│ ├── exploit_rce.mjs # the full chain (trigger → arbitrary R/W → RCE)
│ └── shellcode.S # assembly source for the 52-byte payload
├── build/
│ └── v8-build-nosandbox.sh # build the vulnerable no-sandbox d8 from V8 source
└── docs/
└── walkthrough.md # deep dive: bridge mechanics, layouts, gotchas
एक्सप्लॉइट Module.mjs (कमज़ोर मॉड्यूल नेमस्पेस ऑब्जेक्ट) को अपनी निर्देशिका से इम्पोर्ट करता है, इसलिए दोनों फ़ाइलों को एक साथ रखें (या import पथ समायोजित करें)।
git और ~10 GB खाली डिस्क वाला कोई भी Linuxdepot_tools (git clone https://chromium.googlesource.com/chromium/tools/depot_tools)# 1. fetch V8 at the vulnerable tag (12.4.254.16 is the pre-fix release)
export PATH="$HOME/depot_tools:$PATH"
cd ~/v8w && fetch v8 && cd v8
git checkout 12.4.254.16 # or the commit just before b3c01ac1e60a
# 2. first build a normal release d8 (needed to seed args.gn), then:
./v8-build-nosandbox.sh # copies args.gn and appends v8_enable_sandbox = false
v8-build-nosandbox.sh ninja -C out.gn/x64.release_nosandbox -j6 d8 का उपयोग करता है।
out.gn/x64.release_nosandbox/d8 --allow-natives-syntax --module exploit/exploit_rce.mjs
अपेक्षित आउटपुट इसके साथ समाप्त होता है:
CVE-2024-4947-PWNED
और प्रक्रिया स्थिति 0 के साथ समाप्त होती है।
%PrepareFunctionForOptimization/%OptimizeMaglevOnNextCallरनटाइम कॉल्स के लिए--allow-natives-syntaxआवश्यक है। यही कारण है कि यह PoC वास्तविक ब्राउज़र में नहीं चल सकता — यह डिज़ाइन द्वारा एक d8 शेल प्रूफ-ऑफ-कॉन्सेप्ट है।
V8 शोषण शोध के लिए वास्तव में पुन: उपयोग योग्य (और गैर-स्पष्ट) भाग:
JSTypedArray.external_pointer पुनर्निर्देशन विफल हो जाता है, तो इसके बजाय WasmTrustedInstanceData.memory0_start को पुनर्निर्देशित करें। कंपाइल किए गए wasm बाइट load/store में कोई सॉफ़्टवेयर बाउंड्स चेक नहीं होता; सिग्नल ट्रैप हैंडलर केवल गार्ड-पेज फॉल्ट को परिवर्तित करता है, इसलिए मैप किए गए-लेकिन-गैर-लिखने योग्य क्षेत्र ट्रैप करने के बजाय क्रैश करते हैं।try/catch के साथ इसे बाइट-दर-बाइट जाँचें; wasm "आउट ऑफ बाउंड्स" ट्रैप का अर्थ है गार्ड पेज (अनमैप्ड), वास्तविक SIGSEGV का अर्थ है मैप्ड-लेकिन-RX।e9 rel32 स्लॉट प्रारूप — 5-बाइट रिलेटिव जंप, न कि कई राइट-अप्स द्वारा माना गया movabs रूप। --print-wasm-code डिसअसेंबली के विरुद्ध सत्यापित।यह रिपॉज़िटरी केवल शैक्षिक और रक्षात्मक-सुरक्षा शोध के लिए प्रदान की गई है। यह एक डेवलपमेंट-ओनली V8 बिल्ड के विरुद्ध पैच की गई भेद्यता के शोषण को प्रदर्शित करती है। यह आधुनिक Chrome के विरुद्ध कोई हथियार नहीं है, V8 सैंडबॉक्स को बायपास नहीं करती है, और गैर-डिफ़ॉल्ट --allow-natives-syntax फ़्लैग की आवश्यकता होती है। लेखक किसी भी दुरुपयोग के लिए ज़िम्मेदार नहीं है।
ट्रिगर प्रिमिटिव (नकली NAME_DICTIONARY_TYPE map + WeakRef हैश राइट) पैच के बाद प्रकाशित वास्तविक दुनिया के Lazarus एक्सप्लॉइट के सार्वजनिक विश्लेषणों का अनुसरण करता है — जिसमें Google और Exodus Intelligence के CVE-2024-4947 राइट-अप्स शामिल हैं। बाद के चरण (जंप-टेबल जाँच, ब्रिज, स्लॉट पैचिंग) इस कार्य के दौरान इस विशिष्ट बिल्ड के विरुद्ध अनुभवजन्य रूप से व्युत्पन्न किए गए थे। JIT-spray फ़ॉलबैक अवधारणा सार्वजनिक V8 शोषण तकनीकों (जैसे CVE-2024-5830 make_array पैटर्न) से ली गई है।
MIT — LICENSE देखें।