Incendie du Datacentre FICloud

Charpentier A., De-Pontac C., Le Bohec R., Miralves T., Naulin A., Rataud Q.

← Incendie du Datacentre FICloud · 1ère étape - groupe 4 / Irrégularités dans le système de contrôle / 4e étape : Intrusion Physique / 3e étape - Reverse qui pourra

1ère étape - groupe 4

WEB

Le mot de passe de l'administrateur du site web du datacentre FICloud a fuité...

Ayant mis la main sur les logs du site web, vous devez retrouver le mot de passe et comment celui-ci a été obtenu par l'attaquant.

La société FICloud, spécialisée dans les solutions cloud innovantes, a récemment été la victime d'une cyberattaque.

L'équipe informatique a découvert que le compte administrateur de la machine sur laquelle réside le site web de FICloud a été compromis.

Une copie des derniers logs web a été récupérée avant que l'attaquant ne couvre ses traces.

Saurez-vous retrouver sa trace?

Cote 11 pts

Faire son rapport

En feuilletant les journaux, on remarque rapidement des mots-clés SQL dans
certaines requêtes, par exemple :

... "get_data":{"id":"1' AND IF(SUBSTRING((SELECT password FROM users WHERE user='admin'),1,1)='a', SLEEP(3), 0)-- -","Submit":"Submit"} ...

Cette requête attend trois secondes avant de retourner un résultat uniquement
si le mot de passe du compte admin commence par un a.
Il s'agit d'une injection SQL à l'aveugle, basée sur le temps.

On remarque que les lignes effectuant l'attaque partagent un même identifiant
de session.
On peut alors filtrer uniquement les lignes causées par l'attaquant.
On peut raisonnablement supposer que l'attaquant passe au caractère suivant
dès qu’il trouve le bon par brute-force.
En utilisant cette supposition, on peut tenter de retrouver le mot de passe
récupéré par l'attaquant :

from json import loads
from urllib.parse import parse_qs
import re

password = ''

last_number = ''
char = ''
for line in open('files/webserver.log'):
    data = loads(line)

    # On filtre par PHPSESSIONID de l'attaquant
    if '5164ef2b1f031fc8142f641445f9d28d' not in data['headers']['cookie']:
        continue
    query_string = parse_qs(data['query_string'])
    if 'id' not in query_string:
        continue
    query = query_string['id'][0]

    # On récupère la position/la lettre testée depuis la requête
    pattern = r"admin'\),(\d+),\d+\)='(.)'"
    match = re.search(pattern, query)
    if match is None:
        continue

    # Si l'attaquant a changé de caractère, c'est que la tentative précédente
    # était correcte.

    number = match.group(1)
    if number != last_number:
        password += char
    last_number = number
    char = match.group(2)
    print(number, char)

password += char
print(password) # Cela affiche le MD5 du mot de passe

Cela donne un condensat MD5.
Le mot de passe étant faible, on peut aisément retrouver le mot de passe
correctement en recherchant le condensat sur CrackStation.