SQL Injection: Anatomia, Rilevazione e Difesa — Guida Pratica per Professionisti della Sicurezza
Capitolo 4 di 10 · aggiornato 03 lug 2026
Automazione della Discovery: sqlmap contro ShopBox con Monitoraggio Difensivo
Automazione della Scoperta: sqlmap Contro ShopBox con Monitoraggio Difensivo
Entro la Pagina 3 avevamo già esaminato lo sfruttamento manuale dell'endpoint della cronologia ordini di ShopBox—effettuando il fingerprinting del backend MySQL su 192.0.2.20 con probe a virgoletta singola, confermando l'iniezione blind booleana con AND 1=1 rispetto a AND 1=2, ed estraendo il nome del database carattere per carattere usando SUBSTRING() e SLEEP(). Quel lavoro manuale è importante perché sviluppa l'intuizione su ciò che il database effettivamente vede. Ma una volta compresa la vulnerabilità, ripetere quel lavoro a mano è uno spreco. È qui che entra in gioco sqlmap—e dove, come difensori, dobbiamo comprendere esattamente come appare la sua automazione dall'altro lato della connessione.
sqlmap è uno strumento open-source di penetration testing che automatizza la scoperta e lo sfruttamento dell'SQL injection. Può essere invocato come python sqlmap.py, python3 sqlmap.py, o semplicemente sqlmap su Kali Linux [S4]. Prima di iniziare, verifica la tua versione:
sqlmap --version
Perché questo è importante: L'output della versione varia in base alla fonte di installazione e al momento. Se stai seguendo il lab DeafNews, verifica rispetto alla release corrente per garantire la compatibilità dei flag [S4].
Configurazione del Proxy di Intercettazione
Il flag --proxy di sqlmap instrada tutto il traffico attraverso un server proxy, permettendoci di catturare ogni richiesta per analisi successive [S3]. Eseguo mitmproxy sulla mia workstation di analisi su 192.0.2.100 per creare questa visibilità. mitmproxy è un proxy HTTPS interattivo che registra le coppie di richiesta/risposta HTTP come "flussi," ognuno con un campo timestamp e metadati client_conn [S1].
Avvia il proxy con le opzioni impostate tramite --set [S2]:
mitmproxy --set anticomp=true --set confdir=~/.mitmproxy -w shopbox_sqlmap.dump
L'opzione -w scrive i flussi su shopbox_sqlmap.dump per la serializzazione successiva [S6]. L'opzione anticomp=true impedisce a mitmproxy di modificare le risposte compresse, preservando i byte esatti che l'applicazione invia. Mantengo una directory di configurazione dedicata tramite --set confdir piuttosto che inquinare la posizione predefinita ~/.mitmproxy [S2].
⚠️ Solo uso autorizzato e difensivo. Questo proxy intercetta il traffico verso un sistema lab isolato senza connettività esterna. Non eseguire mai questa configurazione su infrastrutture di produzione senza autorizzazione esplicita.
Prima Esecuzione di sqlmap: Rilevazione Controllata Basata sul Tempo
Dalla Pagina 3, sappiamo che l'endpoint della cronologia ordini su http://192.0.2.10/order_history.php è vulnerabile, con il parametro order_id iniettabile. Invece di lasciare che sqlmap provi ogni tecnica—cosa che genera richieste eccessive e può causare condizioni di denial-of-service [S5]—lo limitiamo alla sola iniezione blind basata sul tempo usando --technique=T [S4][S5].
L'iniezione blind basata sul tempo funziona chiedendo al database di ritardare la sua risposta quando una condizione è vera. L'attaccante inferisce informazioni dal tempo che il server impiega a rispondere, senza vedere alcun dato direttamente nella risposta. Questo è più lento dell'iniezione blind booleana ma funziona anche quando i messaggi di errore e le differenze visibili nella query sono soppressi.
sqlmap -u "http://192.0.2.10/order_history.php?order_id=1001" \ --technique=T \ --dbms=mysql \ --proxy=http://192.0.2.100:8080 \ --batch
Il flag --dbms=mysql restringe l'ambito poiché abbiamo già effettuato il fingerprinting del backend [S5]. --batch accetta le risposte predefinite a tutti i prompt, necessario per l'automazione ma rischioso in produzione—rivedi sempre quali valori predefiniti sqlmap seleziona per la tua versione.
In termini semplici: stiamo dicendo a sqlmap "usa solo ritardi temporali, assumi MySQL, invia tutto attraverso il mio proxy, e non farmi domande."
Osserva la lista dei flussi di mitmproxy. Vedrai richieste arrivare in rapida successione, ognuna con valori order_id leggermente diversi. sqlmap sta sondando: prima stabilisce una baseline del ritardo temporale, poi inietta varianti di SLEEP() per confermare l'iniezione. Il modello è inconfondibile—intervalli uniformi tra le richieste, valori di parametro incrementali, e payload contenenti funzioni SQL.
Cosa Rivelano i Log
Ora passiamo alla prospettiva del difensore. Su 192.0.2.20, il general query log di MySQL (se abilitato) registra ogni istruzione che il server riceve. L'access log dell'applicazione su 192.0.2.10 registra le richieste HTTP. La correlazione tra queste due superfici è dove risiede il rilevamento.
Una tipica sonda basata sul tempo di sqlmap genera query come questa nel general query log:
# output illustrativo — verifica sul tuo target
SELECT * FROM orders WHERE order_id=1001 AND SLEEP(5)
SELECT * FROM orders WHERE order_id=1001 AND IF(ASCII(SUBSTRING((SELECT ...
La struttura esatta del payload varia in base alla versione di sqlmap e al target, ma la firma è coerente: chiamate SUBSTRING() nidificate, conversioni ASCII(), e ritardi SLEEP() o BENCHMARK(). Queste non sono query che qualsiasi applicazione legittima generi.
Sul lato applicazione, l'access log mostra l'impronta HTTP:
# output illustrativo — verifica sul tuo target
192.0.2.100 - - [14/Jan/2025:09:23:17 +0000] "GET /order_history.php?order_id=1001%20AND%20SLEEP%285%29 HTTP/1.1" 200 1423 "-" "sqlmap/1.x.x.xxxxxxxxxx (http://sqlmap.org)"
La stringa User-Agent predefinita di sqlmap viene spesso lasciata invariata da tester junior—un regalo per i difensori, anche se facilmente modificabile con --user-agent. La frequenza delle richieste è il segnale più profondo: decine di richieste al minuto allo stesso endpoint, ognuna con un parametro leggermente mutato, nessuna seguita da pattern di navigazione normale dell'utente.
Aggiungere Evasione: Come Appare l'Evasione del WAF
Gli strumenti difensivi spesso dispongono un WAF (Web Application Firewall, un filtro che ispeziona le richieste HTTP per pattern maligni). sqlmap include script tamper che modificano la codifica del payload per eludere il rilevamento basato su firme semplici. Il tamper space2comment sostituisce i caratteri di spazio con commenti SQL (/**/), che molti parser accettano ma filtri naivi non rilevano.
Voglio sottolineare: non posso verificare dalle nostre fonti attuali che --tamper=space2comment di sqlmap si comporti esattamente come descritto in documentazione più vecchia. La disponibilità e l'efficacia degli script tamper variano per versione. Controlla la directory tamper/ della tua installazione, e verifica il comportamento con --test-filter o equivalente di verifica specifica per versione.
Concettualmente, la trasformazione appare così:
| Payload originale | Dopo space2comment |
|---|---|
AND SLEEP(5) | AND/**/SLEEP(5) |
UNION SELECT 1,2 | UNION/**/SELECT/**/1,2 |
In mitmproxy, il log del proxy mostra la richiesta HTTP grezza con queste sostituzioni intatte. Il WAF, se presente, deve decodificare e normalizzare prima di fare il matching. I WAF buoni lo fanno; quelli basilari no.
La lezione difensiva: l'evasione non è magia. È trasformazione che specifiche difese non riescono ad annullare. Il tuo rilevamento non dovrebbe fare affidamento sul matching di stringhe letterali come AND SLEEP—dovrebbe cercare anomalie strutturali come caratteri eccessivi codificati in URL nei parametri, sequenze di commenti in contesti insoliti, o il pattern comportamentale di richieste rapide e simili.
Costruzione della Timeline di Rilevamento
Lasciatemi illustrare cosa faccio effettivamente quando correl questi artefatti. Parto da tre fonti di dati: il file dump di mitmproxy, l'access log dell'applicazione, e il general query log di MySQL. Ognuna cattura un livello diverso, e i loro timestamp mi permettono di costruire una narrazione coerente.
Prima, esporto i flussi di mitmproxy in un formato utilizzabile. Il file dump scritto con -w può essere elaborato usando Python con json.dumps(flow.get_state()) [S6], o puoi usare l'esempio har_dump.py di mitmproxy per output in formato HAR [S6]. Tipicamente scrivo uno script rapido per estrarre timestamp, metodo, URL e User-Agent:
#!/usr/bin/env python3
# extract_mitm.py — script illustrativo, verifica rispetto alla tua versione di mitmproxy
import json, sys # flussi di mitmproxy serializzati tramite flow.get_state()
for line in sys.stdin: flow = json.loads(line) req = flow.get("request", {}) print(f"{flow.get('timestamp','')} {req.get('method','')} {req.get('url','')} {req.get('headers',{}).get('User-Agent','')}")
Esegui su shopbox_sqlmap.dump, poi ordina e unisci con le voci dell'access log dell'applicazione. La correlazione è semplice: IP sorgente corrispondente (192.0.2.100, la mia workstation), timestamp corrispondenti entro la latenza di rete, e percorsi URL corrispondenti.
Il general query log di MySQL richiede più interpretazione. L'iniezione blind basata sul tempo genera query che si eseguono con successo ma richiedono durata anomala. Cerco:
- Query con tempo di esecuzione significativamente superiore alla baseline dell'applicazione
- Chiamate alle funzioni
SLEEP(),BENCHMARK(), oGET_LOCK() - Pattern
SUBSTRING()/ASCII()/ORD()nidificati che estraggono singoli caratteri - Query dall'utente del database dell'applicazione che non corrispondono a pattern di query dell'applicazione noti
La timeline emerge come: 09:23:17 — arriva la prima sonda sqlmap al proxy; 09:23:17.200 — la stessa sonda viene loggata dall'applicazione; 09:23:17.450 — la query corrispondente appare nel general log di MySQL con tempo di esecuzione di 5.2 secondi; 09:23:22 — arriva la prossima sonda mentre la precedente è ancora in esecuzione. Questa sovrapposizione dell'esecuzione è caratteristica: sqlmap non attende intervelli educati; spara le richieste più velocemente che la rete lo permette, creando pressione sulla coda delle query.
La Firma del Rumore
sqlmap può essere molto pesante sul volume di richieste e può causare crescita eccessiva dei log [S5]. Questo non è un bug da aggirare; è il segnale di rilevamento. Un attaccante manuale abile scandisce le sonde, varia i tempi, e imita i pattern di traffico legittimi. L'automazione di sqlmap, per impostazione predefinita, non fa nulla di tutto ciò. La regolarità stessa diventa l'anomalia.
Dopo anni di gestire entrambi i lati di questo—attaccare sistemi lab e poi setacciare le conseguenze—ho imparato a guardare ciò che chiamo "ritmo meccanico": richieste che arrivano a intervalli consistenti al livello del millisecondo, valori di parametro che progrediscono in sequenze ovvie (1001, 1002, 1003... o più indicativamente, valori ASCII 65, 66, 67...), e l'assenza di qualsiasi comportamento di navigazione umana come richieste CSS o immagini tra chiamate funzionali.
Una Riesecuzione più Sicura con Controllo della Sessione
Se devi ripetere questo esercizio—forse testando una nuova regola WAF o soglia di rilevamento—evita di accumulare dati di sessione obsoleti che potrebbero distorcere i risultati. sqlmap memorizza nella cache i punti di iniezione scoperti e le impronte del database tra le esecuzioni. Sebbene non possa verificare la sintassi esatta del flag dalle nostre fonti, controlla l'help della tua versione per opzioni di gestione della sessione che cancellano o ignorano lo stato precedente.
Per il re-testing controllato, tipicamente rimuovo qualsiasi directory .sqlmap o file di sessione nella directory di lavoro, poi rieseguo con vincoli espliciti di tecnica e DBMS per prevenire l'espansione dell'ambito.
Punti Chiave per la Superficie di Rilevamento
| Cosa fa sqlmap | Cosa cercare nei log |
|---|---|
| Sonde sequenziali rapide a un singolo endpoint | Anomalie di frequenza delle richieste; asset intercalati mancanti |
Ritardi basati sul tempo (SLEEP, BENCHMARK) | Outlier di tempo di esecuzione delle query nei log del database |
| Estrazione carattere per carattere | Pattern SUBSTRING()/ASCII() nelle istruzioni SQL |
| User-Agent predefinito o non modificato | Stringhe letterali "sqlmap" (facilmente modificabili, quindi non fare affidamento esclusivamente) |
| Evasione tamper (space-to-comment, etc.) | Codifica URL eccessiva; sequenze di commenti nei parametri |
Il punto critico di insegnamento: l'automazione è rumorosa e patternizzata [S5]. Un attaccante umano determinato personalizzerà e rallenterà le sue sonde per eludere il rilevamento basato su soglie. Il comportamento predefinito di sqlmap non lo farà. Questo lo rende eccellente per verificare che la tua pipeline di rilevamento effettivamente si attivi—se riesci a intercettare sqlmap, hai una baseline. Intercettare attaccatori manuali pazienti è più difficile, e trattato successivamente nella discussione dell'architettura di rilevamento della Pagina 5 e nell'analisi dell'attacco evasivo della Pagina 9.
Per ora, assicurati di poter costruire la correlazione a tre vie: la cattura del proxy che mostra la struttura del payload, il log dell'applicazione che mostra l'impronta della richiesta, il log del database che mostra l'esecuzione della query. Quando questi tre si allineano, hai una storia di rilevamento completa—non solo "è successo qualcosa di strano," ma "questa specifica tecnica di iniezione contro questo specifico parametro ha causato questo specifico comportamento del database." Quella precisione è ciò che separa la fatica degli allarmi dalla risposta agli incidenti actionable.