
CVE-2026-32740 Next.js/sharp लीक-टू-memcpy-GOT RCE श्रृंखला के लिए निजी Fortbridge PoC
कार्यशील proof of concept जो hardcoded Next.js/sharp image stack में CVE-2026-32740 को chosen-address write और validated /usr/bin/id callback में बदल देता है।
यह एक private Fortbridge research repository है। इसका उपयोग केवल शामिल lab या किसी अन्य सिस्टम के विरुद्ध करें जिसे परीक्षण के लिए आपको स्पष्ट रूप से अधिकृत किया गया है।
exploit केवल target के HTTP upload और image-optimization routes का उपयोग करता है:
g_module_open_full की आंतरिक प्रति का उपयोग करता है, जो एक GModule routine है जो dlopen को wrap करती है ताकि किसी file path से native shared library load की जा सके। exploit इसके runtime address की गणना recovered libvips base और hardcoded profile offset 0x3e995e के योग के रूप में करता है। library load करने पर उसका constructor चलता है।/usr/bin/id चलाता है। यह उस ELF को public upload route के माध्यम से image name x.jpg और media type image/jpeg के अंतर्गत भेजता है।memcpy@GOT - 16 पर redirect करता है।uploads/x.jpg को GOT slot से ठीक पहले store करती है और memcpy@GOT को derived GModule loader से बदल देती है। अगली row उस loader को पहले से RDI में मौजूद library path के साथ call करती है।/usr/bin/id का output लौटाता है। एक per-attempt token किसी stale callback को success के रूप में गिने जाने से रोकता है; लौटाई गई uid=... line ही proof है।मूल libvips-relative validation runs
evidence/libvips-gmodule-rce-10x.json में दर्ज हैं।
सभी दस fresh processes ने दस भिन्न randomized libvips bases और दस स्वतंत्र रूप से derived loader addresses के साथ valid /usr/bin/id output लौटाया।
सटीक Ubuntu run data
evidence/libvips-gmodule-pie-rce-10x.json में हैं।
सटीक Debian 13 APT run data
evidence/debian13-apt-libvips-gmodule-rce-10x.json में हैं।
हमने पूर्ण exploit का परीक्षण 10 नए शुरू किए गए Ubuntu Node processes और 10 नए शुरू किए गए Debian Node processes के विरुद्ध किया। सभी 20 runs ने command execution तक पहुँच बनाई और target का /usr/bin/id output लौटाया। exploit ने प्रत्येक randomized libvips base के लिए एक भिन्न GModule-loader address की भी गणना की।
अंतिम payload बनाने से पहले, exploit को कई ASLR-leak attempts की आवश्यकता हो सकती है। प्रत्येक attempt leak AVIF upload करता है, उसे optimisation route से भेजता है, और returned PNG में चार pointers के लिए जाँचता है जो एक profile और एक libvips base की पहचान करते हैं। Ubuntu को 3 से 23 attempts की आवश्यकता पड़ी। Debian को 3 से 15 की। अपूर्ण या अस्पष्ट evidence अनुमानित profile के बजाय एक और attempt का कारण बनता है।
इस project में 96 automated regression tests भी हैं। ये code-level checks हैं, 96 अतिरिक्त exploit runs नहीं। ये profile validation, returned-pointer classification, heap calibration, address calculation, payload construction, और evidence के किसी supported target से मेल न खाने पर safe failure को cover करते हैं।
दोनों x86-64 targets Next.js 15.5.23, sharp 0.34.4, bundled libvips 8.17.2, bundled libheif 1.20.2, ASLR, और NX का उपयोग करते हैं। उनके native runtimes भिन्न हैं:
| Profile | Node | glibc | libstdc++ | Selector relation |
|---|---|---|---|---|
| Ubuntu | 25.8.1, PIE ET_DYN | 2.43-2ubuntu2.4 | 6.0.35 | 0x6000 - 0x690 = 0x5970 |
| Debian 13 | Debian APT 20.19.2, PIE ET_DYN | 2.41-12+deb13u4 | 6.0.33 | 0x6000 - 0x3a0 = 0x5c60 |
पूर्ण build IDs और SHA-256 values
profiles/native_stack_profiles_pie.json में हैं।
Debian package, artifact, route-smoke, और five-lifetime layout measurements
evidence/debian13-profile-derivation.json में दर्ज हैं।
Debian target मानक distribution package
nodejs=20.19.2+dfsg-1+deb13u3 का उपयोग करता है; Node source से compile नहीं किया गया है।
chain को randomized Node base की आवश्यकता नहीं है। इसका control target libvips के अंदर आंतरिक g_module_open_full routine है, जिसका randomized base returned pixels से recover किया जाता है। प्रत्येक versioned profile exploit द्वारा आवश्यक build-specific constants को hardcode करता है:
memcpy@GOT offset और g_module_open_full offset तथा उसके validating instruction bytes;randomized libvips base, परिणामी runtime loader address, और अंतिम two-byte selector hardcoded नहीं हैं। ये प्रत्येक target process के लिए returned pixels और चयनित profile से derive किए जाते हैं।
exploit fail closed करता है जब कोई profile malformed हो या returned pixels ठीक एक supported profile/base pair का चयन न करें। stock profile को अपने पूर्ण returned heap record की भी आवश्यकता होती है। एक profile एक exact compatibility claim है, इसलिए operator को इसका उपयोग करने से पहले target artifacts को offline verify करना चाहिए।
loader ABI महत्वपूर्ण है। overwritten call RDI में library path, RSI में एक image-row pointer, और RDX में 58-byte copy length प्रदान करता है। यह exact profiled GModule routine ESI से केवल supported flag bits का उपयोग करती है और successful load path पर RDX को dereference नहीं करती। एक offline harness ने measured runs में उपयोग से पहले उस entry point और instruction signature को validate किया।
libaom-av1 encoder के साथ ffmpegcc के रूप में उपलब्ध एक C compilerएकमात्र Python dependency install करें:```bash python3 -m venv .venv . .venv/bin/activate python3 -m pip install -r requirements.txt
AV1 एन्कोडिंग समर्थन की पुष्टि करें:```bash
ffmpeg -hide_banner -encoders | grep libaom-av1
लैब जानबूझकर मनमाने अपलोड स्वीकार करती है और चयनित फ़ाइलों को sharp को पास करती है। इसे किसी अविश्वसनीय नेटवर्क पर उजागर न करें।```bash cd lab npm ci npm run build npm run start
लक्ष्य तब `http://127.0.0.1:3000` पर उपलब्ध होता है।
पहले PIE प्रोफ़ाइल द्वारा उपयोग किए जाने वाले Node आर्टिफ़ैक्ट के चारों ओर एक Ubuntu लैब इमेज बनाने के लिए:```bash
./scripts/build_ubuntu2604_container.sh
docker run --rm --network host \
fortbridge/libheif-grid-nextjs-rce:ubuntu2604
डाइजेस्ट-लॉक्ड Ubuntu 26.04 इमेज प्रोफ़ाइल में दर्ज सटीक Node 25.8.1 PIE आर्टिफ़ैक्ट को बनाती है, उसका SHA-256 सत्यापित करती है, फिर उसे एक साफ़ रनटाइम स्टेज में कॉपी करती है। सोर्स बिल्ड आवश्यक है क्योंकि Node का आधिकारिक Linux बाइनरी ET_EXEC है, जबकि यह प्रोफ़ाइल जानबूझकर एक PIE एक्ज़ीक्यूटेबल का परीक्षण करती है।