
वर्डप्रेस कोर के लिए प्री-ऑथ RCE PoC — CVE-2026-63030 (REST /batch/v1 रूट-कन्फ्यूज़न डीसिंक) को CVE-2026-60137 (author__not_in SQLi) के साथ जोड़ता है और एक अनऑथेंटिकेटेड शेल उत्पन्न करता है। केवल अधिकृत परीक्षण।
अप्रमाणित WordPress कोर RCE PoC जो CVE-2026-63030 + CVE-2026-60137 को श्रृंखलित करता है। केवल अधिकृत परीक्षण।
wp2shell.py एक एकल-फ़ाइल, केवल मानक-लाइब्रेरी वाला प्रूफ़ ऑफ़ कॉन्सेप्ट है जो दो WordPress कोर कमजोरियों को अप्रमाणित रिमोट कोड निष्पादन में श्रृंखलित करता है:
| CVE | घटक | बग |
|---|---|---|
| CVE-2026-63030 | REST /batch/v1 हैंडलर | रूट-कन्फ्यूज़न डिसिंक — बैच हैंडलर अपने हैंडलर टेबल और वैलिडेशन टेबल के बीच सिंक खो देता है जब एक सब-रिक्वेस्ट पथ पार्स करने में विफल होता है, जिससे एक सब-रिक्वेस्ट को एक हैंडलर के माध्यम से भेजा जाता है जिसके लिए इसे कभी वैलिडेट नहीं किया गया था। |
| CVE-2026-60137 | WP_Query | स्केलर SQL इंजेक्शन — author__not_in मान सीधे SQL में चिपका दिया जाता है, इसलिए उस तक पहुँचने वाला एक स्ट्रिंग इंजेक्टेबल है। |
दोनों में से कोई भी अपने आप में RCE नहीं है। डिसिंक डिलीवरी है (यह एक हमलावर स्ट्रिंग को एक क्वेरी में तस्करी करता है जिस तक उसे कभी नहीं पहुँचना चाहिए); इंजेक्शन प्रिमिटिव है। साथ मिलकर वे एक प्री-ऑथ हमलावर को एक पूर्ण SQL रीड/राइट ओरेकल देते हैं, और वहाँ से एक कार्यशील शेल।
⚠️ केवल अधिकृत परीक्षण। यह लाइव WordPress इंस्टॉल का शोषण करता है। इसका उपयोग केवल उन सिस्टमों के विरुद्ध करें जिनके आप मालिक हैं या जिनके परीक्षण की स्पष्ट लिखित अनुमति है।
असुरक्षित: 6.8.0–6.8.5, 6.9.0–6.9.4, 7.0.0–7.0.1 पैच किए गए: 6.8.6, 6.9.5, 7.0.2 (और बाद के) रिपोर्ट किया गया Adam Kues (Assetnote / Searchlight Cyber) द्वारा; SQLi का श्रेय TF1T, dtro, haongo को भी।
केवल 6.9.0–7.0.1 RCE में सक्षम हैं। 6.8.x लाइन पर डिसिंक अभी भी फायर करता है, लेकिन हैंडलर को गलत संरेखित करने वाली शाखा इसके बजाय WP_Error::get_method() फेटल से टकराती है — इसलिए 6.8.x एक डिनायल-ऑफ़-सर्विस / क्रैश है, शेल नहीं। उपकरण इसका पता लगाता है और आपको बताता है कि कौन सा प्रिमिटिव उपलब्ध है।
शोषण परतों में बनाया गया है; प्रत्येक अगली के लिए एक पुल है।
डिसिंक (CVE-2026-63030). एक बैच अनुरोध दूसरे बैच को नेस्ट करता है। एक सब-रिक्वेस्ट जानबूझकर खराब बना पथ (http://:, जिसे wp_parse_url() अस्वीकार करता है) ले जाती है। 6.9.0+ में विफल पार्स हैंडलर और वैलिडेशन तालिकाओं को एक प्रविष्टि से बहने का कारण बनता है, जिससे अगला सब-रिक्वेस्ट एक हैंडलर के तहत चलता है जिसके खिलाफ इसे कभी वैलिडेट नहीं किया गया था — सार्वजनिक पोस्ट संग्रह।
इंजेक्शन (CVE-2026-60137). वह गलत-डिस्पैच कॉल हमलावर-नियंत्रित author__not_in के साथ WP_Query तक पहुँचता है। वहाँ एक UNION ALL SELECT पंक्तियों को पढ़ता नहीं है — यह उन्हें गढ़ता है, जिससे हम क्वेरी परिणाम में मनमानी पोस्ट बना सकते हैं।
SQL → राइट ब्रिज. गढ़ी गई पोस्ट [embed] मार्कअप ले जाती हैं। WordPress उन्हें ईमानदारी से हल करता है और वास्तविक oembed_cache पोस्ट-मेटा पंक्तियों के रूप में कैश करता है — एक रीड-ओनली इंजेक्शन को मनमाने राइट प्रिमिटिव में बदल देता है।
विशेषाधिकार पिवट. उस राइट ब्रिज का उपयोग करके हम (a) वास्तविक प्रशासक के रूप में लेखित एक कस्टमाइज़र चेंजसेट और (b) एक स्व-संदर्भित request पोस्ट गढ़ते हैं। साथ में वे WordPress को अपने स्वयं के अनुरोध पाइपलाइन को उस प्रशासक के रूप में पुनः चलाने के लिए मजबूर करते हैं — एक विंडो इतनी लंबी कि एक क्यू किया गया कॉल एक नया प्रशासक बना सके।
पढ़ने के पक्ष (--dump, उपसर्ग रिज़ॉल्यूशन, कैश किए गए आईडी) के लिए उपकरण स्वचालित रूप से सबसे तेज़ ओरेकल चुनता है जो काम करता है और पहली हिट पर रुक जाता है:
union — इन-बैंड UNION: गढ़ी गई पंक्ति का post_title |||HEX(value)||| रखता है, जो /wp/v2/posts प्रतिक्रिया निकाय में शब्दशः प्रतिबिंबित होता है। एक अनुरोध में पूरा मान (कोई भी लंबाई) पढ़ता है। यदि UNION प्रतिबिंबित होता है, तो बूलियन ओरेकल की कभी जाँच नहीं की जाती।bool — बूलियन X-WP-Total ओरेकल: भ्रमित उप-प्रतिक्रिया का X-WP-Total हेडर सत्य के लिए count>0 / असत्य के लिए 0 है। प्रति अनुरोध एक बिट (द्विभाजन)।time — समय-आधारित SLEEP(): फ़ॉलबैक जब निकाय हटा दिया जाता है और प्रतिक्रिया 500 होती है (जैसे कैशिंग mu-प्लगइन से पोस्ट-डिस्पैच फेटल)। उन लक्ष्यों पर भी काम करता है जो हर REST कॉल पर क्रैश होते हैं।--dump UNION उपलब्ध होने पर एक शॉट में पूरा क्रेडेंशियल सेट खींचने के लिए GROUP_CONCAT का उपयोग करता है।
कोई नहीं। केवल Python 3.7+ मानक लाइब्रेरी — कोई pip install नहीं।
chmod +x wp2shell.py
# 1. क्या यह असुरक्षित है? (कोई इंजेक्शन, कोई लेखन, कोई खाता निर्मित नहीं)
./wp2shell.py http://target --check
# 2. केवल-पढ़ने के लिए क्रेडेंशियल डंप — पहला प्रशासक + विकल्प रहस्य
./wp2shell.py http://target --dump
# …हर प्रशासक
./wp2shell.py http://target --dump all
# 3. पूर्ण RCE — एक अस्थायी प्रशासक बनाएँ, एक कमांड चलाएँ, साफ़ करें
./wp2shell.py http://target --exec "id; uname -a"
./wp2shell.py http://target --user-list # पूर्ण उपयोगकर्ता तालिका (लॉगिन/ईमेल/भूमिकाएँ)
./wp2shell.py http://target --content # status=any पर हर पोस्ट प्रकार (निजी/ड्राफ्ट)
./wp2shell.py http://target --content full # …प्रत्येक आइटम का कच्चा निकाय सहित
./wp2shell.py -f targets.txt --check --target-threads 8
$wp$2y$… / $P$… / $2y$…) सीधे hashcat में जाते हैं (phpass के लिए -m 3200, या WP bcrypt मोड)। WordPress 6.8+ $wp$… bcrypt का उपयोग करता है।--dump डिफ़ॉल्ट रूप से केवल पहले प्रशासक को डंप करता है। पूर्ण प्रशासक सूची के लिए --dump all का उपयोग करें।--oracle time --dump पर पिवट करें।--exec पथ को कुछ भी पीछे न छोड़ने के लिए डिज़ाइन किया गया है: अस्थायी प्रशासक, इसका उपयोगकर्ता मेटा, गढ़ी गई oembed_cache पंक्तियाँ और अपलोड किया गया वेबशेल सभी उपकरण से बाहर निकलने से पहले हटा दिए जाते हैं। कोई --keep फ्लैग नहीं है — एक ऑपरेटर को कभी भी ग्राहक के सिस्टम पर एक जीवित, हमलावर-निर्मित प्रशासक खाता नहीं छोड़ना चाहिए।
wp2shell.py — शोषण (एकल फ़ाइल, केवल stdlib)।कमजोरी की खोज, खुलासा, और मूल "wp2shell" लेख का श्रेय Searchlight Cyber / Assetnote शोध टीम को है:
/batch/v1 रूट-कन्फ्यूज़न डिसिंकWP_Query author__not_in SQL इंजेक्शनयह भंडार उनके द्वारा खुलासा किए गए शोषण श्रृंखला का एक स्वतंत्र प्रूफ-ऑफ-कॉन्सेप्ट कार्यान्वयन है; यह अंतर्निहित कमजोरियों की खोज का दावा नहीं करता है। यदि कोई श्रेय अधूरा या गलत है, तो एक मुद्दा खोलें और इसे सुधारा जाएगा।
यह अधिकृत पेनिट्रेशन परीक्षण और रक्षात्मक सत्यापन के लिए एक सुरक्षा अनुसंधान प्रूफ ऑफ कॉन्सेप्ट है। इसे उन सिस्टमों के विरुद्ध चलाना जिनके आप मालिक नहीं हैं या जिनके परीक्षण की लिखित अनुमति नहीं है, अवैध है। लेखक दुरुपयोग के लिए कोई दायित्व स्वीकार नहीं करता है।
POST /wp/v2/usersशेल. नए प्रशासक के रूप में साइन इन करें, एक प्लगइन अपलोड करें, कमांड चलाएँ। खाता, इसका मेटा, oembed पंक्तियाँ और वेबशेल बाद में सभी साफ़ कर दिए जाते हैं — कोई स्थायी फुटप्रिंट नहीं छोड़ा जाता।
| फ़्लैग | उद्देश्य |
|---|
url / -f FILE | एकल लक्ष्य, या लक्ष्यों की एक फ़ाइल (प्रति पंक्ति एक URL) |
--check | केवल कमजोरी की जाँच — कोई इंजेक्शन, लेखन, या खाता नहीं |
--dump [all] | पहले प्रशासक का हैश + रहस्य डंप करें; all = हर प्रशासक |
--exec CMD | अस्थायी प्रशासक बनाएँ → CMD चलाएँ → साफ़ करें |
--user-list | पूर्ण उपयोगकर्ता तालिका का उन्नत इन-बैंड पढ़ना (कोई लॉगिन नहीं, 2FA को बायपास करता है) |
--content [full] | status=any पर प्रत्येक पोस्ट प्रकार का उन्नत पढ़ना; full निकाय जोड़ता है |
--oracle {auto,union,bool,time} | एक निष्कर्षण ओरेकल बल करें (डिफ़ॉल्ट auto) |
--prefix PFX | स्वचालित रिज़ॉल्यूशन के बजाय तालिका उपसर्ग बल करें |
--impersonate UID | पहले प्रशासक के बजाय इस उपयोगकर्ता आईडी का प्रतिरूपण करें |
--threads N | एक लक्ष्य के भीतर समवर्ती निष्कर्षण प्रोब (डिफ़ॉल्ट 5) |
--target-threads N | -f से N लक्ष्यों को समवर्ती रूप से स्कैन करें (डिफ़ॉल्ट 1) |
--proxy URL | एक प्रॉक्सी के माध्यम से रूट करें (उदा. Burp http://127.0.0.1:8080) |
--timeout SEC | प्रति-अनुरोध टाइमआउट (डिफ़ॉल्ट 30) |
--verbose / -v | कच्चे बैच उप-प्रतिक्रियाएँ डंप करें (डिबगिंग) |
| फ़्लैग | उद्देश्य |
|---|
--form | बैच को multipart/form-data के रूप में भेजें (साफ़ URL, कोई ?rest_route= नहीं) |
--permalink [PREFIX] | /<PREFIX>/batch/v1 के माध्यम से रूट करें (डिफ़ॉल्ट wp-json); पेलोड को URL और $_POST से बाहर रखता है। टिप: --permalink index.php/wp-json REST तक PATH_INFO के माध्यम से पहुँचता है, /wp-json पर एंकर नियमों से बचता है |
--dummy N | WAF निरीक्षण बफर को ओवरफ्लो करने के लिए बॉडी में N बाइट्स कचरा प्रीपेंड करें |
--donor {widgets,categories,tags} | यदि कोई 500 देता है तो कन्फ्यूजन डोनर रूट स्विच करें (डिफ़ॉल्ट widgets) |
--per-page N | per_page गढ़ें (-1 या एक बड़ा धनात्मक दोनों सभी पंक्तियाँ लौटाते हैं; यदि लक्ष्य -1 पर 500 देता है तो एक बड़ा धनात्मक उपयोग करें) |
--users-route PATH | उपयोगकर्ता-निर्माण कॉल के लिए वैकल्पिक केस/क्वेरी (/wp/v2/Users, …?_=1) |
--primer PATH | यदि कोई WAF डिफ़ॉल्ट http://: को फिंगरप्रिंट करता है तो वैकल्पिक खराब डिसिंक पथ |
--user-agent UA | UA को पिन करें (डिफ़ॉल्ट: प्रति रन एक यादृच्छिक यथार्थवादी ब्राउज़र UA) |
--embed-base URL | oembed URL आधार को ओवरराइड करें (सेल्फ-एम्बेड लूपबैक से बचें) |