Yet another Drupal scanner – Drupwn

DISCLAIMER: Article originally published on immunIT.

Hi fellas,

Today, I will introduce you a new tool, developed for the sake of my penetration testing activities, named Drupwn which claims to provide a reliable and efficient way to perform enumerations on Drupal web applications.

You may think, why yet another tool whereas there exist plenty of alternatives on the market.
Well, the answer is straightforward, they are unreliable. Indeed, none of them is actively maintained and are sorely lacking of features. This is to fill this particular gap that Drupwn is born.

Drupwn is a python script, following a modular architecture for maintenance and enhancement purposes, which allows enumerating various kind of information that could be valuable to any security assessment against such platform.


Before diving into the main subject, let’s take a look on its architecture.


As you can see on the picture above, the engine and plugins parts are completely independent, allowing to easily add modules without having the modify the tool core engine.

Each plugin inherits from the abstract class APlugin, providing a better overall structure alongside the whole code base. Upstream the design concern, this inheritance provide a multi threading support by design, deporting this brainteaser, which is parallelization, to the core engine.

Each plugin is designed as following :

class Example(APlugin):
    """This class is an example.

    def __init__(self, request, logger, config):
        """This is the class constructor, allowing to set the number of threads as well as the logger configuration.
        self.logger = logger
        self.request = request

    def run(self):
        """This method is the plugin entrypoint. This is where the magic happen.

Once the plugin created and added to the plugins folder, we must refer it within the dispatcher and the parser in order to ensure its support by the reflective factory.

Quite easy right ? Thanks to this design pattern, anyone is able, within a few minutes, to add new functionalities to improve the Drupwn’s behaviors!


To fit to as much as possible of situations, Drupwn supports:

  • Basic authentication
  • Cookie manipulation
  • User-Agent modification
  • Logging
  • Request sending speed
  • Enumeration range customization

Upstream those passive functionalities, this python3 script actually provides 6 modules, described below.

User enumeration

As its name suggests, this module is used to enumerate the registered users on the platform assessed.
In fact, depending on the Drupal version, an unauthenticated user could be able to enumerates the existing users through the /user/{ID} resource.

Cause, code is more explicit than words, here is a piece of pseudo code, explaining the module inner working.

for id between 0 and 3000
    request the resource /user/id
    if a redirection occurred
        get the username within the returned URL
    else if success
        get the username within the source code returned
    else if forbidden
        the username is not retrievable

Node enumeration

When publishing an article, the CMS create a node, associated with a slug. Lambda users use the slug name to access a given article. However, it is quite tedious to enumerate all the website’s pages using combinations of alphanumeric chars. Of course, spidering can be a good way to accomplish this job but, it is noisy as hell and a better solution exist.

Indeed, by iterating on the resource /node/{ID}, we can retrieve the associated slugs and map the whole website content. This can help to find unlinked pages which can results by sensitive information gathering.

Default files enumeration

Well, this module just check if the default installation files are present on the web server, allowing to improve the server side hardening, reducing the attack surface.

Theme enumeration

Theme enumeration can seem useless however, some free themes available online can be backdoored, which is an easy win situation. This enumeration simply use a wordlist and print out the name of the installed themes.

Module enumeration

This module is very similar to the previous one nevertheless, we are commonly face to hardened installation, avoiding any kind of module enumeration.
Modules are, in 99 % of the time, the failure point of a Drupal application. This is why, finding a workaround is inescapable to ensure the assessment reliability.

Here is how this plugin works:

for each module in the wordlist
    check if the status code is not equal to 404
    if 200
        check the information in the and extract its version as well as its default files
    else if 403
        retrieve its default files


Fingerprinting a Drupal application can be quite difficult. Indeed, none of the CMS default files allows to efficiently determinate the version deployed. To remedy this situation, Drupwn uses several locations to accomplish this task.

while we have no result
    check landing page
    check HTTP header


Drupwn works out of the box thanks to its dockerization.

# Build the container
docker build -t drupwn .

# Run the docker
docker run --rm -it drupwn --help

If docker seems unfriendly to you. Drupwn can be used directly on any system using pip3 and python3. To do so, follow the guidelines below:

# Install dependencies
pip3 -r install requirements.txt

# Run Drupwn
python3 --help






I believe this tool provides good capabilities of enumeration that can definitely help any pentester conduct, with efficiency and reliability, his security assessment.

As any open source project, pull requests are widely welcome! Here is a short list of wanting features that will be implemented later:

  • TOR network support
  • Proxy support
  • Vulnerability detection

Hope you enjoyed this article,


Hm… Ok so… sorry for my lack of understanding, but… I read somewhere that even though that a webpage or whatever you’re trying to test… if it returns a status code of lets say 200, couldn’t it still be unreliable?

Well, in theory, yes … However, this is not how Drupal or its associated hardening plugins works.

Moreover, web applications follow the HTTP RFC consequently, protected contents often return a 403 status code, 404 for unexisting one and so on. It is the respect of this norm which allows us to perform enumeration attacks :slight_smile:

I hope it answered your question.



Dude this is awesome. I have yet to pentest a Drupal instance, but these kinds of engagements pop up all the time.

I’ve actually been wanting to make a scanner for Magento. I found it’s possible to discover plugins via the CSS and class names inside div elements on the page. We should work together on something soon (when I find a minute :grin:).

Anyway, good work! Looks really cool. I think I might have a good use for this :wink:


You are welcome :stuck_out_tongue:
I’m up for it, you know how to reach me :wink:


[0.9.2] [2018-04-16]


  • Exploit mode allowing to check and exploit CVEs


  • Deleting the vulnerability checker plugin. Now, CVEs can be checked using the exploit mode
  • Adding colors within the logger engine
  • Improving the version fingerprinting engine

I didn’t see the link to it, but here is the git repo,

also, IoT seems to be taking a shine to adding drupal to their mix,

Thanks for this clarification. Btw, the link is present in the first paragraph, second line.


1 Like

I might look at the code after I’m done with my current project (top secret), but if it’s anything like nikto than I probably can figure out how it works… although, it’s written in python. Maybe I could try re-writing it in Perl for those that prefer Perl?

Just a thought.

–Techno Forg–

This topic was automatically closed after 30 days. New replies are no longer allowed.

Change Log

[1.0.3] [2019-02-28]


  • Support CVE-2019-6340


  • Requests wrapper to handle data and headers overwriting
  • Delete legacy CVE checker

[1.0.2] [2019-01-22]


  • README file update
  • Fixing name resolution and catching stack trace when fail

[1.0.1] [2018-11-21]


  • Fix prompt_toolkit package
  • Adding new module path, used by new Drupal version
  • Set 20 default threads for efficiency

[1.0.0] [2018-08-31]


  • SOCKS and HTTP proxy support


  • Misspelling
1 Like