Aller au contenu
Categoria: Pentest9 min de lecture

SQL Injection en Pratique: Exploiter, Detecter et Mitiger dans un Lab Controle

Por Lucas Andrade ·

Demo technique de SQLi avec sqlmap dans votre propre lab, axee sur la detection defensive et les correctifs parametres qui tiennent vraiment face au trafic de production.

SQL Injection en Pratique: Exploiter, Detecter et Mitiger dans un Lab Controle

SQL Injection a fete ses 27 ans en 2026 et reste dans le top trois OWASP, non parce que les attaquants sont devenus plus malins, mais parce que les ORMs mal utilises, les requetes dynamiques dans les dashboards internes et les resolvers GraphQL qui concatenent des strings continuent de partir en production. Ce guide monte un lab controle ou vous exploitez, detectez et mitigez la vulnerabilite de bout en bout. Le but nest pas dexhiber un dump de la table users: cest de comprendre la boucle complete, du premier probe a une regle WAF qui tue sqlmap en moins de deux minutes. Tout tourne sur du materiel a vous, contre des cibles que vous etes autorise a casser, dans un reseau isole sans route vers quoi que ce soit de reel.

Ce quest reellement une injection SQL

Une injection SQL survient quand un input non fiable atteint linterpreteur SQL comme du code plutot que comme de la donnee. La base ne peut plus distinguer lintention du developpeur du payload de lattaquant une fois les deux colles dans le meme string. Lexemple canonique est "SELECT * FROM users WHERE id = " + req.id, ou id=1 OR 1=1 transforme une recherche mono-ligne en lecture complete de table. La cause racine nest jamais le moteur de base; cest la concatenation. Les frameworks modernes font de la parametrisation le defaut, mais la construction brute de strings survit dans les endpoints de reporting, les clauses dynamiques ORDER BY, les filtres de recherche et les query builders faits main.

La taxonomie des classes dinjection

On ne teste pas ce quon ne sait pas nommer. In-band UNION-based renvoie la donnee directement dans la reponse HTTP via un UNION SELECT ajoute. Boolean-based blind deduit un bit a la fois selon comment la page change quand une condition est vraie ou fausse. Time-based blind utilise SLEEP() ou pg_sleep() pour fuiter la donnee par la latence quand il ny a aucune sortie visible. Error-based pousse la base a echoer la donnee dans un message derreur. Out-of-band exfiltre par DNS ou HTTP quand le canal est totalement aveugle. Et second-order stocke un payload qui se declenche plus tard, dans une autre requete, sur une autre route. Les vraies applications exposent souvent plus dune classe.

Construire le lab isole

Commencez par Docker sur un reseau host-only. Faites tourner une instance DVWA, un MySQL 8.0 avec le binlog active et un proxy Burp Suite qui capture chaque requete. Un compose minimal donne une cible reproductible: docker compose up -d dvwa mysql. Routez le navigateur via Burp, mettez le niveau de securite sur low pour la premiere passe, puis montez a medium et high pour sentir comment le filtrage dinput change la donne. Nexposez jamais ce stack sur une interface routable; les labs SQLi attirent les scanners opportunistes, et un MySQL vulnerable sur internet public devient le cryptominer dun inconnu en quelques heures.

Exploitation pas a pas avec sqlmap

La premiere experience frappe lendpoint GET de DVWA. Lancez sqlmap -u 'http://lab.local/vulnerabilities/sqli/?id=1&Submit=Submit' --cookie='PHPSESSID=...; security=low' --batch --technique=BEUST --level=3 --risk=2. En environ quatre secondes sqlmap confirme une injection boolean-based blind sur le parametre id; en onze il enumere la base dvwa et ses tables. Ajoutez --dump -T users pour extraire des identifiants, ou --os-shell la ou les privileges FILE et secure_file_priv autorisent lecriture dun web shell. Observez les payloads sur le fil: 1 AND 4523=4523, 1 AND 1=2 UNION SELECT NULL,NULL. Ces litteraux numeriques repetitifs, le user-agent par defaut sqlmap/1.8.x et labsence de Accept-Encoding sont exactement le signal que vous armerez plus tard pour la detection.

Exploitation manuelle, car les outils ratent le contexte

Automatisez la decouverte, mais exploitez a la main quand ca compte. Pour lextraction UNION-based, trouvez dabord le nombre de colonnes avec ORDER BY 5-- - jusqua ce que la requete casse, puis alignez les types avec UNION SELECT 1,2,3,4,5-- - et placez @@version, database() et group_concat(table_name) dans les colonnes visibles via information_schema.tables. Pour le blind boolean, bissectez chaque caractere avec AND ASCII(SUBSTRING((SELECT ...),1,1))>77. Pour le time-based, remplacez la comparaison par AND IF(condition, SLEEP(3), 0). Le faire a la main une fois vous enseigne le modele mental quaucun scanner ne donne, et cest le seul moyen de gerer les contextes mutiles par WAF ou les tamper scripts de sqlmap echouent.

Injection second-order: le bug que les scanners sautent

Enregistrez via un formulaire un utilisateur nomme admin'-- dont le prepared statement echappe proprement la quote a lecriture. Le payload reste dormant dans la base. Le probleme vit dans un endpoint interne de recherche ou de profil qui reutilise cette valeur stockee dans une requete dynamique sans reparametrer. Resultat: bypass dauthentification sur une route qui na jamais paru dans le scan initial, parce que le payload ne se declenche que dans un autre contexte. Cest le meme mode de defaillance qui perce les APIs GraphQL dont les resolvers partagent un query builder. Les outils automatiques lattrapent rarement, cest pourquoi la revue manuelle de code continue de payer dans tout engagement serieux.

Detection et instrumentation

Transformez le bruit de lattaquant en signal. Activez SET GLOBAL general_log = 'ON' pour que chaque statement tombe dans le query log avec un timestamp en microsecondes. Comparez trente secondes de trafic legitime a trente secondes de sqlmap: le coefficient de variation de la longueur de requete bondit denviron 0,12 a 1,8, et les erreurs de syntaxe explosent. Envoyez le log via Filebeat vers Elastic et batissez trois detections: erreurs de syntaxe SQL au-dessus de cinq par minute par IP source, sequences contenant UNION SELECT NULL, et temps dexecution superieur a trois ecarts-types du baseline horaire. Contre sqlmap avec --random-agent et --delay=2, les trois ont declenche en moins de quatre-vingt-dix secondes. Posez aussi des honeytokens: une fausse colonne credit_card_test avec une string tracable vous dit exactement quel endpoint a fuite le jour ou elle apparait sur un paste site.

Mitigation et hardening qui tient vraiment

La vraie mitigation demarre avec des prepared statements parametres et ne sarrete pas la. Remplacez les strings interpoles par des parametres lies dans chaque langage: NamedParameterJdbcTemplate en Java, placeholders $1 dans le pgx de Go, et PDO avec PDO::ATTR_EMULATE_PREPARES=false en PHP pour eviter le classique bypass de quote multibyte. Comme les prepared statements ne parametrent pas les identifiants, protegez le ORDER BY dynamique et les noms de colonne par un allowlist strict. Ajoutez le moindre privilege sur lutilisateur applicatif (GRANT SELECT, INSERT, UPDATE seulement, jamais FILE ni SUPER), la validation dinput au bord, et une WAF comme ModSecurity avec CRS 4.x en mode blocking devant. Reduisez la surface avant de faire confiance a la detection; la defense en profondeur signifie quun attaquant doit battre chaque couche, pas seulement une.

Pieges frequents

Les equipes cassent leurs propres defenses de facons previsibles. Elles parametrent la valeur mais interpolent le nom de table. Elles font confiance a un ORM puis descendent en requete brute pour un rapport. Elles echappent a la sortie au lieu de parametrer a lentree. Elles font tourner lutilisateur applicatif en root sur la base, si bien quune injection mineure devient une compromission totale du serveur. Elles ne testent que le formulaire de login et ignorent recherche, export et panneaux admin ou se cache le vilain SQL dynamique. Et elles prennent un scan vert de sqlmap pour une preuve de securite, alors que sqlmap par conception ne reporte jamais les chemins second-order et de logique metier quun relecteur humain trouve.

Une checklist de terrain

Avant de signer: toute requete touchant de linput externe est parametree; les identifiants passent par un allowlist; lutilisateur de base a le moindre privilege; les messages derreur sont generiques et nechoent jamais de SQL; une WAF bloque en production, pas seulement logue; le query log alimente un SIEM avec les trois detections ci-dessus; des honeytokens sont poses dans les tables de valeur; et une revue trimestrielle couvre chaque endpoint acceptant de linput, y compris les routes internes et admin. Prouvez que la boucle marche en attaquant votre propre build et en voyant les alertes se declencher.

Au-dela de MySQL: dautres moteurs changent les payloads

La classe du bug est portable, la syntaxe non, et un testeur qui ne connait que MySQL se fige des que le backend est PostgreSQL ou SQL Server. Sur PostgreSQL la concatenation utilise ||, les commentaires utilisent --, les delais viennent de pg_sleep(3), et les stacked queries sont souvent disponibles via le driver, ce qui ouvre la porte a lexecution de commandes avec COPY ... TO PROGRAM sur des installs mal configurees. Sur SQL Server WAITFOR DELAY '0:0:3' pilote linference time-based, xp_cmdshell est lescalade classique quand il est active, et lextraction error-based sappuie sur des conflits de type via CONVERT(). Oracle force chaque SELECT a passer par FROM dual et concatene aussi avec ||. Les stores NoSQL ne sont pas surs non plus: MongoDB accepte linjection doperateurs comme {"$gt": ""} quand un body JSON passe sans validation dans une requete, transformant un login en un match toujours vrai. La lecon defensive est identique partout, do sa generalisation: ne construisez jamais la requete depuis linput, liez toujours, et faites tourner le compte de base avec le grant le plus etroit possible pour quune injection reussie natteigne meme pas le systeme dexploitation.

FAQ

Un ORM me rend-il immunise contre linjection SQL? Non. Les ORMs parametrent le chemin courant, mais les echappes de requete brute, les fragments SQL natifs et les clauses WHERE ou ORDER BY construites dynamiquement reintroduisent la vulnerabilite. Auditez chaque endroit ou votre ORM vous laisse descendre en SQL brut.

Une WAF suffit-elle a elle seule? Non. Une WAF achete du temps et bloque loutillage courant, mais les astuces dencodage, les tamper scripts et les payloads second-order contournent les regles de signature. Traitez la WAF comme une couche au-dessus des requetes parametrees et du moindre privilege, jamais comme un substitut.

A retenir en pratique: montez le lab, lancez sqlmap une fois pour sentir le rythme de ses payloads, puis passez quatre-vingts pour cent du temps restant sur la detection et les correctifs. Linjection SQL nest pas un probleme de creativite de lattaquant; cest une requete dynamique que personne na relue. Parametrez tout ce qui est valeur, mettez en allowlist tout ce qui est identifiant, et le jour ou vous pouvez prouver que votre application tue sqlmap en moins de deux minutes avec blocage automatique, vous avez gagne.

Related posts

Nenhum comentário ainda

Seja o primeiro a comentar.

Deixe seu comentário

Entre com sua conta Canverly para comentar. Você pode usar a mesma conta em qualquer site da rede.

Entrar com Canverly