π© Level of the challenge: Easy
Tools used:
Nmap
GoBuster
SSH
MySQL
Python
Starting in 3, 2 1...
Welcome to the world of dreams! The "Dreaming" challenge from TryHackMe is a beautifully crafted fantasy-themed box that takes us on a journey through the realm of Lucian, Death and Morpheus.
What makes this box special isn't just the technical aspects - it's how the creators wove together Greek mythology with cybersecurity concepts.
Initial Enumeration
I initiated the assessment using
nmap -A -v [target-ip]
to discover the following open ports:
SSH (22) - Our potential gateway once we find some credentials
HTTP (80) - A web service running Apache
Given that port 80 is open, let's follow the path of...
Web Enumeration
Down the rabbit hole, I was greeted by... drumroll please... the Apache default page!
You know that feeling when you see a default page? It's like opening a book and finding the first page blank - there's definitely more to the story, but you need to dig deeper. This was clearly a job for directory enumeration.
Directory Brute-forcing with GoBuster
I continued by using GoBuster
:
gobuster dir -u http://[target-ip] -w [wordlist]
The /app
directory was found.
I accessed the page and discovered a folder called pluck-4.7.13/
Web Application Analysis
Navigating to /app
, I was greeted by a page containing a quote:
Bottom it can be observed the admin
page. Where is that going to bring us to...?
The login page. In this situation, we can either perform some trial and error or to go for some OSINT and look for the default password of this CMS. Exploring mode activated! π΅οΈ
After some digging through documentation and forums, I found the default credentials.
That moment when the credentials work and you are actually inside the application? Pure magic! I spent a good amount of time just clicking around, understanding the application's structure. This isn't just about rushing to the next step - it's about understanding your environment.
Discovering the upload page was exactly what I needed. All I had to do was to surf on the web and search in exploit db (or searchsploit if you prefer CLI) a payload tailored for file upload vulnerability found in pluck-4.7.13. Exploit 49909 was the one.
Once the shell spawned, checked whoami
and what the directory I was in contained.
And then changed directory to root (/
)
The /opt
directory caught my attention because, that's where optional software typically lives.
I discovered two Python scripts:
-getDreams.py
-test.py
I wonder what's inside the script getDreams
. Am I dreaming? These are Death
's MySQL credentials! Or are they? We could test them or check test.py
. I'd rather go on with checking the script, because based on the order of flag retrievals, we definitely must get Lucien
's flag and then Death
's.
Looking at the code, the following vulnerability is observed Command Injection. The combination between the user input and shell=True
results into a high risk of command injection. Basically, as a malicious actor can alter the integrity of the database by creating the name of the dreamer and instead of a legitimate input (like, the dream- Want to become a famous singer π€), would provide a command, with the final result of breaching the confidentiality. We'll see that in action a bit later. Let's move on to test.py
.
In test.py
, we literally found one Lucien
's password. But I keep it redacted:
Finding credentials hardcoded in scripts is like finding a $20 bill in an old jacket - unexpected but incredibly welcome! The developers had left Lucian's password right there in the Python code. π€©
It's a classic security mistake that we see all too often in real-world scenarios. Developers think, "It's just a test script" or "Only we have access to this."- however this translates into Insecure Credential Storage.
Lateral Movement
ssh lucian@[target-ip]
That satisfying moment when SSH accepts your credentials and you get your first proper shell! No more web application limitations - now we're on the actual system. I will look around and grab that user flag! At the same time- let's be conscious: it's not over yet! We still have two other characters whose flags can't just escape. So, after grabbing my first treasure, I will have a look into the first file, i.e .bash_history
.
This is where things got really interesting. Not only have we discovered MySQL credentials [password redacted], but it can be deducted there was a privilege escalation at some point.
I connected on the MySQL database using the credentials found
The first step after connecting is performing reconnaissance by using the command show tables;
, followed by select* from dreams;
. Given the data obtained- remember the Command Injection vulnerability detailed earlier? Now it's time to exploit that, by inserting a new row in the table which contains a script for shell spawning.
The next step is checking the sudo capabilites of lucien
. We discover that the user doesn't need a password to perform the command outlined in the screenshot. Essentially, the current user can execute getDreams.py
script as death
and become that user. As it can be observed, the manual entry provided earlier is not visible.
We're going to ensure lucien
has the privilege to run getDreams.py
script by running chmod 777 getDreams.py
. Essentially, this gives read, write, execute permissions, thus establishing persistence.
That's an optional step, by the way.
Password and Mythology
I would like to ask you: did you know that Democritus trained himself for this inevitable event by going into solitude and often visiting the palms? What's Democritus' business in this whole challenge? You will get that when you see death
's password π. I won't be revealing it here, but access getDreams.py
from /death
and not from /opt
and you'll get there.
I love how this challenge weaves philosophical references throughout the technical content. It's not just about exploitation - it's about the journey, the preparation, the patience required to succeed. Democritus understood that mastery comes through deliberate practice and isolation from distractions. Kind of like how we need to focus deeply when we're working through complex privilege escalation paths!
By the way, here is the flag:
The Python Script mystery
Here's where the challenge got really clever. The getdreams
Python script in the current directory wasn't the same as the one in /opt. This kind of PATH confusion is a common real-world privilege escalation vector. The system would execute the local script with elevated privileges because of how the permissions were set up.
Privilege Escalation
The God of Dreams Guards His Secrets.
Of course, Morpheus saved the best for him. Only in our dreams we could have accessed the file by being someone else than the God of Dreams and the son of Hypnos.
I checked whether might be temporary assignments...however, nothing came to avail.
Thus, I leveraged the power of find
, to find files with SUID set
The Final Modification
The final step involved modifying the shutil.py
) to grant us the permissions we needed. Notice the line in green brackets: that's what we need to add so we can elevate the privileges.
And here is the flag:
This was an astonishing tour in Lucian, Death and Morpheus world. It's time to wake up for the next challenge. Let my know your thoughts!
Top comments (2)
Hey, creator of Dreaming here. Outstanding post, maybe you can submit it as a Write-Up in the THM Room so we can keep it there too!
Hey @b1d0ws , thank you for your words! It's a pleasant surprise to see you commenting on this post π