Skip to content

Joomla Enumeration

7 min read Created Mar 28, 2026 Last updated Mar 30, 2026

Joomla enumeration identifies the installed version, active components, plugins, templates, and user accounts. Version is the critical signal: Joomla has a history of high-severity unauthenticated RCE and SQL injection vulnerabilities tied to specific releases and components. Run this after tech fingerprinting confirms Joomla. The attack surface extends beyond core to installed third-party components and the admin panel at /administrator/. Exposed configuration backups and directory listings add to that surface. Older Joomla 3.x installs carry a long tail of known RCE and SQLi CVEs. Knowing the exact version narrows your exploit search before running any tooling.

Key areas to cover during Joomla enumeration:

  • Core version from XML manifests and generator meta tag
  • Installed components and their individual versions
  • Admin panel accessibility at /administrator/
  • Configuration backup files (.bak, .old, ~)
  • User accounts through the REST API and login form
  • Directory listing on /administrator/components/

Confirm Joomla and Version

The XML manifest and admin generator tag disclose the version before running any tooling. The manifest at /administrator/manifests/files/joomla.xml returns a plain XML file with the exact version number. If that path returns a 404, the language file at /language/en-GB/en-GB.xml is a reliable fallback. The generator meta tag in page source confirms Joomla is present but often omits the minor release. Use all three paths in sequence so a blocked manifest does not hide the version:

┌──(kali㉿kali)-[~]
└─$ curl -sk http://$TARGET_IP:$PORT/administrator/manifests/files/joomla.xml | grep -i version
<version>3.9.26</version>
Explain command
-s Silent mode; suppresses progress meter and error messages.
-k Allows insecure SSL connections by skipping certificate verification.
http://$TARGET_IP:$PORT/administrator/manifests/files/joomla.xml Target URL with variable host and port pointing to Joomla manifest file.
-i Makes the grep pattern match case-insensitive.
version Search pattern to filter lines containing version information.
┌──(kali㉿kali)-[~]
└─$ curl -sk http://$TARGET_IP:$PORT/ | grep -i 'joomla\|generator'
<meta name="generator" content="Joomla! - Open Source Content Management" />
Explain command
-s Silent mode; suppresses progress meter and error messages.
-k Allow insecure SSL connections, skipping certificate verification.
http://$TARGET_IP:$PORT/ Target URL using variable placeholders for IP and port.
-i Makes the grep pattern match case-insensitive.
'joomla\|generator' Grep pattern matching lines containing 'joomla' or 'generator'.
┌──(kali㉿kali)-[~]
└─$ curl -sk http://$TARGET_IP:$PORT/language/en-GB/en-GB.xml | grep -i version
<version>3.9.26</version>
Explain command
-s Silent mode; suppresses progress meter and error messages.
-k Allows insecure SSL/TLS connections, skipping certificate verification.
http://$TARGET_IP:$PORT/language/en-GB/en-GB.xml Target URL with variable host and port pointing to a language XML file.
-i Makes the grep pattern match case-insensitive.
version Search pattern to filter lines containing 'version' from the XML output.

joomscan

joomscan is the primary automated tool for Joomla enumeration. It identifies version, vulnerable components, configuration issues, and backup files. Check the Core Joomla Vulnerability section first. A clean core means focus shifts to the component list. Directory listing on /administrator/components/ is a frequent misconfiguration joomscan flags directly. Run a second pass with --enumerate-components to map every installed component. Record each component name for CVE lookup before moving to manual checks.

┌──(kali㉿kali)-[~]
└─$ joomscan -u http://$TARGET_IP:$PORT/
[+] Detecting Joomla Version
[++] Joomla 3.9.26

[+] Core Joomla Vulnerability
[++] Target Joomla core is not vulnerable

[+] Checking Directory Listing
[++] directory has directory listing : http://10.10.10.50/administrator/components
Explain command
-u Specifies the target URL to scan.
http://$TARGET_IP:$PORT/ Target Joomla base URL with dynamic IP and port placeholders.
┌──(kali㉿kali)-[~]
└─$ joomscan -u http://$TARGET_IP:$PORT/ --enumerate-components
Explain command
-u Specifies the target URL to scan.
http://$TARGET_IP:$PORT/ Target host IP and port placeholder forming the base URL.
--enumerate-components Enumerates installed Joomla components on the target.

Admin Panel and Configuration Checks

Check whether the admin panel is accessible and whether configuration files are exposed. A 200 response on /administrator/ means the login page loads without IP restriction. Note this for credential attacks at a later stage. The more valuable find is a readable backup of configuration.php. Text editors like vi leave tilde backups on save. Deployment scripts sometimes drop .bak or .old copies alongside the live file. A readable backup exposes database credentials, the application secret key, and any SMTP settings stored in that file. PHP serves configuration.php itself without leaking the plaintext, so only backup file extensions expose the content.

┌──(kali㉿kali)-[~]
└─$ curl -sk -o /dev/null -w '%{http_code}' http://$TARGET_IP:$PORT/administrator/
200
Explain command
-s Silent mode; suppresses progress meter and error messages.
-k Allow insecure TLS connections, skipping certificate verification.
-o /dev/null Discard response body by redirecting output to /dev/null.
-w '%{http_code}' Print only the HTTP response status code after the request.
http://$TARGET_IP:$PORT/administrator/ Target URL built from variable host, port, and path to probe.
┌──(kali㉿kali)-[~]
└─$ curl -sk http://$TARGET_IP:$PORT/configuration.php.bak
┌──(kali㉿kali)-[~]
└─$ curl -sk http://$TARGET_IP:$PORT/configuration.php~
┌──(kali㉿kali)-[~]
└─$ curl -sk http://$TARGET_IP:$PORT/configuration.php.old
Explain command
-s Silent mode; suppresses progress meter and error messages.
-k Allow insecure TLS connections; skip certificate verification.
http://$TARGET_IP:$PORT/configuration.php.bak Target URL with IP, port, and backup file path placeholder.
http://$TARGET_IP:$PORT/configuration.php~ Target URL pointing to a tilde-suffixed editor backup file.
http://$TARGET_IP:$PORT/configuration.php.old Target URL pointing to a .old suffixed leftover config file.

User Enumeration

Joomla exposes user data through the API and registration error messages. The /api/index.php/v1/users endpoint returns usernames, user IDs, and group memberships in default configurations. If it returns a 403 or empty data, the Joomla API plugin may be disabled under Extensions. Check this in the admin panel if you already have access. The login form works as a username confirmation fallback. Different error messages for unknown usernames versus wrong passwords confirm account existence. If both errors look identical, the install has patched enumeration at the form level.

┌──(kali㉿kali)-[~]
└─$ curl -sk http://$TARGET_IP:$PORT/api/index.php/v1/users | python3 -m json.tool
Explain command
-s Silent mode; suppresses progress meter and error messages.
-k Allows insecure SSL connections by skipping certificate verification.
http://$TARGET_IP:$PORT/api/index.php/v1/users Target URL with variable host and port pointing to Joomla users API endpoint.
-m json.tool Runs Python's built-in json.tool module to pretty-print JSON output.
┌──(kali㉿kali)-[~]
└─$ curl -sk -X POST http://$TARGET_IP:$PORT/index.php -d 'option=com_users&task=user.login&username=admin&password=wrongpassword' | grep -i 'invalid\|error\|username'
Explain command
-s Silent mode; suppresses progress meter and error messages.
-k Allows insecure SSL connections by skipping certificate verification.
-X POST Specifies HTTP POST as the request method.
http://$TARGET_IP:$PORT/index.php Target URL with variable host IP and port placeholders.
-d 'option=com_users&task=user.login&username=admin&password=wrongpassword' Sends URL-encoded POST body with Joomla login credentials.
-i 'invalid\|error\|username' Case-insensitive grep filter for keywords: invalid, error, or username.

Component and Plugin Enumeration

Joomla components often have their own vulnerabilities separate from core. Enumerate installed components by probing common paths. The ?option=FUZZ approach works because Joomla routes component requests through the option parameter. A 200 response with real body content means the component is installed and active. Use -fw 100 to filter out default-page responses that match the error page word count. Directory listing on /administrator/components/ gives a direct component list when that misconfiguration is present. Record each component slug and search it against Exploit-DB by name before moving to manual review.

┌──(kali㉿kali)-[~]
└─$ ffuf -w /usr/share/seclists/Discovery/Web-Content/CMS/joomla-components.txt -u http://$TARGET_IP:$PORT/index.php?option=FUZZ -mc 200,301,302 -fw 100
Explain command
-w /usr/share/seclists/Discovery/Web-Content/CMS/joomla-components.txt Wordlist file path used for fuzzing input.
-u http://$TARGET_IP:$PORT/index.php?option=FUZZ Target URL with FUZZ keyword marking the injection point.
$TARGET_IP:$PORT Variable placeholders for the target host IP and port.
-mc 200,301,302 Match only responses with HTTP status codes 200, 301, or 302.
-fw 100 Filter out responses containing exactly 100 words in the body.
┌──(kali㉿kali)-[~]
└─$ curl -sk http://$TARGET_IP:$PORT/administrator/components/ | grep -i 'href' | grep -oP '(?<=href=")[^"]+' | sort -u
Explain command
-s Silent mode; suppresses progress meter and error messages.
-k Skips SSL/TLS certificate verification.
http://$TARGET_IP:$PORT/administrator/components/ Target URL with variable host and port placeholders.
-i Case-insensitive pattern matching in grep.
-o Prints only the matched part of the line.
-P Enables Perl-compatible regular expressions (PCRE).
(?<=href=")[^"]+' PCRE lookbehind to extract URL values from href attributes.
-u Outputs only unique sorted lines, removing duplicates.

Cross-reference identified components and their versions against the Joomla Vulnerable Extension List. Third-party components are far more frequently vulnerable than Joomla core and are the most common path to exploitation. Get component versions from their XML manifests under /administrator/manifests/packages/ or from each component directory. File upload components, contact forms, and e-commerce plugins concentrate the most exploitable conditions. When a manifest has no version tag, search Exploit-DB for the component name alone. Many vulnerabilities affect all known versions of a given component, so absence of a version does not mean absence of risk.

References