· 8 min read
If you run WordPress, WPScan is probably already in your toolbox. It enumerates the core version, lists installed plugins and themes, and matches them against a curated vulnerability database. That is genuinely useful, and for a single WordPress site it is often enough to start. The trouble begins when you run more than WordPress, or when the question stops being "what versions are here" and becomes "which of these findings is actually exploitable on this specific install". A version match is a lead. It is not proof.
Darkmoon takes the second question seriously and spreads it across six dedicated agents. There is a wordpress agent, a drupal agent, a joomla agent, a magento agent, a prestashop agent and a moodle agent, each one a distinct specialist rather than a shared code path with a different banner check. This piece explains what that buys you over a signature scanner, and it is careful about what has been demonstrated versus what is designed to happen.
What WPScan does, and where it stops
WPScan is a fingerprint and lookup engine. It reads the readme, the meta generator tag, the enqueued script versions and the REST API, decides what is installed, and cross references the WPScan vulnerability database. Against the OWASP Top 10 it is squarely aimed at A06 Vulnerable and Outdated Components, and it does that one job well.
Three things sit outside that job. First, coverage is WordPress only, so a hosting provider or agency running a mix of Drupal, Joomla, Magento, PrestaShop and Moodle needs a different tool for each, with a different data source and a different notion of severity. Second, a database match tells you a vulnerable version is present, not that the vulnerable code path is reachable on this install, behind this WAF, with this plugin configuration. Third, it reports, it does not exploit, so the work of turning a candidate CVE into a confirmed, ranked finding still lands on a human. None of that makes WPScan wrong. It makes it a starting point rather than an answer.
Six CMS, six specialist agents
The reason to build one agent per platform is that a CMS is not a CMS. WordPress security lives and dies by its plugin and theme ecosystem. Drupal has its own access model and a history of highly impactful core issues. Joomla, Magento, PrestaShop and Moodle each have distinct architectures, default admin paths, extension mechanisms and privilege models. A single generic web agent would average across all of them and know none of them well. Six specialists let each one carry the exact enumeration logic, the default paths and the platform specific attack surface that matter for its target.
| Agent | Platform | Where the specialist knowledge lives |
|---|---|---|
| wordpress | WordPress | Plugins and themes, REST API, xmlrpc, user enumeration, admin surface |
| drupal | Drupal | Modules, access model, core version specific issues, admin paths |
| joomla | Joomla | Extensions, components, template surface, administrator login |
| magento | Magento | Admin panel, modules, storefront surface, payment and order flows |
| prestashop | PrestaShop | Modules, back office, front controllers, theme surface |
| moodle | Moodle | Plugins, roles and capabilities, enrolment and authentication surface |
These six agents are present and distinct in the repository today. What follows describes how they are built to work and the framework that governs what they are allowed to claim. Where a specific published case study exists we link to it, and where one does not yet exist we say so plainly.
From plugin and theme enumeration to a proven exploit
Enumeration is the same starting move a signature scanner makes: identify the core version, list the plugins, themes, modules or extensions, and note the ones with known issues. Darkmoon does this through the same offensive toolbox its other agents use, part of the 50+ tools shipped in the image, with httpx and ffuf for surface discovery, nuclei for templated CVE checks, and sqlmap when an injection lead appears. The difference is what happens next.
A version match becomes a hypothesis, and the agent then tries to demonstrate the impact rather than record the version and move on. Is the vulnerable endpoint reachable? Does the payload actually execute, or is it echoed back and served, not run? Did the request return data, or just a 200? That distinction between a lead and a demonstrated impact is not a stylistic preference, it is enforced by the status framework every agent carries.
Every finding is graded against a deliberately strict scale. UNCONFIRMED is a real lead where impact was not demonstrated, and it is capped at low severity with a CVSS ceiling of 3.9. CONFIRMED means the impact was shown with an exact request and payload, the raw response, and the extracted data or an execution trace. EXPLOITED means the impact was carried out end to end, with data extracted, an action completed or access gained. The agents adversarially challenge their own claims and demote the weak ones: a bare 200 on a route, a differential response, a payload that was reflected but never executed, or a file that was served rather than run. That is the same discipline we showed in the hardened site assessment, where the agent filed a 200 on /.env as informational once it read the body and found the application shell, not a secrets file.
Authentication, privilege escalation and file write chains
The findings that matter on a CMS are rarely a single misconfigured header. They are chains. A weak or default administrator credential leads to the theme or plugin editor, which leads to writing PHP, which leads to code execution on the host. An extension with an arbitrary file upload leads to a web shell. An access control gap lets a low privileged account reach an administrator only action, which leads to the same editor and the same file write. Mapping those chains, rather than listing their first link, is exactly the work a per platform specialist is built to do, because the default admin path, the editor location and the privilege model are different on every one of the six.
A necessary word on scope. Everything in this category is an offensive technique against a live application, and it must only ever run against systems you own or are explicitly authorized in writing to test. Credential testing, file write and privilege escalation are destructive by nature. Darkmoon is self hosted precisely so that you keep that authorization boundary under your own control, and the operations that reach further are credential gated and dispatched deliberately rather than triggered by a model guessing it should try harder.
Why one agent per CMS beats one generic scanner
A generic scanner optimizes for breadth: run everywhere, match signatures, produce a list. A specialist optimizes for a correct answer on one platform. The trade is real, and for CMS work the specialist wins for a simple reason. The false positive rate on a generic pass is what makes CMS scan output tiring to triage. A version is flagged, and someone has to open the site, check whether the plugin is even active, whether the endpoint is reachable, and whether the issue applies to this configuration. The specialist does that check as part of its run, and grades the result honestly, so the list you read is closer to the list you can act on.
This is the same architecture argument we make across the platform. An orchestrator reasons and plans, then dispatches specialist agents that execute real operations through a controlled tool layer built on the Model Context Protocol. For the CMS family that means the WordPress agent runs WordPress logic, the Magento agent runs Magento logic, and neither pretends to be a universal scanner that is good at everything. If you want the broader tooling landscape, we survey it in open source AI pentest tools for 2026.
Where the Privacy Gateway fits
Testing a client CMS usually means the hostnames, internal IPs and any credentials you supply are sensitive. Darkmoon runs on a local model and routes data through a Privacy Gateway that tokenizes those values before the model reasons over them. The model only ever sees deterministic placeholders such as HOST_INTERNAL_001 or EMAIL_001, never your real hosts, IPs or credentials. The real values are rehydrated locally, only at the moment a tool actually runs, and masked back out of every result.
We are precise about the limit of that claim, because it matters. Deterministic placeholders leak structure, cardinality and co occurrence by design, and the command gateway is a policy layer, not a sandbox. It is a strong reduction of what leaves your environment, not a guarantee that zero information reaches the model. The honest, full treatment is in how to run an AI pentest without sending your data to the LLM.
Proof of exploitation on a CMS, and what stays unconfirmed
The point of the status framework is that a report reads the same whether the target fell over or held. On a CMS with a stale plugin and a weak admin password, a run should reach EXPLOITED, with the exact request, the response and the artifact that proves impact. On a patched, hardened CMS with a strong admin credential and no reachable vulnerable code, the same run should return a short list of UNCONFIRMED leads and informational notes, and it should not manufacture a critical to look productive. A tool that finds a critical on every target is not thorough, it is unreliable.
What we do not claim
These six CMS agents are verified present and distinct in the repository, and the status framework above is enforced across every agent. We have not yet published a per platform benchmark or a full case study report for WordPress, Drupal, Joomla, Magento, PrestaShop or Moodle the way we have for the database, cloud and infrastructure runs. So this article does not put a findings count or a severity breakdown on any specific CMS target. When we run those campaigns end to end, the numbers we publish will be the graded ones, with the demotions left in, not the raw candidate list.
Remediation
- Keep core, plugins, themes, modules and extensions current, and remove the ones you do not use rather than leaving them installed and disabled. This is the A06 vulnerable components problem and it is the majority of real CMS risk.
- Enforce strong, unique administrator credentials with multi factor authentication, and change every default admin path and default account the platform ships with. Most exploit chains start at a weak or default login.
- Disable the in application code editors for themes and plugins in production, so an admin compromise does not become file write and code execution on the host.
- Lock down file upload and write paths, and ensure uploaded files cannot be executed as code. This closes the arbitrary file write to web shell chain.
- Review roles and capabilities against A05 Security Misconfiguration so that low privileged accounts cannot reach administrator only actions, and remove verbose error output that leaks paths and stack traces.
FAQ
Is this a WPScan replacement? Not in the sense of a drop in swap for one tool. WPScan is an excellent WordPress fingerprint and vulnerability lookup engine, and you can keep using it. Darkmoon covers six CMS platforms with dedicated agents and, more importantly, tries to demonstrate impact and grade it honestly rather than stopping at a version match. Think of it as the layer that turns leads into confirmed or exploited findings across more than WordPress.
Which CMS platforms are covered? Six today, each with its own agent: WordPress, Drupal, Joomla, Magento, PrestaShop and Moodle. They are separate specialists, not one scanner with six banner checks.
Does it test plugins and themes, not just core? Yes. Plugin, theme, module and extension surface is where most real CMS risk lives, so enumeration of that ecosystem is the starting point, followed by attempts to demonstrate whether a flagged component is actually exploitable on this install.
Can it exploit findings or only report them? It attempts real exploitation through a controlled tool layer, and it grades the result. UNCONFIRMED is a lead with no demonstrated impact, CONFIRMED carries the exact request, response and extracted data, and EXPLOITED means the impact was carried out end to end. It runs only against systems you own or are authorized to test.
How does it handle a hardened CMS with nothing to find? It returns a short, honest list rather than inventing a critical. A patched install with strong credentials and no reachable vulnerable code should produce UNCONFIRMED leads and informational notes, which is the same behavior we documented on our own hardened site.
What this proves about autonomous CMS testing
WPScan answers "what is installed" for WordPress. The harder, more valuable question is "what can actually be done here", across whatever mix of CMS platforms you run, with a report you can act on without re triaging every line. Six specialist agents plus a strict grading framework is our answer to that question, and we would rather publish the graded numbers when the campaigns are done than an inflated candidate list now.