
WordPress के लिए एक पिन किए गए Docker Official Image हेतु CVE-2026-111497 RCE PoC
यह source-only PoC WordPress के लिए एक pinned Docker Official Image के विरुद्ध unauthenticated command execution को पुनः उत्पन्न करता है।
एक pingback.ping request WordPress को उसी PHP request के दौरान दो बार attacker URL fetch करवाता है। पहला response Brotli के माध्यम से एक PHP handler को corrupt करता है। retry header Bash शुरू करता है और lab flag लौटाता है।
यह profile target-specific है। यह वर्तमान WordPress images, अन्य digests, या WordPress Core में किसी memory error के बारे में कोई दावा नहीं करता।
WARNING: इस PoC को केवल शामिल lab में, ऐसे सिस्टम पर चलाएँ जो आपके स्वामित्व में हो। इसमें एक कार्यशील RCE payload है।
/flag.txt पढ़ता है, और flag XML-RPC response में लौटता है।sh से bash से sleep तक की process chain रिकॉर्ड करता है।| Item | Value |
|---|---|
| Target | docker.io/library/wordpress@sha256:806680ba62232c4c300fb9dcc9f89d08e9e8c2bfc59837a1f58716f8648306d5 |
| Image ID | c64dd89c00079939f18d70489e7c3e30cb071e8581824ab2de688f9f4d70d076 |
| Platform | Linux amd64, Debian 13.7 |
| Application | WordPress 7.1.3, Apache 2.4.69 prefork |
| Runtime | PHP 8.3.36 NTS |
| Decoder | libbrotli1:amd64 1.1.0-2+b7 |
यह Linux/amd64 manifest प्रकाशन के समय wordpress:latest द्वारा चुना गया था। वर्तमान latest tag अब इसे नहीं चुनता।
lab इस unmodified Docker Official Image को rootless Podman के साथ चलाता है। यह कोई Brotli library inject नहीं करता।
CVE-2026-111497 decoder corruption प्रदान करता है। WordPress pingback.ping के माध्यम से unauthenticated fetch path प्रदान करता है।
malformed stream live system handler pointer से छह bytes को strtolower handler में copy करता है। दोनों pointers एक ही ASLR-loaded libphp.so base का उपयोग करते हैं। इसलिए, profile को absolute address leak की आवश्यकता नहीं है।
profile अभी भी सटीक Brotli, PHP, glibc, cURL, Requests, Apache, allocator, और request history पर निर्भर है। पहला response 161-byte header और 23,069,816-byte body का उपयोग करता है। origin 23,069,752 bytes भेजता है, एक सेकंड प्रतीक्षा करता है, और अंतिम 64 bytes भेजता है।
decoder corruption के बाद error लौटाता है। Requests CURLE_BAD_CONTENT_ENCODING के बाद content decoding के बिना retry करता है। इसका पहला header name modified handler तक पहुँचता है और fixed Bash command शुरू करता है।
application path के लिए ये शर्तें आवश्यक हैं:
/xmlrpc.php reachable है, और pingback.ping enabled है।lab इन शर्तों को किसी plugin या victim-side instrumentation के बिना बनाता है।
generate_payloads.py authoritative payload source है। repository कोई prebuilt payload binaries track नहीं करता।
generator केवल Python standard library का उपयोग करता है। यह offline काम करता है और traffic नहीं भेजता या commands execute नहीं करता। यह RFC 7932 से profile constants और serialization stages परिभाषित करता है।
verify.sh सभी fragments regenerate करता है। यह उनके sizes, hashes, intermediate bit offsets, और one-bit selector relationship सत्यापित करता है।
परीक्षण किया गया host amd64 पर WSL2 के अंतर्गत Ubuntu 24.04.4 का उपयोग करता था। इसने rootless Podman 4.9.3, Bash 5.2.21, और Python 3.12.3 का उपयोग किया।
न्यूनतम आवश्यकताएँ हैं Linux amd64, rootless Podman, Bash, Python 3.8 या बाद का, ASLR mode 2, और standard GNU user tools। port 18170 और subnet 93.184.218.0/24 खाली रखें, या alternatives चुनें। एक enforcing SELinux host bind mounts को अस्वीकार कर सकता है।
lab चलाने से पहले, immutable images pull करें:
podman pull docker.io/library/wordpress@sha256:806680ba62232c4c300fb9dcc9f89d08e9e8c2bfc59837a1f58716f8648306d5
podman pull docker.io/library/wordpress@sha256:65d5f185a6f539803a177ea9cdd5ad632ae24427bea114447e67a6fcd5d8bfe8
podman pull docker.io/library/mariadb@sha256:33a6653ab666774f48818120045f9367a81cd4c54c027412fe294a7d1274e2dc
स्क्रिप्ट्स को निष्पादन योग्य बनाएँ, फिर स्रोत पैकेज सत्यापित करें:
chmod +x generate_payloads.py verify.sh run.sh
./verify.sh
प्रत्येक मोड को नए टैग के साथ चलाएँ:
| मोड | कमांड | अपेक्षित परिणाम |
|---|---|---|
| Positive | ./run.sh standard | फ़्लैग लौटाता है और PoC positive: प्रिंट करता है |
| Observable | ./run.sh observable | दृश्यमान bash और sleep प्रक्रियाएँ भी रिकॉर्ड करता है |
| Selector | ./run.sh selector | पुनः प्रयास करता है लेकिन फ़्लैग को प्रतिक्रिया से बाहर रखता है |
selector बाइट ऑफ़सेट 1066 पर एक बिट बदलता है। यह एक same-image कार्य-कारण नियंत्रण है, न कि fixed-decoder नियंत्रण।
वैकल्पिक आर्ग्युमेंट हैं मोड, टैग, होस्ट पोर्ट, और तीसरा नेटवर्क ऑक्टेट:
./run.sh standard trial2 18171 219
रनर साक्ष्य को runs/<tag>/ में लिखता है। मुख्य फ़ाइलें हैं:
VERDICT.txt: परिणाम और अनुरोध गणनाएँclient-request.raw और client-response.raw: इनबाउंड वायर डेटाorigin-evidence/origin-events.json: दोनों आउटबाउंड अनुरोध और रीट्राई हेडरoracle-match.txt: प्रतिक्रिया में फ़्लैग मिलानpayloads/identity.json: जनरेट किया गया प्रोफ़ाइल मेटाडेटाMANIFEST.sha256: सभी साक्ष्य फ़ाइलों के हैशरनर एक आंतरिक Podman नेटवर्क का उपयोग करता है और WordPress को केवल 127.0.0.1 पर प्रकाशित करता है। क्लाइंट कोई लक्ष्य पता स्वीकार नहीं करता। ओरिजिन कोई कमांड इनपुट स्वीकार नहीं करता। निश्चित कमांड केवल सिंथेटिक फ़्लैग पढ़ता है।
रनर Apache के शुरू होने से पहले Apache परिवेश से फ़्लैग मान हटा देता है। यह नए क्रेडेंशियल भी बनाता है और केवल वर्तमान रन के संसाधनों को हटाता है।
प्रतिक्रिया विभाजन और प्रक्रिया इतिहास शोषण इनपुट हैं। यदि कोई रन विफल हो जाता है, तो अपरिवर्तित प्रोफ़ाइल को नए टैग के साथ दोहराएँ। विफल रन के बाद पतों या पेलोड बाइट्स को ट्यून न करें।
यह पैकेज इमेज डाइजेस्ट, PHP बिल्ड, आर्किटेक्चर, एलोकेटर या प्रतिक्रिया शेड्यूल में पोर्टेबिलिटी स्थापित नहीं करता। एक भिन्न लक्ष्य निष्पादन रोक सकता है या केवल क्रैश का कारण बन सकता है।
अपस्ट्रीम ने 1.0.10, 1.1.1 और 1.2.1 में अनुरक्षित Brotli शाखाओं को ठीक किया। वितरण विक्रेता फ़िक्स को बैकपोर्ट कर सकते हैं। केवल प्रदर्शित संस्करण नहीं, बल्कि विक्रेता सलाह और पैकेज चेंजलॉग का उपयोग करें।