Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

🏠 Back to Blog

Drupal — Discovery & Enumeration

Background

Drupal (launched 2001) is the third most popular CMS by market share (~2.4%), written in PHP with support for MySQL, PostgreSQL, or SQLite as the backend. It supports ~43,000 modules and ~2,900 themes.

Key stats:

  • ~1.5% of all websites (~1.1 million sites); 5% of the top 1 million sites; 7% of the top 10,000
  • Available in 100 languages; 1.3+ million community members
  • 56% of government websites worldwide use Drupal
  • 33 Fortune 500 companies use Drupal
  • Notable users: Tesla, Warner Bros Records

Discovery / Footprinting

Fingerprinting indicators

IndicatorLocation
<meta name="Generator" content="Drupal 8 ...">Page source
Powered by Drupal text/linkPage header or footer
/node/<id> URL structureAny content page
Standard Drupal logoSite header
/CHANGELOG.txt or /README.txtDirect access (may be blocked on newer installs)
References to /noderobots.txt

Page source grep

curl -s http://drupal.inlanefreight.local | grep Drupal
<meta name="Generator" content="Drupal 8 (https://www.drupal.org)" />
<span>Powered by <a href="https://www.drupal.org">Drupal</a></span>

Node-based fingerprinting

Drupal indexes all content as nodes at predictable URIs:

http://drupal.inlanefreight.local/node/1
http://drupal.inlanefreight.local/node/2

A node can represent a blog post, article, poll, or any other content type. The /node/<id> path structure is a reliable Drupal indicator even when a custom theme hides other signs.

User types

RoleDefault capabilities
AdministratorComplete control over the site
Authenticated UserLogin + role-based operations (add/edit articles, etc.)
AnonymousRead-only access to public posts

Enumeration

Version via CHANGELOG.txt (older installs)

curl -s http://drupal-acc.inlanefreight.local/CHANGELOG.txt | grep -m2 ""
Drupal 7.57, 2018-02-21

Newer Drupal installs (8.x+) block access to CHANGELOG.txt by default — a 404 response does not rule out Drupal, it just means this technique is unavailable.

Other files that may disclose the version when CHANGELOG.txt is blocked:

PathContents
/README.txtGeneric Drupal intro, sometimes includes version
/core/CHANGELOG.txtDrupal 8+ changelog location
/core/includes/bootstrap.incVERSION constant (if readable)
/modules/php/LICENSE.txtPresence confirms PHP module installed

droopescan

droopescan has significantly more Drupal functionality than it does for Joomla.

droopescan scan drupal -u http://drupal.inlanefreight.local

Example output:

[+] Plugins found:
    php http://drupal.inlanefreight.local/modules/php/
        http://drupal.inlanefreight.local/modules/php/LICENSE.txt

[+] No themes found.

[+] Possible version(s):
    8.9.0
    8.9.1

[+] Possible interesting urls found:
    Default admin - http://drupal.inlanefreight.local/user/login

droopescan surfaces:

  • Installed modules/plugins (from LICENSE.txt and other files under /modules/)
  • A version range based on file hashes
  • The admin login URL

Admin login

The default Drupal login portal is at:

http://<target>/user/login

Unlike WordPress (which uses /wp-login.php) and Joomla (/administrator/index.php), Drupal uses the /user/login path. The login page behavior for incorrect credentials should be noted — does it distinguish between bad username and bad password (username enumeration oracle) or return a generic message?


Enumeration checklist

  • Confirm Drupal via <meta name="Generator"> tag, footer text, or robots.txt
  • Check /node/1, /node/2 to confirm node-based URL structure
  • Attempt /CHANGELOG.txt for version (expect 404 on newer installs)
  • Attempt /core/CHANGELOG.txt (Drupal 8+)
  • Run droopescan scan drupal -u TARGET for version range, modules, and interesting URLs
  • Note admin login at /user/login
  • Record installed modules — cross-reference with CVE databases
  • Check whether the PHP module is installed (/modules/php/) — if so, it may enable code execution