Featured image of post YWH DOJO#26 - SQLovin

YWH DOJO#26 - SQLovin

Description of the SQLovin challenge by YesWeHack

📝 Description

On se retrouve face à une injection SQL 💉, notre but est de changer l’email pour un username donné (l’email et l’username sont définis UNIQUE du coup nous avons un conflit qui se crée car nous ne pouvons pas ajouter deux entrées avec le même username).

💥 EXPLOITATION

COMPRENDRE

La première étape est de voir où est la SQLI, en regardant le code on peut voir que notre input est mis dans un INSERT :

1
INSERT INTO superbad(country, email, username, password) VALUES('Hawaii', '[email protected]', 'McLovin', $pass)

on peut voir aussi qu’un replace est effectué sur notre input :

1
[0-9]|'|"|`|\s

nous n’avons donc pas le droit aux chiffres, aux ‘, “, ` et aux espaces. On sait aussi que c’est sous SQLITE3

on test quelques payloads pour essayer de ne plus avoir d’erreur, en testant :

1
null)--

cela nous renvoie :

1
2
3
{
  "ERROR": "SqliteError: UNIQUE constraint failed: superbad.username"
}

😀😀 c’est un bon début, on comprend qu’il va donc y avoir un conflit à cause du UNIQUE dans le CREATE TABLE puisque nos deux insert ont le même username.

on pourra donc ecrire du SQL ici :

1
null)<inject_here>--

TROUVER COMMENT BYPASS L’ERREUR

Après quelques recherches sur google incluant une injection SQL et cette erreur je ne trouve vraiment pas grand chose 💀. Après plusieurs minutes à tourner en rond je pars lire la documentation SQLITE

En lisant je tombe sur ON CONFLICT clause, ca me paraît intéressant !

Je cherche un peu sur internet et je tombe sur ça Use INSERT ON CONFLICT to overwrite data, parfait je trouve que ça colle vraiment avec notre situation plus qu’a crée notre payload final !😈

CRÉATION DU PAYLOAD FINAL

on sait qu’on ne peux pas mettre d’espaces mais un bypass est de mettre des commentaires :

1
SELECT * from test; => SELECT/**/*/**/from/**/test;

avec cette technique nous pouvons donc créer notre payload (avec on conflict) sans quotes, sans nombres et sans espaces !

si on applique la logique des exemples que nous avons pu voir sur les sites précédents on obtient :

1
null)ON/**/CONFLICT(username)/**/DO/**/UPDATE/**/SET/**/email/**/=/**/excluded.email;--

Concrètement ce code fais en sorte que si nous avons une erreur sur notre INSERT à cause du fait que deux values soient similaire il va exécuter le code apres le DO donc ici update la value de la row avec le même username avec l’email qu’on voulais de base ajouté.

En gros on ça transforme un peu notre INSERT en UPDATE.

💥 Proof of Concept

Comme expliqué ci-dessus avec ce payload je suis capable de changer l’email pour l’username McLovin 😎😎 :

1
null)ON/**/CONFLICT(username)/**/DO/**/UPDATE/**/SET/**/email/**/=/**/excluded.email;--
Built with Hugo
Theme Stack designed by Jimmy