Drupalgeddon2 – Yet Another Weapon for the Attacker
Here at the Application and Threat Intelligence (ATI) Research Center, our team analyzes active security threats caught in the wild by our honeypots to determine some of the attack vectors employed by malicious actors. The result of such research is usually a strike, which is a set of directives that the BreakingPoint security test solution uses for the generation of traffic that mimics the behavior of a specific threat. In effect, customers can use the BreakingPoint strikes to test the security of their infrastructure.
One threat that caught our attention is CVE-2018-7600, a highly-critical vulnerability within the Drupal open-source content management system that could allow attackers to gain complete control of a target website. Infamously known as Drupalgeddon2, nicknamed after its predecessor, this vulnerability makes over 1 million websites vulnerable to remote code execution, as suggested by Buildwith.
The vulnerability was disclosed on the 28th of March, by the Drupal security team and affects Drupal versions 7.x up to 7.58, versions 8.x up to 8.3.9, versions 8.4.x up to 8.4.6, and versions 8.5.x up to 8.5.1. The vulnerability is due to insufficient user-supplied input sanitization. The entry point of the attacker is usually the ManagedFile.php, a form used for uploading and saving files. A malicious user would pass parameters such as #post_render or #access_callback to the uploading form. These are directives that affect the outcome of the rendering process and are used to construct a Form API AJAX response containing the rendered requested resource.
Taking a closer look at the provided sample code, we can observe the complete lack of sanitization within the callback AJAX method, allowing the attacker to pass within the form field actual rendering parameters that the doRender() method uses afterwards, which is where the actual code execution is obtained.
Code snippet from Drupal version 8.5.0. Comments are added for clarity.
The patch submitted by Drupal’s team was published on the 21st of March and consists of a single class named RequestSanitizer that checks all the input arrays for rendering attributes, which are Drupal Form API properties that can be identified by the prefixed hash character.
The proposed method sanitizes the input data within the HTTP client requests during the Drupal bootstrap, immediately after loading the site configurations, not before it is processed by the callback functions that determine the outcome of the rendering process. While this can hamper the attacker’s ability to rapidly find an entry point candidate for the exploitation, it might also result in not filtering all the entry points for this specific vulnerability, which could give an attacker the means of still exploiting the vulnerability, even with the patch on. This was indeed the case, with the follow-up Drupalgeddon 3 vulnerability, an attack that works in a similar manner, bypassing this patch by encoding properties and passing them in specific form fields.
The security patch for Drupalgeddon2.
The public PoC exploit published on April 12th is written in Ruby and consists of several steps, as follows. Certain parts were removed for brevity.
• Determine if the remote webserver has a vulnerable version of Drupal by requesting and parsing files such as CHANGELOG.txt or includes/database.inc
• Testing if remote code execution can be achieved by sending an echo command and parsing the server response:
Snippet from Drupalgeddon2 public PoC: testing RCE.
• Building the payload, which accesses the callback functions from the doRender() method, via #post_render parameter:
Snippet from Drupalgeddon2 public PoC: generating malicious payload.
• Finally, uploading the webshell and gaining remote code execution via a HTTP POST request by passing the command to a POST parameter.
One thing to note is the fact that remote code execution can be achieved via multiple parameters. Such parameters are: #post_render, #pre_render, #access_callback, or #lazy_builder. All of these parameters, when parsed by the doRender() method, will give access to callback functions that the attacker can use to achieve remote code execution.
Activity in the Wild
Drupalgeddon2 and Drupalgeddon3 – related activity.
Over 7,000 attacks targeting Drupal versions 7.x and 8.x have been caught by our honeypots since April 14th, two days after the public PoC had been released. Most of the requests leverage code execution to identify vulnerable targets for later use, while others attempt to upload cryptominers on the target machines. We can see a spike in the activity starting on the 1st of May, the date when the public PoC for Drupalgeddon3 was released.
Sample #1. Script-Shell.Trojan.Coinminer (sha-256 bd2d11a1ea38e14ade0bfb0d3851b632e0b644cfde5f49e608d51e9cfd74f4f2)
This sample was detected by one of our honeypots on the 16th of April. After using the Drupalgeddon2 exploit, the attacker attempts to download and execute the resource (mrx1), as highlighted below. The analysis of the sample was conducted using Remnux V.6 .
Sample#1: Malicious request that employs Drupalgeddon2 exploit as attack vector.
Looking at the resource, we can see that we are dealing with a shell script that attempts to:
• Terminate other miner processes if any exist on the infected machine - an effective way of killing off the competition:
Sample#1: There can be only one cryptominer here.
• Install the miner’s dependencies and ensuring persistence using automated cron jobs:
Sample#1: Miner dependencies.
• Ensure attacker access by creating a backdoor authorized SSH key, then download the miner:
Sample#1: SSH backdoor.
• If all dependencies are met, start the mining process and download another library if required for correct functioning:
Sample#1: Initiate mining process.
A closer look at the last command reveals that what seems to be the miner client is launched into execution with the file downloaded to /tmp/migrations, connecting at the mining pool pool.zer0day.ru:8080. Then, the script attempts to launch the resource downloaded in /tmp/clay, if it is not running already. What is the purpose of /tmp/clay? Before looking at it, let’s inspect the miner client.
Sample#1: Inspecting the binary file: UPX-packed file
It seems that we are dealing with a 64-bit ELF binary executable file, packed with the UPX packer. Let’s unpack it and further inspect it.
Sample#1: Unpacking the binary.
Sample#1: Inspecting the unpacked file: Monero coinminer.
Looking at the strings within the unpacked file, we can observe that we are dealing with a Monero coinminer. Finally, let’s take a look at the /tmp/clay file.
Sample#1: Inspecting the second binary: ELF-executable.
We are dealing with a statically-linked, non-stripped binary executable file. Let’s inspect the strings.
Sample#1: Inspecting the second binary: static analysis.
This is most likely a backdoor written in C++ that seems to also support different types of DDoS attacks, which is probably instructed by a C2C server to synchronize with other infected nodes. All the IP’s found are reported to be from China. VirusTotal confirms the file maliciousness:
Sample#1: VirusTotal scanning result
Sample #2. PHP/Agent.IA!tr (sha-256: 2eac91b2f85a0a54dcf67d8fa08e9d3a83c5385779e26b4db79c01be69450e57)
This sample was detected by one of our honeypots on the 3rd of June. After using the Drupalgeddon2 exploit, the attacker attempts to download the file mimetypes.php from an attacker-controlled server, as highlighted below. The analysis of the sample was conducted using Remnux V.6.
Sample #2: Malicious request that employ Drupalgeddon2 exploit as attack vector.
Looking at the resource, we can see that we are dealing with an obfuscated PHP script:
Sample #2: Obfuscated PHP script.
We can observe that the long string seems to be base64-encoded, and so we suspect the name of the function that is called using the string as parameter is the PHP base64_decode. Let’s see if this is the case. After renaming the variables and decode the string, we obtain:
Sample #2: Less - obfuscated PHP script.
Let’s see the hidden variables:
As we can observe, var2 is indeed the PHP base64_decode method. From the other variable names, we can conclude that, after a pipeline of string operations on var5 and var6, the result is a valid base64 encode string, which is executed with PHP eval method. After the replacement of the variable names, we obtain the final script:
Sample #2: De-obfuscated PHP script.
In effect, we are dealing with a PHP file uploader script that the attacker can ultimately use to gain access to the target machine.
The Ixia ATI Research Center continuously monitors threats as they appear in the wild. Customers of our BreakingPoint product have access to strikes for CVE-2018-7600 and its sibling CVE-2018-7602, starting with ATI Strikepack version 332852. Our monitoring of in-the-wild attackers ensures that such attacks are also blocked for customers of Ixia ThreatARMOR.