Just months ago, Drupal, one of the most famous Content Management System (or CMS) along with WordPress and Joomla, sparked a lot of controversies surrounding its alleged vulnerability of how easy it is for threat actors to compromise its system. We’re referring to what happened last March, on which two vulnerabilities, (CVE-2018-7600) and (CVE-2018-7602), dealt devastating blows to Drupal’s security in just a span of a single month. Nowadays we just call them Drupalgeddon 2 and Drupalgeddon 3.
We’d like to keep our focus and uncover these said vulnerabilities which led to Drupalgeddon 2, despite Drupal not releasing an official walkthrough of how the issue came to be. For the investigation to kick in without empirical analysis from Drupal’s security team, researchers have to get creative by simulating a technical scenario closely similar to what actually happened.
In summary, Drupal’s vulnerability allowed even attackers without due authentication to perform remote code execution and subsequently compromise Drupal-installed sites through a set number of payloads. For this very reason that their security team rated the severity of Drupalgeddon 2 as 24/25 (Highly Critical.) This meant:
- The attacker only needed to visit a Drupal-installed site to leverage the vulnerability.
- There is no permission-level required to exploit these sites. Even anonymous users are capable of doing so.
- All private data in the backend will be accessible without permission.
- All system data can be compromised or modified by this said vulnerability.
- Exploit already existing in the wild. This meant the different method already rampant and shared across the internet.
- Over one million websites or about nine percent of all CMS-installed sites are affected by this vulnerability.
- A configuration change of the backend system might mitigate the issue, but it has to be an extreme one.
The said vulnerability permeated multiple sub-versions of Drupal 6.x, 7.x and 8.x, though Drupal 7.5.x seemed to be the most affected with over 50 percent infection rate from the whole roster.
- Technical Findings
Drupal backend poses an unsecured input security for its Form API (FAPI) AJAX callback function request. This becomes a vulnerability to be injected through form structure, causing Drupal to render a non-element value and execute an injection without proper authentication. Just by this knowledge that any attacker can take over a Drupal-installed site easily.
The earliest record of Drupal’s Form API can be investigated way back when Drupal 6 got introduced. This revolutionary process allows customization of form data even during its rendering process. This practice continued on even after the flagship migration to Drupal 7, which was responsible for giving its general name of “Renderable Arrays”. This Form API contain metadata, most of which represent set elements such as blocks, nodes, pages, etc., used in rendering functions. These Renderable Arrays usually start with a hash sign (#) such as the following:
‘#type’ => ‘markup’,
‘#markup’ => ‘<em>some text</em>’,
‘#prefix’ => ‘<div>’,
‘#suffix’ => ‘</div>’
Among the patch Drupal implemented includes the subclass RequestSanitizer which scans and secure data from $_GET, $_POST and $_COOKIES during the initial site bootup. This means more security against malicious applications for Renderable Arrays.
How researchers discover Drupal’s weaknesses
Since we can’t just penetrate its defenses through the mainstream hacking approach, due to the added security of Drupal’s patch, researchers then focused its attention at exploiting publicly available forms.
On this particular investigation, researchers have used Drupal’s registration form for anonymous visitors. This registration form contains multiple entry fields, which we can see in the following screenshot.
Figure 1.1: Drupal’s Past Registration Form
Looking at the above screenshot (which was Drupal’s registration form before their major update), researchers have found a way to inject a custom Renderable Array using the “Email Address” field. Take note that this field does not use RequestSanitizer for the input it receives. Consequently, this vulnerability became the gateway to penetrating Drupal’s defense. And just like that it’s possible to see the customized injection researchers have injected by inspecting its source page elements.
Now that the injection is there without Drupal detecting, next thing we do is to successfully render it. To fool Drupal into rendering our custom array, we’ll first need Drupal to treat the custom array as an element, not a value. This can be done by leveraging the Form API (FAPI) AJAX callback function.
Remember the “Picture” field from Drupal’s registration form? Turns out it uses GET parameter that is being used to locate a part of the form (to be precise, upload the picture in the server and send back its thumbnail for us to see.) With this functionality, we can modify the GET parameter, instead of pointing to the “Picture” field, to actually point to the customized Renderable Array that we have created inside the “Email Address” field. By doing this, Drupal will even render the bad attribute that was created.
Now that we’re at this point, we can finally inject the malicious array code in the system. For this occasion, the #lazy_builder seems like the most effective command we can inject inside the compromised “Email Address” array.
In conclusion, a fully rendered malicious array is capable of taking control of Drupal’s Admin Account, secretly installing a backdoor module and executing questionable commands upon any compromised servers.
Hidden crypto web miners like Coinhive injections or private Monero pools are still the most common indicators for a compromised Drupal-installed site.
Moreover, Fake Browser Update Requests are upon the rise, which steal a victim’s password credentials via Remote Administration Tool (RAT).
Tech Support Scams from redirected Browser Locker Pages (Browlock) using .TK domains are also prevalent. Some of these are:
Patching/Updating Drupal’s version normally will fix the issue. However, for websites that were already compromised, a simple update does not root out the issue. Unknown from the victims, malicious attackers may have already installed backdoors inside their database, source code, directory files, etc. To make things worse, these attackers might have already reached as far as your Host, or cloud provider, and have guaranteed control of the victim’s site.
Removing backdoors is an extremely difficult, if not impossible, maintenance task. This comes from the fact that we are not sure how many backdoors were installed in secret.
For this case, restoring from the last-known safe backup usually fixes the compromising issue. Rebuilding the site from scratch is also a safe alternative, albeit rather wearisome.
Other Preventive Solutions
Compromised websites will always be there for threat actors to take advantage of. And because patching is such a pain, Drupalgeddon became a widespread issue for those organizations not wanting to upgrade their Drupal backend. For one thing, system upgrade sounds nice, but it usually entails misaligned UIs, ugly templates and broken functionalities. In theory, organizations will have to recalibrate their websites to accommodate a newer Drupal baseline, which has a considerable upgrade and maintaining costs.
Some other early measures to improve site’s security include:
- Implementing 2 Factor Authentication to improve logins.
- Drupal’s Security Review Tool for discovering weak backend configurations.
- Drupal’s Paranoia Module which offers a variety of options for added account security.