Contexte :

Nous sommes l’agent 42, qui doit enquêter sur les agissements d’Evil Gouv, concernant le massacre de résistants. Pour ce faire, nous devons retrouver l’email du client d’Evil gouv afin de l’utiliser pour prendre un billet sur le site d’AirEvil.

Étape 1 : Stockos

Stockos est un site de gestion de marchandise, nous allons essayer de nous introduire afin de récupérer les informations concernant Evil Gouv.

Jérémy Nitel, notre interlocuteur pour la partie Web, nous indique que Stockos a connu plusieurs fuites de mot de passe et qu’ils n’étaient pas très originaux.

l’URL du site est disponible à l’adresse : https://www.challengecybersec.fr/4e9033c6eacf38dc2a5df7a14526bec1/

1) Connexion à l’interface de gestion des stocks :

On se retrouve sur une page de login, mon premier reflex étant donné que Jérémy Nitel nous a indiqué que les mots de passe n’étaient pas très originaux.

Je décide de tester les célèbres combinaisons de mdp, qu’on retrouve malheureusement encore dans plusieurs services.

Stockos_1

Mon intuition est bonne, le mot de passe pour accéder au site est : admin:admin.

2 ) Reconnaissance sur le site :

On se retrouve donc sur la partie backend du site. Après inspection du code source et des différents onglets, je découvre qu’il y a une partie “Gestion des stocks” avec plusieurs commandes et clients.

Stockos_2

Sur la page il y a un onglet de recherche permettant de rechercher une commande. Par exemple ici j’affiche uniquement l’objet “Cyclosarin”:

Stockos_3

On peut voir que seules les informations concernant le “Cyclosarin” s’affichent.

Détecter une possible injection SQL :

Le but est de parvenir à générer une erreur SQL pour voir si une injection SQL est possible, pour ce faire, je rentre dans le champ de recherche :

Cyclosarin' # Le ' permettant de générer l'erreur

Stockos_4

On se retrouve avec une belle erreur SQL, l’onglet “Rechercher objet” `est donc faillible à une injection SQL.

3) Exploitation :

Trouver le nombre de champs :

La première chose à faire est de déterminer le nombre de champs que la requête renvoie. Ici on peut voir qu’il y a 5 champs : IDcolis, Object, Status, Section, Client.

Je décide tout de même de voir si il n’y a pas un 6e champ. Pour ce faire j’utilise ORDER BY qui permet de trier en se référant à la position du champ dans la requête. Si le champ n’existe pas, la requête renvoie une erreur, c’est comme cela qui nous pouvons déterminer le nombre de champs : tant que ORDER BY ne renvoie pas d’erreur, nous savons qu’il y a au moins X champs.

Requêtes ORDER BY :Erreurs :
Cyclosarin’ ORDER BY 5#;False
Cyclosarin’ ORDER BY 6#;True

Stockos_5

Il y a bien 5 champs dans la table. Il faut donc que la requête que nous ferons après le mot UNION comporte 5 champs.

Testons pour voir si les champs sont injectables :

Cyclosarin' UNION SELECT 1,2,3,4,5#;

Stockos_6

On peut voir que j’arrive à énumérer les champs. Les champs sont donc injectables.

Trouver la base de données utilisée :

Il possible de deviner le nom de la base de données, mais cela est beaucoup trop hasardeux. Pour ce faire, il existe database() qui permet de nous renvoyer la base de données actuellement utilisée.

On va donc forger notre requête comme ceci :

Cyclosarin' UNION SELECT 1,database(),3,4,5#;

Stockos_7

On peut voir que le nom de la base de données apparait dans le champ 2, celle-ci s’appelle stockos.

Trouver la liste des tables :

Maintenant que nous connaissons la base de données. Nous allons pouvoir afficher les noms des tables. C’est là que information_schema et sa table TABLES entrent en jeu !

La table TABLES contient la liste des tables utilisées par l’ensemble des autres bases de données.

La requête suivante affiche le champ TABLE_NAME à partir de la BDD information_schema.TABLES quand TABLE_SCHEMA correspond à stockos :

Cyclosarin' UNION SELECT 1,TABLE_NAME,3,4,5 FROM information_schema.TABLES WHERE TABLE_SCHEMA='stockos'#;

Stockos_8

Nous avons la liste des tables :

  • customer : Une table intéressante qui pourrait contenir notre fameux email.
  • orders
  • section
  • supplier
Trouver la liste des champs d’une table :

Nous avons pu voir précédemment que la table customer était présente dans la base de données stockos, nous allons l’analyser afin de voir si nous pouvons récupérer quelque chose d’intéressant.

Pour ce faire, nous utiliserons le même principe que ci-dessus, mais sur la table COLUMNS, qui permet de lister tous les champs de toutes les tables.

3 éléments composeront notre requête :

  • COLUMN_NAME : désigne le nom du champ.
  • TABLE_SCHEMA : désigne le nom de la BDD.
  • `TABLE_NAME: désigne le nom de la table.

Nous utiliserons la fonction CHAR() qui va permettre de retourner les caractères en fonction du nombre qu’on lui fournit. Transformer l’ASCII en chaîne de caractère, va permettre d’introduire une chaîne sans avoir recours à des guillemets.

Notre requête demandera donc d’afficher le nom des champs quand TABLE_SCHEMA sera égal a stockos et TABLE_NAME a customer :

Cyclosarin' UNION SELECT 1,COLUMN_NAME,3,4,5 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=CHAR(115, 116, 111, 99, 107, 111, 115) AND TABLE_NAME=CHAR(99, 117, 115, 116, 111, 109, 101, 114)#;

Stockos_9

la table customer est constituée des champs suivants :

  • delivery_adress
  • email
  • id
  • name
  • signup_date
Affichage des champs de la table customer :

Maintenant que nous avons le nom des champs de la table customer nous allons pouvoir les afficher avec la requête:

Cyclosarin' UNION SELECT delivery_address,email,id,name,signup_date FROM customer#;

Stockos_10

Ainsi on récupère l’ensemble des informations contenu dans la table customer.

On peut notamment voir qu’il y a eu une transaction suspecte d’Evil Gouv, qui correspond surement à notre cible :

adresse de livraison : 2056 Evil Road, Evil City, Death State, Evil Country
email : agent.malice@secret.evil.gov.ev
id : 12
Name : Evil Gouv
Date d'inscription : 2015-10-21 00:00:00

Étape 2 : AirEvil

Pour pouvoir prendre un billet sur le site d’AirEvil de Bad City à Evil City, nous allons devoir utiliser les informations obtenues sur Stockos.

1 ) Reconnaissance sur le site :

Le site d’AirEvil est disponible à l’adresse : https://www.challengecybersec.fr/35e334a1ef338faf064da9eb5f861d3c/

C’est un site de réservation de billet en ligne louant les “bienfais” de visiter Evil Country. Autant dire que cela donne envie 😳

Pour pouvoir acheter un billet il est nécessaire créer un compte sur leur site.

Je vais donc me comporter comme un utilisateur normal pour acheter mon billet. Pour ce faire, je commence par créer un compte. Concernant l’adresse email, j’utilise une adresse temporaire afin d’éviter d’utiliser ma propre adresse.

AirEvil_1

Le site me demande de confirmer mon compte par mail.

AirEvil_2

On peut voir que l’email d’activation est en base64 ce qui est très étrange et bon à prendre. Un coup de base64 décode pour voir à quoi cela correspond :

echo bmVsZWhhODYwOEBmdzAyNS5jb20= |base64 -d
neleha8608@fw025.com

On peut voir que cela correspond à mon email renseigné. Ça peut être une piste pour notre exploitation.

J’active mon compte en cliquant sur le lien, je suis à présent connecté en tant que Jean Eude sur le site. Je commande un billet comme demandé :

AirEvil_3

En cliquant sur Réserver j’ai un message m’indiquant que je ne peux pas réserver cette destination. En inspectant de plus près mon compte, on peut voir que je ne suis pas autorisé à voyager avec la compagnie aérienne AirEvil.

Il va donc falloir que j’usurpe identité d’agent malice, afin de pouvoir réserver le vol.

AirEvil_4

À présent je vais étudier la fonctionnalité de récupération de mot de passe présente sur le site. Pour ce faire, je me déconnecte et je clique sur Mot de passe oublié. Je renseigne ensuite l’adresse de mon compte :

AirEvil_5

Puis je me rends sur mon email pour effectuer la récupération de mot de passe.

AirEvil_6

Comment précédemment on peut voir que l’email de reset est aussi en base64, un coup de base64 pour voir à quoi il correspond :

echo d29yYW1hbjY2MkBmdzAyNS5jb20= |base64 -d
neleha8608@fw025.com

Celui-ci correspond encore à notre email. Il est donc peut être possible insérer l’email d’agent malice en base 64 à la place de notre email pour pouvoir usurper son compte.

2) Exploitation :

Je décide de tester cette hypothèse pour voir si l’on peut usurper le compte d’agent malice. Pour ce faire je commence par convertir son email en base64 :

echo 'agent.malice@secret.evil.gov.ev'|base64
YWdlbnQubWFsaWNlQHNlY3JldC5ldmlsLmdvdi5ldgo==

Puis je vais effectuer une réinitialisation de mot de passe avec son adresse email.

AirEvil_7

Une fois le reset demandé, je me rends sur le lien permettant de changer le mot de passe et je change la fin de l’URL par le b64 correspondant à l’email d’agent malice.

AirEvil_8

Bingo ! Nous avons le mot de passe d’agent malice.

Password : Superlongpassword666

Nous pouvons à présent usurper son compte pour acheter un billet sur la compagnie AirEvil. En cliquant sur réservé, un message nous indique que le vol a déjà été réservé.

AirEvil_9

On peut donc regarder dans l’onglet Mes reservations pour voir si le vol est présent.

AirEvil_10

Celui-ci est bien présent. Il nous est demandé d’analyser le QRCODE pour pouvoir récupérer le flag.

Pour ce faire j’enregistre l’image correspond au qrcode. Puis j’utilise zbar-tools sous Linux pour récupérer le flag.

AirEvil_11

Voilà notre flag : DGSESIEE{2cd992f9b2319860ce3a35db6673a9b8}

Nous pouvons soumettre celui-ci à notre interlocuteur, pour pouvoir continuer notre investigation.

Étape 3 : Analyse d’une communication sécurisée

Jérémy Nitel, nous demande d’analyser les communications de l’agent Satan concernant le convoi intercepté par des sources sur le terrain. Pour ce faire, nous disposons d’un fichier capture.pcap.

Je décide d’ouvrir ce fichier avec Wireshark, qui va nous permettre d’analyser les trames.

SSL-HTTP_1

Ici nous avons une capture de plusieurs protocoles : TCP, TLSv1. C’est donc une communication chiffrée, les informations sont illisibles sans la clé privée.

À la trame “24” on peut y voir le handshake protocol.

SSL-HTTP_2

Le handshake protocol c’est quoi ?

Traduit par “poignée de main”, ce protocole permet au serveur et au client de:

  1. s’authentifier mutuellement;
  2. négocier:
    1. Les algorithmes de chiffrement;
    2. les algorithmes de MAC;
    3. Les clés symétriques qui vont servir au chiffrement avant que l’application ne transmette son premier octet.

Voice une image issue de cloudflare qui explique comment se déroule le handshake dans l’ordre chronologique:

SSL-HTTP_3

Cette trame correspond donc à l’envoi de la clé publique au destinataire. Avec Wireshark il est possible de récupérer cette clé.

SSL-HTTP_3

Maintenant que nous avons la clé publique, nous allons pouvoir procéder à l’analyse de celle-ci. Pour ce faire, j’utilise openssl avec les paramètres suivants :

  • x509 permet de créer un certificat autosigné au lieu d’une simple demande de certificat.
  • -in désigne le chemin où est stocké la clé publique.
  • -text affiche en mode texte le certificat.

SSL-HTTP_3

On peut voir toutes les infos sur le certificat, pour pouvoir déterminer la clé privée en fonction de la clé publique je vais utiliser l’outil rsactftool.

rsactftool --publickey publickey.pub --private

-----BEGIN RSA PRIVATE KEY-----
MIIBXwIBAAJJAMLLsk/b+SO2Emjj8Ro4lt5FdLO6WHMMvWUpOIZOIiPu63BKF8/Q
jRa0aJGmFHR1mTnG5Jqv5/JZVUjHTB1/uNJM0VyyO0zQowIDAQABAkgyAw5Cxp1O
d95+I5exPbouUvLFeiBfWXP+1vh2MvU8+IhmCf9j+hFOK13x22JJ+Orwv1+iatW4
5It/qwUNMvxXS0RuItCLp7ECJQDM6VRX8SfElUbleEECmsavcGBMZOgoEBisu1OC
M7tX83puaJUCJQDzXLgl8AM5bxHxSaWaD+c9tDFiyzBbjr/tpcqEC+JMU2tqrlcC
JQCjGt8+GQD0o3YJVc05i4W3RBYC+RcqPJXHeFyieRcYjP/ZPnkCJQDVUULBTl8l
KuzJWcrk/metuJNJi925g6lMwHSBxoD4cm7HtkUCJFqWTOzCIODw7eoypcJYjm2O
/ohEsSjEXsg6Bh8mY3LunBaqiA==
-----END RSA PRIVATE KEY----

rsactftool nous a permis de trouver la clé privée en fonction de la clé publique. J’enregistre la clé privée pour pouvoir l’utiliser dans Wireshark.

On peut donc maintenant lire les informations échangées via Wireshark en indiquant la clé privée. Pour ce faire, on se rend dans Editer -> Préférences -> Protocoles -> TLS -> RSA keys list puis on rentre la clé.

SSL-HTTP_6

Notre clé privée est bien enregistrée dans Wireshark nous pouvons à présent analyser les échanges. Cliquer sur l’onglet Analyser puis Suivre et ensuite sélectionner TLS Stream.

SSL-HTTP_7

On peut voir que la cible effectue une requête POST sur l’URL /7a144cdc500b28e80cf760d60aca2ed3. Je décide d’investiguer cette URL.

SSL-HTTP_8

Nous voilà sur l’onglet d’inscription au CTF, nous avons fini avec la track Web !!!