## https://sploitus.com/exploit?id=12E0CD28-7FFF-5159-8284-A1E3774F66BA
# CVE-2025-4396 - WordPress Relevanssi Time-Based Blind SQL Injection Toolkit
## Overview
This repository contains a practical research and validation toolkit for **CVE-2025-4396**, an unauthenticated **Time-Based Blind SQL Injection** affecting the WordPress **Relevanssi** plugin through the `cats` parameter.
The project was built for **authorized Purple Team engagements** in order to:
- validate exploitability in a controlled manner,
- demonstrate different attacker tradecraft levels,
- measure SOC detection coverage,
- extract a WordPress password hash in a realistic way,
- and automate the offline cracking workflow once the hash has been recovered.
The repository includes:
- a **standard extraction script**,
- a **faster binary-search extraction script**,
- and a helper script to **prepare and crack the extracted WordPress 6.8+ hash** with Hashcat.
> **Disclaimer**
> This project is provided for **educational**, **defensive validation**, and **authorized security testing** only.
> Do not use it against systems you do not own or do not have explicit written permission to assess.
## Test Environnement
- Server : Debian 11
- WordPress 6.9.1,
- Relevanssi plugins 4.24.4 (downloaded from https://wordpress.org/plugins/relevanssi/advanced/),
- POC used from kali linux OS.
---
## CVE Description
**CVE-2025-4396** is a SQL Injection vulnerability affecting the **Relevanssi** search functionality in WordPress.
In the tested scenario, the issue is reachable through the search workflow and more specifically through the `cats` parameter. The vulnerable code path allows attacker-controlled input to influence the SQL query generated by the plugin.
Because the vulnerable endpoint is accessible without prior authentication, the flaw can be exploited by a remote attacker to perform **unauthenticated SQL injection**.
The practical impact includes:
- database query manipulation,
- Time-Based Blind SQL Injection,
- extraction of sensitive data such as password hashes,
- and, depending on the environment, possible privilege escalation through valid credential recovery.
---
## How the Vulnerability Works
### Root Cause
The vulnerability exists because user-controlled input from a search-related parameter is not safely handled before being incorporated into a SQL query.
In practice, this means an attacker can inject SQL expressions into the backend query logic and force the database to evaluate additional conditions.
### Why It Is Blind
The vulnerability is exploited in **blind** mode, which means the application does **not** directly display SQL errors or raw database results.
Instead of reading query output from the page, the attacker asks the database a series of **true/false questions** and observes one side effect:
- if the condition is **true**, the database sleeps for a few seconds,
- if the condition is **false**, the response returns immediately.
### Why It Is Time-Based
The exploitation relies on SQL functions such as `SLEEP()` to create a measurable difference in server response time.
This allows an attacker to infer data without ever seeing it directly.
For example, the attacker can ask questions such as:
- βIs the first character equal to `$`?β
- βIs the ASCII value of the second character greater than 77?β
- βDo the first N characters match this pattern?β
By repeating this process, the attacker can reconstruct a full hash character by character.
---
## How the Exploitation Works
### Standard Extraction Logic
The standard approach iterates through a known character set and tests each candidate one by one.
For each position in the target hash:
1. Build a SQL condition targeting one character.
2. Trigger a server delay only if the guess is correct.
3. Measure the response time.
4. Re-send the same request to reduce false positives caused by network jitter.
5. Append the confirmed character to the extracted hash.
6. Move to the next position.
This method is simple and reliable, but relatively slow because it may require many requests per character.
### Binary Search Extraction Logic
The faster approach uses **binary search** on the ASCII value of each character.
Instead of asking:
- βIs the character equal to `a`?β
- βIs the character equal to `b`?β
- βIs the character equal to `c`?β
it asks:
- βIs the ASCII value greater than 79?β
- βIs it greater than 55?β
- βIs it greater than 43?β
This divides the search space in half on every request and reduces the number of HTTP requests dramatically.
### Practical Result
The attack allows the operator to extract the `user_pass` value from `wp_users`, typically for a chosen WordPress user ID such as:
- `1` for the default administrator,
- or another ID passed on the command line.
In recent WordPress versions, this value may use the new **WordPress 6.8+ password pipeline**, which combines:
- a pre-hashing stage using **HMAC-SHA384**,
- Base64 encoding,
- and a final **bcrypt** hash.
---
## Included Scripts
### 1. `CVE_2025_4396.py`
This is the **standard extraction script**.
#### Purpose :
It performs a classic Time-Based Blind SQL Injection and extracts the target hash **character by character** using a linear search over a fixed charset.
#### Key Characteristics :
- simple and easy to understand,
- reliable in stable environments,
- double-verification logic to reduce false positives,
- useful as a baseline for detection engineering and PoC demonstrations.
#### How It Works :
For each character position:
- it iterates through a predefined character set,
- builds a SQL condition matching a single character,
- waits for the server response,
- and confirms the hit with a second request.
#### Requirements :
- `python3`
- `requests`
- `urllib3`
#### Installation :
```bash
pip3 install requests urllib3
```
##### Usage :
```bash
python3 CVE_2025_4396.py -t "https://target.local/?s=test&cats=" -u 1 -s 3 -v
```
```text
Arguments :
-t, --target : vulnerable target URL including the injectable parameter
-u, --userid : WordPress user ID to target
-s, --sleep : sleep threshold in seconds
-v, --verbose : enable debug logging
```
### 2. `CVE_2025_4396_Stealth.py`
This is the binary search edition.
#### Purpose :
It performs the same extraction objective as the standard script, but replaces the linear character-by-character search with a binary search on ASCII values.
#### Key Characteristics :
- significantly fewer HTTP requests,
- smaller network footprint,
- still includes a double-check step to prevent false positives.
#### How It Works :
For each position:
- Define a printable ASCII range.
- Test the midpoint.
- Ask whether the target character is greater than that midpoint.
- Reduce the range accordingly.
- Continue until the exact character is identified.
#### Requirements :
- `python3`
- `requests`
- `urllib3`
#### Installation :
```bash
pip3 install requests urllib3
```
#### Usage :
```bash
python3 CVE_2025_4396_Stealth.py -t "https://target.local/?s=test&cats=" -u 1 -s 3 -v
```
#### When to Use It :
- the target is confirmed vulnerable,
- latency is stable enough,
- and the goal is to reduce request volume.
---
## Offline Hash Cracking Workflow
Once the password hash has been extracted from WordPress, the next step is to crack it offline.
WordPress 6.8+ Hashing Notes. In the tested workflow, the extracted value may look like:
```text
$wp$2y$10$zPA8xGJMvr.kvAAIIYaCreIMnTDpgw/9o8K7.ONBm/KBbNIywQtu.
```
For Hashcat, the usable bcrypt portion is:
```text
$2y$10$zPA8xGJMvr.kvAAIIYaCreIMnTDpgw/9o8K7.ONBm/KBbNIywQtu.
```
However, this bcrypt is not applied directly to the raw password. WordPress first applies a preprocessing stage:
- PHP-style trim on the candidate password,
- HMAC-SHA384 using the key wp-sha384,
- Base64 encoding of the resulting digest,
- then bcrypt verification.
#### Why a Pre-Hashing Step Is Needed
This means a normal wordlist cannot be sent directly to Hashcat if you want to reproduce the exact WordPress 6.8+ logic.
Instead, each candidate password must be transformed first into its WordPress-compatible pre-hash representation.
The repository also includes a "helper" script that:
- accepts the extracted hash as an argument,
- strips the `$wp$` prefix when needed,
- pre-processes the supplied wordlist,
- generates the transformed dictionary,
- optionally creates a mapping file,
- launches Hashcat automatically,
- resolves the recovered pre-hash back to the original cleartext password.
#### Typical Workflow
Extract the hash :
- Example result : `$wp$2y$10$zPA8xGJMvr.kvAAIIYaCreIMnTDpgw/9o8K7.ONBm/KBbNIywQtu.`
Prepare the cracking environment :
- `python3`
- `hashcat` and available in PATH
Run `Auto_Crack.py` :
```bash
python3 Auto_Crack.py -H '\$wp\$2y\$10\$zPA8xGJMvr.kvAAIIYaCreIMnTDpgw/9o8K7.ONBm/KBbNIywQtu.' -w /usr/share/wordlists/rockyou.txt
```
```text
We need to escape "$" with "\" -> bash compatibility
```
---
## SOC Detection Guidance
The following detection content can be used by SOC teams to identify exploitation attempts and measure defensive maturity.
### Sigma Detection
```text
title: Potential Time-Based Blind SQLi (CVE-2025-4396 Relevanssi)
id: 5a8a1c93-5c74-4b5b-a620-8e1c3e41ab5d
status: experimental
description: Detects HTTP GET requests containing typical Time-Based Blind SQL injection payloads often used to exploit CVE-2025-4396 in the WordPress Relevanssi plugin (bypassing comma filters).
author: n3fhara
date: 2026-03-18
tags:
- attack.initial_access
- attack.t1190
- cve.2025-4396
logsource:
category: webserver
detection:
selection_endpoint:
cs-uri-query|contains:
- 's='
- 'cats='
- 'tags='
selection_payload:
cs-uri-query|contains:
- 'SLEEP('
- 'WAITFOR'
- 'SUBSTRING('
- 'ASCII('
- 'LENGTH('
selection_bypass_indicators:
cs-uri-query|contains:
- 'FROM'
- 'FOR 1'
- '*('
condition: selection_endpoint and selection_payload and selection_bypass_indicators
falsepositives:
- Highly unlikely. Legitimate search queries should not contain SQL functions.
level: high
```
### Suricata Detection
```text
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"ET EXPLOIT WordPress Relevanssi SQLi Attempt (CVE-2025-4396)"; flow:established,to_server; content:"GET"; http_method; content:"cats="; http_uri; pcre:"/(cats|tags)=.*(SLEEP|WAITFOR)%28.*(%2A|\*).*SUBSTRING/i"; classtype:web-application-attack; sid:1000001; rev:1; metadata:created_at 2026_03_18, cve CVE_2025_4396;)
```
### SPLUNK Detection
```text
index=web_logs sourcetype=access_combined
| regex uri_query="(?i)cats=|tags="
| stats count as request_count, avg(response_time) as avg_time, max(response_time) as max_time, dc(uri_query) as unique_payloads by clientip
| where request_count > 20 AND max_time > 2000
| sort - max_time
```
### KQL Detection
```text
url.query : (*cats=* OR *tags=* OR *s=*) AND url.query : (*SLEEP* OR *WAITFOR* OR *SUBSTRING* OR *ASCII*) AND url.query : (*FROM* OR *FOR* OR *%2A*)
```
### EQL Detection
```text
sequence by source.ip with maxspan=1m
[network where url.path == "/" and url.query : "*cats=*" and event.duration > 2000000000]
[network where url.path == "/" and url.query : "*cats=*" and event.duration > 2000000000]
[network where url.path == "/" and url.query : "*cats=*" and event.duration > 2000000000]
```
### Detection Gaps and Recommendations
The baseline detections above are good for non-obfuscated exploitation, but they become weaker when an operator introduces more advanced tradecraft.
SOC visibility degrades when the attacker starts using:
- alternative SQL functions instead of obvious ones,
- URL encoding and comment-based obfuscation,
- reduced request volume through binary search,
- jitter and low-and-slow timing,
- proxy rotation,
- browser impersonation.
#### Additional Detection Ideas for the SOC :
- Detect unusual slow search traffic,
- Monitor requests to the WordPress search endpoint where:
- response times are repeatedly elevated,
- the same client performs many search requests,
- or the same endpoint shows abnormal latency patterns over time.
- Alert on search parameters containing encoded operators,
- Even if obvious SQL keywords are not visible, search parameters containing combinations of :
- encoded comparison operators,
- suspicious parentheses density,
- repeated numeric logic,
- or heavily URL-encoded query strings.
- Correlate by endpoint, not only by source IP,
- If the attacker rotates proxies, IP correlation becomes weak. Detection should also focus on :
- repeated access to the same endpoint,
- repeated delayed responses,
- or repeated malformed search queries targeting the same WordPress page.
- Use long-window behavioral detection :
- 30-minute,
- 1-hour,
- or multi-hour windows.
- Monitor database-side slow queries
---
## Repository Structure
```text
.
βββ CVE_2025_4396.py
βββ CVE_2025_4396_Stealth.py
βββ Auto_Crack.py
βββ README.md
βββ relevanssi.4.24.4.zip
```
# Legal Notice
Use only in environments where you are explicitly authorized to test.
The authors and contributors assume no liability for misuse.
> **Disclaimer**
> This project is provided for **educational**, **defensive validation**, and **authorized security testing** only.
> Do not use it against systems you do not own or do not have explicit written permission to assess.