ConvertMyVideo - TryHackMe Writeup
The link for this lab is located here: https://tryhackme.com/room/convertmyvideo
You can convert your videos - Why don't you check it out!
Full Walkthrough
First thing we do is run an Nmap scan on all ports to identify which ones are open:
-p- specifies all ports
10.10.84.21 is the target IP
-oN allports.scan outputs in Nmap format
This returns two ports and services running - SSH and HTTP. With this, we can run a more detailed scan on these two ports only to gather more information like versions and possible enumeration.
This tells us that OpenSSH is running and Apache httpd 2.4.9 is running possibly through Ubuntu. It’s very unlikely that SSH has a vulnerability we can gain initial access so we can leave that for now and focus on the website.
We can navigate to the website and check it out.
Here, we see a simple box that wants us to input a Video ID and it will convert it to what looks like an MP3 based on the images.
Before we start playing around with the input sanitization and other web vulnerabilities, we can see if there are any hidden directories by using a tool like Feroxbuster.
Here, we don’t see a lot, but we do see a /admin page. We can see what it leads us to.
Unfortunately this just leads us to a login popup box most likely using Basic Authentication for which we don’t know any credentials yet. It’s possible to bruteforce this login panel, but it’s better to do that as a last resort rather than hammer the service with requests as we might break it.
As it’s a website running, we can run a tool like Nikto on it to see if it identifies any vulnerabilities immediately. We get some results back, but nothing of real value.
Next step I took is running an Automated Scan through OWASP ZAP Proxy.
After letting it run for a few minutes, we once again get a few alerts, but nothing that stands out as critical and a major vulnerability.
Again, before attacking the site, we can look at the source code and see if any hidden comments appear - they do not.
Moving on to playing around with the input validation, we can provide a random string - in this case, test123 - to the input box on the site and intercept the request in Burp Suite.
As we can see, it looks like it simply appends the string to the end of “https://www.youtube.com/watch?v=” indicating it wants a real YouTube video inputted.
With this request, we can see what the response looks like.
As we can see, it returns an error indicating it is an incomplete Youtube ID.
However, more interesting it looks like "--restrict-filenames" is a parameter that can be passed - is this a program simply being run from a command line?
With this, what happens if we just input a random string without the youtube.com part as part of the yt_url parmeter passed? In this case, I tried executing a simple “ls” command.
A different error returns. On the third line of the response it tells us we can run "youtube-dl" - we now know what program is being ran in the background.
What is Youtube-dl? Let’s find out.
It allows you to download videos from YouTube or other platforms.
SIDE NOTE: I have used Youtube-dl in a previous job so I have knowledge of how it works and its command line parameters. If you haven’t you can read through the code itself, see how it works, play around with it and just get to know it.
Knowing it is simply run from a command line, what happens if we supply a Youtube ID and then supply a second Linux command separated by a semicolon to execute both commands?
We get an interesting error, but it looks like it is trying to execute the ls command. What happens if we add another semicolon at the end to essentially close it off?
Now we’re getting somewhere! As you can see by the highlighted section, the ls command is actually executed and returned to us. We can see things like admin, images, index.php and more.
With this, we can try executing “ls -la” to get more information.
Unfortunately, we get another error.
At this point, we know that the “ls” command works but “ls -la” doesn’t. What is the difference between these two commands? The second command has a space in it which could be causing problems.
What happens if we try and use URL encoding to encode the space?
We get the same error.
Something you might not know about Linux is that there is another way to include a space via the $IFS variable - the Internal Field Seperator. It’s used by the shell to determine how to do word splitting (i.e. how to recognize word boundaries).
By default, the $IFS value is a space, tab and then a newline. You can kind of see this in the terminal by echoing it out. Additionally, you can see what the value is by using the “cat -etv <<<“$IFS” command.
For more information, you can read the following article and learn more about it. In short, it’s incredibly useful in BASH scripting for word splitting.
As an example, if we simply echo “hello” to the terminal, it simply prints it on a single line. However, if we echo hello with the $IFS variable in between, we can see there is a newline, a space before hello, and then a tab on the last line.
With this new information, what happens if instead of using a space, we use the $IFS variable and simply echo out a string to test if it works?
It works! In the response, we can see the long hello string was executed using echo with the $IFS variable.
With this, we can now use full Linux commands to gain a reverse shell. For this scenario, I first hosted a PHP reverse shell on port 80 using Python3.
Then, through Burp Suite Repeater, I sent a wget request to download the reverse shell to the target machine.
As you can see, the download worked and we get an OK message from the target. With the file now on the target, we can identify what the current directory is on the target by running the “pwd” command.
This program/webpage is being hosted in the /var/www/html directory. For a sanity check, we can run ls once again to make sure our PHP shell is showing up.
It does! However, what is more important is we can see the index.php file being listed out indicating that this is in the same directory as the home page.
To make sure, we can return to the home page and see that the index.php page is loaded.
Now it’s time to get a reverse shell. First, we can start a Netcat listener on any port - I choose 8888 which is the same as I set in the php-reverse-shell.php file.
Finally, as we are in the same directory and NOT a sub directory, we can simply navigate to http://10.10.84.21/php-reverse-shell.php to execute the PHP script.
We get a shell!
Next, we can perform some simple post-exploitation enumeration like checking the home directory.
Here, we find a user called “dmv” in the /home folder, but no files really interest us. It’s a good idea to check the bash history file, but here nothing of note is in there.
Next, we can try navigating to the /var/www/html folder and see if anything exists there.
Immediately, we see an “admin” directory which is intriguing. Let’s take a look inside.
Listing the contents of the admin directory, we see the flag.txt file, but we also see the “.htpasswd” file.
We can do a little research and understand what this file is.
It seems this file possibly stores credentials for basic authentication of HTTP users - remember back to when we saw the login popup? Maybe this file contains the credentials for that login.
Time to grab those credentials.
This reveals a username of itsmeadmin with a password hash. With this hash, we can feed it to John the Ripper and try and crack it using the rockyou.txt wordlist.
Success! This returns a password of “jessie”. With some valid credentials, we can now try and SSH into the machine using these new found credentials.
Unfortunately, it seems as if this is a dead end. Let’s keep the credentials in our back pocket and move on for now.
Going back to the /admin directory on the webpage, we can log in with these credentials and gain access to the admin panel.
Here, we see a button to clean downloads. Before clicking it, we can check the source code and see if this button executes a script or gain an idea of what it’s doing.
Interesting! It seems as if this button simply just executes the rm command on Linux and removes any files located in /var/www/html/tmp/downloads.
In my mind, typically clean up scripts are executed on a schedule so a good thing to check for is any cron jobs that may bee running.
Unfortunately, we don’t see any cron jobs running right now with the privileges we have as www-data. Performing further enumeration, I decided to look into the /tmp folder inside /var/www/html and found the clean.sh script which contains the same content that removes the downloads.
At this point, manual enumeration could be done but a quicker way is to use something like LinPEAS. To transfer it over, I simply started a Python3 web server on my attacker machine and used wget to download it to the /tmp directory.
Then, we ran it.
After letting it run, nothing will really stand out - get your eagle eyes out. If we look very closely through the results, you will see something that seems a bit odd.
Under the weird processes run by root section, we can see that cron is indeed being ran by root meaning there is likely a cron job being ran by root - but what is it running?
Doing a little bit of researching to see if we can snoop on root cron jobs, we stumble across a tool called Pspy.
Reading through, it seems Pspy allows you to snoop on processes without needing root permissions - this sounds perfect!
To run this tool, first download the 64 bit version of the tool. Once downloaded, simply host the file using a Python3 web server.
Then, use wget on the target to download it to the /tmp directory again.
Finally, execute it using “./pspy64”
After letting it run, we are specifically looking for a Cron process. Near the bottom, we find what we are looking for.
Here, we can see that UID of 0 (this is root) is moving into the /var/www/html/tmp directory and using BASH to execute the clean.sh script we saw earlier - bingo!
You should now be thinking - can we overwrite this file? Let’s check the permissions.
Interestingly, it seems that this file is not owned by root, but is actually owned by www-data - the user we currently are.
This means that we have read and write permissions, but we also have the ability to change the permissions for the file itself. As a precaution, I simply changed the permissions of this file to 777.
Then, because we have write permissions on this file, I simply replaced the contents with a BASH one liner that connects back to my attacker machine on port 5555.
Before executing, we start a Netcat listener on that same port.
After waiting a short while (<2 minutes), the cron job is executed and instead of cleaning the folder like an obedient servant, it connects back to us and we get a root shell!