TryHackMe Dreaming Walkthrough: Initial Enumeration

TryHackMe Dreaming Walkthrough

I started with an Nmap scan to determine which services were exposed by the target.

nmap -sC -sV -p- <TARGET_IP>

The attack surface was fairly small, with the important services being SSH and HTTP.

22/tcp    SSH
80/tcp    HTTP

Browsing directly to the web server did not reveal much initially, so the next step was directory enumeration.

gobuster dir -u http://<TARGET_IP>/ -w /usr/share/wordlists/dirb/common.txt

Enumeration revealed an interesting directory:

/app/

Exploring the application eventually revealed an installation of Pluck CMS 4.7.13.

Finding an exact product and version number is always worth investigating because it gives us something specific to research rather than blindly testing the server.

Finding the Pluck CMS Vulnerability

Researching Pluck CMS 4.7.13 revealed a known authenticated file-upload vulnerability that can lead to remote code execution.

Searchsploit can also be used to look for available information:

searchsploit pluck 4.7.13

The vulnerability affecting this version of Pluck CMS is associated with CVE-2020-29607.

The important lesson here is not simply finding an exploit. Enumeration gave us the exact CMS and version, which allowed us to narrow the attack considerably.

After gaining access to the Pluck administration functionality, the vulnerable upload mechanism provides a way to execute PHP on the server and establish the initial foothold.

At this point, the challenge moves away from web exploitation and becomes a Linux privilege-escalation exercise.

python3 exploit.py <server_ip> <server_port> <pass> <cms_path>

Enumerating the Linux Host

After gaining access to the machine, I started enumeration again.

Some basic commands are useful for establishing where we are and what privileges we currently have.

whoami
id
pwd
ls -la

I also started looking through directories containing custom applications, scripts, and configuration files.

One particularly interesting location was:

/opt

Inside were Python scripts that deserved further investigation.

Among the interesting files were:

getDreams.py
test.py

Examining the scripts revealed information that should not have been exposed to the web-server account.

The test.py script contained authentication information associated with the Pluck application.

This is an important lesson from Dreaming: credentials do not always live in traditional configuration files.

Developers sometimes leave passwords, API keys, database credentials, and test accounts directly inside scripts.

The information discovered here provided the next step in the room and allowed movement from the web-server context to the Linux user lucien.

Enumerating the Lucien Account

After gaining access as Lucien, I started enumeration again.

One of the first things worth checking when compromising a user account is shell history.

cat ~/.bash_history

Shell history can contain a surprising amount of useful information.

Users occasionally enter passwords directly into commands, connect to databases from the terminal, or leave behind commands that reveal how applications are configured.

In this case, Lucien’s history provided information for accessing MySQL.

Now the database became another part of the attack surface.

Enumerating MySQL

Using the discovered credentials, I connected to MySQL.

mysql -u lucien -p

Once connected, I enumerated the available databases.

SHOW DATABASES;

One database stood out:

library

I selected it:

USE library;

Then enumerated the available tables:

SHOW TABLES;

The important table was:

dreams

The contents could then be examined with:

SELECT dreamer, dream FROM dreams;

The table contains columns named:

dreamer
dream

Each row simply contains data associated with a dreamer and their dream.

Conceptually, the results look something like:

Alice    Flying through the sky
Bob      Exploring ancient ruins

There is nothing executable about those database rows by themselves.

The interesting part is what another application does with that data.

Understanding getDreams.py

The next important file was getDreams.py.

The script retrieves the dreamer and dream values from the MySQL database and processes them.

Conceptually, the database operation resembles:

SELECT dreamer, dream FROM dreams;

The problem appears when information retrieved from the database is eventually incorporated into an operating-system command.

That creates a dangerous trust relationship:

MySQL Database
      |
      v
getDreams.py
      |
      v
Shell Command
      |
      v
Operating System

The database itself is not executing commands.

Instead, getDreams.py trusts information retrieved from the database and later allows that information to influence something executed by the operating system.

If an attacker can modify the database contents, that becomes significantly more interesting.

Manipulating the Dreams Table

Lucien has the ability to modify information inside the dreams table.

A new database entry can be created using the normal SQL structure:

INSERT INTO dreams (dreamer, dream)
VALUES ('test', '<CONTROLLED_DATA>');

By itself, inserting information into a database is not a privilege-escalation vulnerability.

The problem is that getDreams.py later retrieves that controlled information and uses it unsafely.

The next question is therefore:

Who can execute getDreams.py?

Checking Lucien’s sudo permissions provides the answer.

sudo -l

Lucien is permitted to execute the getDreams.py script as another user: death.

Now the vulnerability becomes much more serious.

The attack path looks like this:

Lucien
   |
   v
Controls MySQL Data
   |
   v
getDreams.py Reads the Data
   |
   v
Data Reaches a Shell Command
   |
   v
Script Executes as Death

The permitted script can be executed in the Death user’s context with:

sudo -u death /usr/bin/python3 /home/death/getDreams.py

Because controlled database information eventually reaches the shell, the combination of database access and sudo permissions creates the next privilege-escalation opportunity.

This allows us to move from lucien to death.

Enumerating the Death Account

Once again, gaining access to another account means starting enumeration over.

Different users may have access to completely different files, scripts, directories, credentials, and services.

From the Death account, another Python script becomes particularly interesting.

The next target involves the morpheus account and a script named:

restore.py

Looking through the script shows that it imports Python’s shutil module.

For example:

import shutil

Importing shutil is completely normal.

The vulnerability is not the import itself.

The problem is the permissions assigned to the Python library being imported.

Python Library Hijacking

Python searches for modules when an import statement is encountered.

If a more privileged script imports a Python module that a lower-privileged user can modify, that user may be able to influence what code gets executed.

In Dreaming, the Death user has the ability to modify the Python library used by the more privileged restore.py process.

The relationship looks like this:

restore.py
    |
    v
import shutil
    |
    v
Writable Python Library
    |
    v
Code Executes in the Context of restore.py

This creates a classic Python library hijacking opportunity.

The important security issue is the file permission.

A privileged process should never import executable Python code that can be modified by a less-privileged account.

Once the writable library is identified and the execution behavior of restore.py is understood, the imported module can be used to influence execution in the Morpheus context.

That provides the final privilege transition required for the room.

The Complete Dreaming Attack Path

One of the things I liked about this room is that no single vulnerability provides the entire compromise.

Instead, Dreaming is built around chaining several weaknesses together.

The overall attack path looks like this:

Web Enumeration
      |
      v
Pluck CMS 4.7.13
      |
      v
File Upload / Code Execution
      |
      v
Web Server Access
      |
      v
Exposed Credentials
      |
      v
Lucien
      |
      v
MySQL Credentials
      |
      v
Writable Dreams Data
      |
      v
getDreams.py Command Injection
      |
      v
Sudo Permission
      |
      v
Death
      |
      v
Writable Python Library
      |
      v
Python Library Hijacking
      |
      v
Morpheus

This is what makes the TryHackMe Dreaming Walkthrough particularly useful for learning privilege escalation.

Each mistake creates just enough access to discover the next one.

What Dreaming Teaches

The biggest lesson from Dreaming is simple:

Enumeration starts over every time your privileges change.

Getting the first shell does not mean enumeration is finished.

Changing from the web-server account to Lucien does not mean enumeration is finished.

Changing from Lucien to Death does not mean enumeration is finished either.

Every new account may expose:

  • Different files
  • Different credentials
  • Different sudo permissions
  • Different scripts
  • Different database access
  • Different writable directories
  • Different scheduled processes
  • Different trust relationships

Dreaming rewards repeatedly asking the same question:

What can this user access that the previous user could not?

That mindset is much more useful than immediately searching for a privilege-escalation exploit.

Defensive Takeaways

Dreaming also contains several good defensive lessons.

Keep Web Applications Updated

The initial access begins with an outdated version of Pluck CMS.

Known vulnerable software should be patched or upgraded, especially when it is directly exposed through a web server.

Don’t Store Credentials in Scripts

Passwords and database credentials should not be embedded directly inside Python scripts.

Secrets should be stored using an appropriate credential-management system and protected with restrictive permissions.

Watch Shell History

Credentials entered directly on the command line may remain inside shell history.

Administrators and developers should avoid placing passwords directly into commands whenever possible.

Treat Database Content as Untrusted Input

Information coming from a database should not automatically be considered safe.

If users can modify database records, that data is still attacker-controlled input.

Passing database information into shell commands without proper validation can therefore create command-injection vulnerabilities.

Review Sudo Permissions

Sudo rules should follow the principle of least privilege.

Allowing one user to execute a custom script as another user can create an unexpected escalation path if that script processes attacker-controlled information.

Protect Python Libraries

Privileged Python scripts should never import modules that less-privileged users can modify.

Writable libraries can turn an otherwise harmless import statement into a privilege-escalation vulnerability.

Final Thoughts

The TryHackMe Dreaming Walkthrough demonstrates how several relatively small security mistakes can be chained into a complete compromise.

Pluck CMS provides the initial foothold, but the more interesting parts of the room happen afterward.

Exposed credentials lead to Lucien. MySQL provides attacker-controlled data. getDreams.py introduces command injection. Sudo provides the transition to Death, and insecure Python library permissions create the final path to Morpheus.

More importantly, Dreaming reinforces one of the most valuable habits in penetration testing:

Enumerate. Gain access. Enumerate again.

Understanding why each privilege transition works is far more useful than simply copying the commands required to complete the room.

No flags have been included in this walkthrough.

If you enjoyed this room, check out my other TryHackMe walkthroughs on RootNotebook for more web exploitation, Linux privilege escalation, and enumeration challenges.

You can also visit the official TryHackMe Dreaming room to work through the challenge yourself.

For additional information about the web vulnerability used during the initial foothold, the National Vulnerability Database entry for CVE-2020-29607 provides additional technical details.

Similar Posts