Vous êtes sur la page 1sur 20

École Centrale Lyon

MSO 3.2
MSO Cybersécurité

BE n°1 et BE n°3: Root Me challenges

Élève : Enseignants :
Manal Hachhach Dr Charles-Edmond BICHOT

avril 2023
BE n°1 :
2.1 App - Script : Bach - System 2

Password : 8a95eDS/*e_T#
2.2 App - Script : Powershell - Command injection

Password : SecureIEXpassword
2.4 App - Systeme : ELF x86 - Stack buffer overflow basic 2

Password : B33r1sSoG0oD4y0urBr4iN
2.5 Programmation : IRC - La Roue Romaine

Pour résoudre ce challenge, j'ai utilisé un script bash ainsi que le programme ii
de suckless disponible sur http://tools.suckless.org/ii/.

La méthode est simple : en se connectant au serveur IRC à l'aide de ii, on peut


écrire et lire des fichiers et dossiers pour communiquer avec les canaux de
discussion.

Par exemple,
pour écrire dans le canal #root-me, on doit écrire dans le fichier "in" du
répertoire "irc.root-me.org/#root-me/in".

Pour un message privé, il suffit de rejoindre le canal "irc.root-me.org/#root-


me_challenge/Candy" et d'écrire dans le fichier "in" de "irc.root-me.org/in".
Les messages reçus peuvent être consultés dans "irc.root-me.org/candy/out".

Pour résoudre le challenge, voici le script bash que j'ai utilisé :

#!/usr/bin/bash

pushd
. cd ~/irc/irc.root-me.org
bot="candy/in"

#echo "/join #root-me_challenge/Candy !ep3" > in


echo "!ep3" > $bot

sleep 0.2

clear=$(tail -1 candy/out | cut -d' ' -f4 | tr [a-zA-Z] [n-za-mN-ZA-M])

echo $clear echo "!ep3 -rep $clear" > $bot

cat candy/out

popd

Ce script permet de rejoindre le canal "Candy", d'envoyer le message "!ep3",


d'attendre un bref délai (0.2 secondes), de récupérer la dernière ligne du fichier
"candy/out", de la décrypter en utilisant l'algorithme ROT13, d'afficher le
résultat et d'envoyer le message "!ep3 -rep" suivi de la réponse cryptée dans le
fichier "candy/in". Enfin, il affiche le contenu du fichier "candy/out".

Password: 3bienBr4v0Continuepe7i7PONEY
2.6 Cracking : ELF x86 - Basique

Tout d'abord, nous identifierons le type de fichier.

Le fichier en question est un binaire lié statiquement qui n'a pas été supprimé.
Pour résoudre le défi, j'ai utilisé des chaînes et j'ai finalement obtenu la réponse.
Cependant, le processus a été assez long. J'ai commencé par ouvrir le binaire
avec Cutter, puis j'ai utilisé le décompilateur de Ghidra, que j'aime beaucoup
utiliser, contrairement à jsdec qui peut parfois être difficile à analyser, comme
je l'ai expliqué dans mes blogs précédents.

Examinons le code en détail. Tout d'abord, nous récupérons la première entrée


de l'utilisateur dans la variable iVar1. Ensuite, nous effectuons une comparaison
de chaînes. Si la comparaison est vraie, nous passons à l'intérieur de la
condition "if" et nous récupérons une deuxième entrée de l'utilisateur, stockée
dans la variable uVar3. Le deuxième appel de strcmp compare uVar3 à la chaîne
"le ripper" et stocke le résultat de la comparaison dans iVar1.
Cependant, le premier appel de strcmp a un paramètre manquant. Nous
pouvons supposer que ce paramètre manquant est arg_ch, mais cela doit être
confirmé. Pour cela, j'ai utilisé le décompilateur jdsec, que l'on peut
sélectionner dans Cutter en modifiant l'option en bas à droite, comme je l'ai
expliqué dans mes précédents blogs.
Password : 987654321

3 Autres problèmes
Tous les challenges que vous réussirez à résoudre dans l’une des 4 catégories
suivantes compteront pour ce BE : — App - Script — App - Systeme —
Programmation — Cracking

3.1 App - Script : Perl - Command injection


Password : PerlCanDoBetterThanYouThink

3.2 App - Systeme : ELF x86 - Stack buffer overflow basic 1


Password : 1w4ntm0r3pr0np1s

3-3 Cracking : ELF x86 - CrackPass


Entry point: 0x8048440

anti debug:
.text:0804868A test eax, eax

flag here:
.text:08048617 call _strcmp
.text:0804861C test eax, eax

----------------------------------------------------------

gdb-peda$ info file


Symbols from "/root/bin/Crack".
Local exec file:
`/root/bin/Crack', file type elf32-i386.
Entry point: 0x8048440
....
0x0804836c - 0x0804839c is .init
0x0804839c - 0x0804843c is .plt
0x08048440 - 0x0804877c is .text
0x0804877c - 0x08048798 is .fini
....

gdb-peda$ break *0x8048440


Breakpoint 1 at 0x8048440

gdb-peda$ run ander

0x8048437 <strcmp@plt+11>: jmp 0x804839c


0x804843c: add BYTE PTR [eax],al
0x804843e: add BYTE PTR [eax],al
=> 0x8048440: xor ebp,ebp
0x8048442: pop esi
0x8048443: mov ecx,esp
0x8048445: and esp,0xfffffff0
0x8048448: push eax
gdb-peda$ break *0x0804868A
Breakpoint 2 at 0x804868a

gdb-peda$ c

0x8048676: mov DWORD PTR [esp+0x4],0x0


0x804867e: mov DWORD PTR [esp],0x0
0x8048685: call 0x80483dc <ptrace@plt>
=> 0x804868a: test eax,eax
0x804868c: jns 0x804869f
0x804868e: mov DWORD PTR [esp],0x80487cf
0x8048695: call 0x804841c <puts@plt>
0x804869a: call 0x80483ac <abort@plt>

gdb-peda$ info reg $eax


eax 0xffffffff 0xffffffff

# BYPASS anti debug


gdb-peda$ set $eax=0

# Breakflag!
gdb-peda$ break *0x08048617
Breakpoint 3 at 0x8048617

gdb-peda$ c

0x804860b: call 0x804851c


0x8048610: mov DWORD PTR [esp+0x4],esi
0x8048614: mov DWORD PTR [esp],ebx
=> 0x8048617: call 0x804842c <strcmp@plt>
0x804861c: test eax,eax
0x804861e: jne 0x8048632
0x8048620: mov DWORD PTR [esp+0x4],ebx
0x8048624: mov DWORD PTR [esp],0x80487e8
Guessed arguments:
arg[0]: 0xbfffe690 ("ff07031d6fb052490149f44b1d5e94f1592b6bac93c06ca9")
arg[1]: 0xbfffe710 ("ander")

gdb-peda$ x/s $esi


0xbfffe710: "ander"

gdb-peda$ x/s $ebx


0xbfffe690: "ff07031d6fb052490149f44b1d5e94f1592b6bac93c06ca9"

----------------------------------------------------------

root@kali:~/bin# ./Crack
ff07031d6fb052490149f44b1d5e94f1592b6bac93c06ca9

Password : ff07031d6fb052490149f44b1d5e94f1592b6bac93c06ca9
3-4 Programmation : IRC - Uncompress me
La question indique explicitement qu'il s'agit d'une compression zlib +
encodage Base64, et donne un exemple, qui a été testé et traité dans l'ordre
suivant

eJxzrHItCqn0zC8AABBiA2g= => décodage Base64 => décompression zlib =>


AzErTyIop

En d'autres termes, nous devons effectuer un décodage Base64 de la chaîne


donnée par le robot, puis une décompression zlib.

Le code de la solution est affiché ci-dessous (python version 3.5.2) :

# ! /usr/bin/python
# -*- codage : UTF-8 -*-

import zlib
import base64
import re
import socket
CHARSET = 'utf-8'

def send_cmd(irc_sock, cmd) .


"""
Envoi d'une commande au serveur IRC

Args.
irc_sock : connexion socket au serveur IRC
cmd : commande à envoyer (pas besoin du terminateur \r\n, il sera rempli
automatiquement)

Retourne.
Aucun
"""

print(' => %s' % cmd)


irc_sock.send(('%s\r\n' % cmd).encode(CHARSET))
return

def send_msg(irc_sock, to, msg) .


"""
Envoi de la commande de message privé PRIVMSG au serveur IRC

Args.
irc_sock : connexion socket au serveur IRC
to : l'objet qui doit recevoir le message privé
msg : le contenu du message privé à envoyer

Retourne.
Aucun
"""
cmd = 'PRIVMSG %s :%s' % (to, msg)
send_cmd(irc_sock, cmd)
retour

def conn_irc(irc_host, irc_port, irc_chan, username, anywords) .


"""
Se connecter au canal de discussion spécifié sur le serveur IRC

Args.
irc_host : Serveur IRC hôte
irc_port : Port du service IRC
irc_chan : canal de discussion IRC
username : un surnom pour s'identifier dans le salon de discussion IRC
(n'importe quelle valeur est acceptable, tant qu'elle n'est pas utilisée par
quelqu'un d'autre sur IRC)
anywords : une phrase utilisée pour dire bonjour après avoir rejoint le
salon de discussion IRC pour la première fois.

Retourne.
irc_sock : connexion socket au serveur IRC
"""

irc_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)


irc_sock.connect((irc_host, irc_port))

# les commandes NICK et USER doivent être envoyées en premier pour


déclarer votre identité
# (notez que la même IP ne peut pas ouvrir plus de deux connexions en
même temps, sinon seule la première s'enregistrera avec succès)
send_cmd(irc_sock, 'NICK %s' % username)
send_cmd(irc_sock, 'USER %s %s %s %s :%s' % (username, username,
username, anywords))
send_cmd(irc_sock, 'JOIN %s' % irc_chan) # Rejoindre le canal
return irc_sock

def interface(irc_sock, bot_name, username) .


"""
Interagir avec le robot dans la salle de chat IRC avec des messages

Args.
irc_sock : connexion socket au serveur IRC
bot_name : pseudo du robot
username : votre propre pseudo

Retourne.
Aucun
"""

finish = False
while finish == False .
rsp_data = irc_sock.makefile(encoding=CHARSET)

# Analyse les données de la réponse ligne par ligne


for line in rsp_data.
print(line, end='')

if line.startswith('PING') .
send_cmd(irc_sock, line.replace('PING', 'PONG'))

# :EXP!EXP@hzv-tsd.o51.eaqa1b.IP MODE EXP +x


elif line.startswith(':%s' % username) .
send_msg(irc_sock, bot_name, '!ep4')
# :Candy!Candy@root-me.org PRIVMSG EXP
:eJyLyvIui/DKdw8IMvQyN/GxLDA0zDStCDaIdPY1AgCAhQhx
elif line.startswith(':%s' % bot_name) .
mth = re.match(r' :. + ? :(\S+)$', line)
if mth .
cipher = mth.group(1)
zip_byte = base64.b64decode(cipher) # décodage base64
byte = zlib.decompress(zip_byte) # décompression zlib
plain = bytes.decode(byte, CHARSET) # byte en chaîne de
caractères
send_msg(irc_sock, bot_name, '!ep4 -rep %s' % plain)

else .
send_cmd(irc_sock, 'QUIT') # Quitte le canal de discussion
finish = True
break
return

if __name__ == '__main__' .
irc_host = 'irc.root-me.org'
irc_port = 6667
irc_chan = '#root-me_challenge'
bot_name = 'Candy'
username = 'EXP'
anywords = 'http://exp-blog.com'

# Se connecter à la salle de chat IRC de ROOTME et rejoindre le canal de


chat CHALLENGE
irc_sock = conn_irc(irc_host, irc_port, irc_chan, username, anywords)

# Interagir avec le robot dans la salle de chat avec des messages


interface(irc_sock, bot_name, username)

# Ferme la connexion IRC


irc_sock.shutdown(2)
irc_sock.close()
Password : tumasp0wned
BE n°3 :
2.1 Web - Client : HTML - disabled buttons
En inspectant l'élément, il est possible de voir que le bouton est désactivé. Pour le rendre disponible, il faut
simplement enlever l'attribut "disabled" de la zone de saisie et du bouton.

<input disabled type="text" name="auth-login" value="" />


<input disabled type="submit" value="Member access" name="authbutton" />

l suffit de saisir le texte de notre choix, puis cliquer sur le bouton de soumission pour obtenir le mot de passe et
réussir le défi.

Résultat :

Le flag de ce challenge est : HTMLCantStopYou


2.2 Web - Client : Javascript - Authentification
Pour résoudre ce défi, vous devez ouvrir les outils de développement de votre navigateur et accéder au fichier
login.js. Il est clair que le mot de passe est écrit dans la condition "if", donc vous pouvez le copier pour réussir le défi.
Le pseudo requis est "4ad1n" et le mot de passe est "sh.org".

Le flag de ce challenge est : sh.org

2.3 Web - Serveur : HTML - Source code


Pour réussir le défi HTML - Source code, vous devez visiter l'URL du défi et afficher le code source en utilisant la
combinaison de touches "CTRL+U". Le mot de passe requis pour relever le défi se trouve à la ligne 29 du code source.
Une fois que vous avez trouvé le mot de passe, vous pouvez le soumettre pour terminer le défi.

Le flag de ce challenge est : nZ^&@q5&sjJHev0


2.4 Web - Serveur : HTTP - Open redirect

Lorsque vous ouvrez la page de ce défi, vous remarquez qu'il y a trois boutons qui permettent de passer à d'autres
pages en cliquant dessus. La question est de trouver un moyen de passer à une page qui n'est pas accessible via ces
trois boutons.

Pour cela, vous pouvez ouvrir les outils de développement de votre navigateur et accéder à l'onglet "Elements". Vous
verrez que chacun des trois boutons déclenche une URL avec des paramètres spécifiques : "?url=xxx&h=yyyy". En
analysant cela, vous constaterez que la page vérifie la valeur de "h" avant de passer à l'URL spécifiée, et que la valeur
de "h" est le résultat MD5 de l'URL. Pour passer à une autre page, vous pouvez donc construire une charge utile en
utilisant le paramètre "get" comme suit : "?url=xxx&h=to_md5(xxx)".

Pour générer le résultat MD5, vous pouvez utiliser l'outil Burp Suite -> Decoder (ou un autre constructeur MD5 en
ligne).

Le flag de ce challenge est : e6f8a530811d5a479812d7b82fc1a5c5

2.5 Réseau : FTP - authentification


Le problème est de trouver le mot de passe de l'utilisateur FTP après avoir transféré un fichier par FTP. Après avoir
cliqué sur le bouton de défi, un fichier appelé ch1.pcap est téléchargé, ce qui est immédiatement reconnaissable si
vous avez effectué une capture de paquets réseau. Après avoir ouvert le fichier avec Wireshark et l'avoir entièrement
analysé, il apparaît clairement qu'un seul paquet utilise le protocole de transfert de données FTP-DATA, ce qui
indique que c'est le fichier qui a été transféré par FTP précédemment.

Ensuite, vous pouvez cliquer avec le bouton droit de la souris sur le paquet FTP-DATA, puis choisir "Trace Stream" ->
"TCP Stream". En effectuant une trace TCP sur ce paquet, vous pouvez essayer de trouver le paquet qui a établi cette
session FTP.

Finalement, vous pouvez trouver le mot de passe de l'utilisateur FTP en résolvant le défi FTP, comme illustré dans la
Figure

Le flag de ce challenge est : cdts3500


2.6 Cryptanalyse : Encoding - ASCII

La procédure consiste à copier le texte présent sur la page, puis à ouvrir l'outil Burp Suite. Ensuite, on accède à
l'onglet "Décodeur" de Burp Suite et on colle le texte à décoder. On utilise alors le décodeur ASCII hex pour décrypter
le texte et retrouver le caractère ASCII original.

Le flag de ce challenge est : 2ac376481ae546cd689d5b91275d324e

3- Autre problème
3.5 Web - Client : Javascript - Authentification 2
La procédure pour obtenir le code source du script Java d'authentification consiste à cliquer sur le bouton
correspondant, ce qui fera apparaître une boîte interactive demandant le mot de passe. Ensuite, on inspecte la page
web et on clique sur l'onglet "Sources". On cherche alors le fichier "login.js" et en cliquant dessus, on peut accéder au
code source du script Java d'authentification.

var TheLists = ["GOD:HIDDEN"];


for (i = 0; i < TheLists.length; i++)

if (TheLists[i].indexOf(username) == 0)

var TheSplit = TheLists[i].split(":");


var TheUsername = TheSplit[0];
var ThePassword = TheSplit[1];
if (username == TheUsername && password == ThePassword)

On peut donc dire que le nom d’utilisateur est : GOD et le mot de passe est : HID-DEN .

Le flag de ce challenge est : HIDDEN


3.6 Web - Client : Javascript - Native code
Après avoir cliqué sur le bouton, la page s'affiche avec une fenêtre interactive qui force un commit, puis affiche un
message d'erreur d'échec. Pour résoudre ce défi, nous inspectons la page et cherchons un morceau de code
JavaScript caché nommé ch16.html.

En accédant au site web correspondant, il est possible de coller le contenu de la balise <script> et de décoder la
valeur associée.

Le flag de ce challenge est : toto123lol

3.7 Web - Serveur : PHP - Command injection


Après avoir ouvert la page, en saisissant 127.0.0.1 et en cliquant sur "soumettre", un retour s'affichera.
D'après les résultats, il semble que l'implémentation du code utilise une commande système. Pour vérifier cela, on
peut essayer de saisir la commande | ls -al dans l'interface et de valider. Si la commande est exécutée, l'écran
affichera la liste des fichiers dans le répertoire actuel, à partir de laquelle on peut repérer le fichier .passwd.

Le flag de ce challenge est : S3rv1ceP1n9Sup3rS3cure

3.8 Web - Serveur : CRLF


Lorsque la page de défi est chargée, on peut trouver trois lignes de journalisation initiales. En les analysant, on peut
voir qu'il s'agit des logs d'authentification, comprenant les événements suivants : "admin a échoué à s'authentifier",
"admin s'est authentifié" et "invité a échoué à s'authentifier". Si l'on entre des informations de connexion dans la boîte
de dialogue, le journal sera mis à jour avec une ligne d'échec d'authentification correspondante.
A ce stade, nous pouvons déduire que nous devons injecter des payloads dans la boîte de saisie du nom d’utilisateur
pour que le journal affiche une ligne "guest authenticated"(invité authentifié). Cela se fait en utilisant la méthode
CRLF suggérée par le titre, c’est-à-dire un retour à la ligne avec un encodage URL de %0d%0a (on note que
l’encodage URL pour les espaces est %20).
On ouvre la page à l’aide de Burp Suite -> Repeater et on définit les payloads dans les paramètres de requête HTTP
comme suit :

?username=guest%20authenticated.%0d%0aexp&password=none

On soumet la page et l’usurper avec succès pour obtenir le mot de passe et relever le défi.

Le flag de ce challenge est : rFSP&G0p&5uAg1%

3.9 Cryptanalyse : Encoding - UU


— A partir du titre on comprend qu’il suffit de chercher un décodeur UU.
— On choisit un décodeur UU en ligne par exemple ce site.
— On colle la chaîne.

Le flag de ce challenge est : ULTRASIMPLE

Vous aimerez peut-être aussi