Ignite: When the App Password Becomes Root
Machine: Ignite
Introduction
Ignite starts with a public web exploit, but that is not what made the box interesting to me. The initial foothold came from Fuel CMS, yet the part worth paying attention to was what happened after that: the shell was awkward, the usual local checks did not produce a convincing privilege escalation path, and the machine finally opened up because the application was holding a secret that mattered well beyond the application itself.
That gave the box a more useful shape than a simple exploit exercise. I got execution through the CMS, turned that into a usable shell, and then moved back into the application files to look for the kind of operational weakness that often matters more than the original bug.
Initial Enumeration
I started with a full TCP scan to see how much of the target was actually exposed.
nmap -sC -sV -p- -T4 -oA scan TARGET_IP
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.18 (Ubuntu)
| http-robots.txt: 1 disallowed entry
|_/fuel/
|_http-title: Welcome to FUEL CMS
That result narrowed the box down immediately. Only port 80 was open, and both the page title and robots.txt pointed straight at Fuel CMS. There was no reason to treat this like a broad attack surface problem. The web application was clearly the machine.
I also ran a quick directory scan to check whether there was another path worth pursuing.
gobuster dir -u http://TARGET_IP/ -w /usr/share/dirb/wordlists/common.txt
/assets (Status: 301)
/home (Status: 200)
/index.php (Status: 200)
/offline (Status: 200)
/robots.txt (Status: 200)
/server-status (Status: 403)
That did not change the picture much. Gobuster confirmed the application structure, but it did not reveal a second route that competed with Fuel CMS as the main lead. At that point, the sensible move was to stop widening the enumeration and start validating the CMS path directly.
Matching Fuel CMS to a Working Exploit
With Fuel CMS identified, I checked for a public exploit that matched the target.
searchsploit fuel
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
I took the Python exploit and copied it locally:
searchsploit -m 47138
There was not much mystery at this stage. The web layer had already collapsed down to a specific CMS, and the target was not offering another service or misconfiguration that looked more promising. The right next step was simply to test whether the published RCE still worked and see how much access the application context would give me.
Gaining Code Execution
I ran the exploit and used a few basic commands to confirm where I had landed.
python2 47138.py
cmd: ls
README.md
assets
composer.json
fuel
index.php
robots.txt
cmd: pwd
/var/www/html
cmd: whoami
www-data
That gave me command execution in the web root as www-data.
The foothold worked, but it was not especially clean. Output came back mixed with PHP warnings and extra text from the exploit response handling, so every command needed a bit of interpretation. The code execution was real, but the shell was noisy enough that I did not want to rely on it for anything more interactive than basic enumeration.
Finding the User Flag
From there I started exploring the filesystem from the web context. My first pass was the usual one: look for user.txt, check common directories, and see what the service account could read. That did not immediately produce anything useful, which was a good reminder not to force the machine into a pattern just because many boxes use one.
After moving into /home, I found that the relevant file for this stage was flag.txt under the www-data home directory rather than a more predictable user.txt.
cd /home
ls -la
cd www-data
ls
cat flag.txt
flag.txt
6470e394cbf6dab6a91682cc8585059b
It was a small pivot, but it set the tone for the rest of the machine. The box was not asking for deep discovery here. It was asking me to stay close to the compromised context and pay attention to what was actually present.
Turning the Foothold into a Real Shell
The exploit was enough to read files and move around, but not enough to work comfortably. I opened a listener and triggered a reverse shell back to my machine.
nc -lvnp 4444
When the shell connected, it dropped me into a minimal /bin/sh session:
connect to [LISTENER_IP] from (UNKNOWN) [TARGET_IP] 47880
/bin/sh: 0: can't access tty; job control turned off
www-data@ubuntu:/var/www/html$
That was workable, but only barely. Anything interactive was going to be painful, so I upgraded it into a proper TTY:
python3 -c 'import pty; pty.spawn("/bin/bash")'
stty raw -echo; fg
export TERM=xterm
That mattered because the next steps were likely to involve testing credentials or using tools that do not behave well in a half-broken shell. Once the session was stabilized, the box became much easier to reason about.
Local Enumeration Without Forcing a Dead End
With a better shell, I checked the usual local escalation routes.
uname -a
cat /etc/passwd
sudo -l
find / -perm -4000 -type f 2>/dev/null
Nothing there justified going deeper. The checks were routine, but they were not pointing toward a real path. There was no obvious sudo misconfiguration, no standout SUID binary worth chasing, and nothing that made a classic local privilege escalation route look more promising than the access I already had through the application.
That was the point where it made more sense to stop treating post-exploitation and privilege escalation as separate problems. I already had code execution through Fuel CMS. The more useful question was what the application could tell me about the rest of the system.
Reading the Configuration Instead of Chasing the Kernel
Once I shifted back to the application files, the next target was straightforward: configuration. From a www-data shell inside the web root, Fuel CMS configuration is not background detail. It is part of the attack surface.
I checked the database configuration file:
cat /var/www/html/fuel/application/config/database.php
'hostname' => 'localhost',
'username' => 'root',
'password' => 'mememe',
'database' => 'fuel_schema',
'dbdriver' => 'mysqli',
That was the real opening. The application was storing database credentials in plain configuration, which is expected in itself, but the important part was the value of the secret. At that point I was no longer looking at a database password in isolation. I was looking at a credential worth testing anywhere trust boundaries might have been blurred.
That was a better lead than anything local enumeration had given me. The exploit had already bought access to the app, and the app was now exposing a secret that looked likely to matter elsewhere.
Reusing the Application Secret to Become Root
With a stable shell and a candidate password, I tested it directly against the local root account:
su root
After entering the password from the Fuel CMS configuration, I landed in a root shell. I verified the context and grabbed the final flag.
whoami
cd /root
cat root.txt
root
b9bbcb33e11b80be759c4e844862482d
That completed the machine.
The escalation was simple, but that is exactly why it worked well as a lab. There was no need for a kernel exploit or a complicated binary abuse chain. The application had already exposed the credential that mattered, and the operating system trusted it too.
Conclusion
Ignite is built around a public Fuel CMS RCE, but that is only the start of the story. The exploit gave me execution as www-data, but the machine fell because that access extended into the application configuration, and the configuration exposed a password that crossed boundaries it should never have crossed.
That is the part worth carrying outside the lab. A compromised web application does not just mean a web shell. It often means access to the files, credentials, and assumptions the application relies on every day. In this case, the exploit was only the entry point. The real weakness was operational trust: the same secret was trusted by the app and by root, and once that secret was visible, the rest of the machine was already half-open.