Exploits in the Wild for vBulletin Pre-Auth RCE Vulnerability CVE-2019-16759

By , and

Category: Unit 42

Tags: , ,

This post is also available in: 日本語 (Japanese)

Executive Summary

A new zero-day vulnerability was recently disclosed for vBulletin, a proprietary Internet forum software and the assigned CVE number is CVE-2019-16759. Now, several weeks later, Unit 42 researchers have identified active exploitation of this vulnerability in the wild. By exploiting this vulnerability, an unauthenticated attacker can gain privileged access and control over any vBulletin server running versions 5.0.0 up to 5.5.4, and potentially lock organizations out from their own sites. More than 100,000 sites are built on vBulletin, including the forums of major enterprises and organizations, so it’s imperative to patch immediately.

In this blog post we provide new details on the root cause of the vulnerability, proof of concept code (PoC) to demonstrate the vulnerability, and information on attacks we have observed in the wild.

Root Cause Analysis of the Vulnerability

This is a pre-auth remote code execution vulnerability with a 9.8 CVSS v3.1 base score. This is caused by a PHP server-side template injection by the Ajax render function which was introduced on the vBulletin version 5.0.0.

This code starts in index.php.

Figure 1. Entry Point of the vulnerability (index.php)

The code calls vB5_Frontend_ApplicationLight::isQuickRoute() to check whether the request is a “quick route.” The method isQuickRoute() is in includes/vb5/frontend/applicationlight.php:

Figure 2. isQuickRoute function (includes/vb5/frontend/applicationlight.php)

As shown in Figure 2, the function will return true if there is a ‘ajax/api’ or ‘ajax/render’ at the beginning of the request. Then the vB5_Frontend_ApplicationLight object will be initiated and executed according to Figure 1.

Figure 3. Ajax render handler (includes/vb5/frontend/applicationlight.php)

Figure 3 shows the handler will be set to ‘callRender’ when the request is start with ‘ajax/render.’

Figure 4. callRender() renders the template (includes/vb5/frontend/applicationlight.php)

Figure 4 shows the callRender() function will render the template using the name coming from the $routeInfo[2] and $params coming from array_merge($_POST, $GET).

Figure 5. widget_php template (core/install/vbulletin-style.xml)

Figure 5 shows there is a ‘widget_php’ template in the vbulletin-style.xml file. According to the template, when $widgetConfig['code'] is not empty and $vboptions['disable_php_rendering']is disabled, the following code will be executed:

Figure 6. evalCode() function (includes/vb5/frontend/controller/bbcode.php)

Figure 6 shows the evalCode function, the text in $code will be executed directly by the PHP eval() function.

If we can construct a request with the params:

Proof of Concept

Based on the analysis, we can construct the exploit code to prove the functionality. Since the parameter “routestring” is from $_REQUEST, it can be sent through $_GET, $_POST or $_COOKIE HTTP methods. “widgetConfig[code]” can be sent through $_GET, $_POST. As such, our simple POC can be constructed as the following and sent as either a GET or POST request:




Figure 7. Vulnerability demonstrated through a GET request

Figure 7 shows that phpinfo() runs when the PoC is sent through a GET request.

Figure 8. PoC through POST request

Figure 8 shows phpinfo() runs when the PoC is sent through POST request.

Exploits in the Wild

We have detected multiple attempts to exploit this vulnerability in the wild through Palo Alto Networks Next-Generation Firewall. Below we’ve summarized three of these attempts.

In the first example (Figure 9) the attacker attempts to execute die(@md5(HellovBulletin)) to determine whether a server is vulnerable or not but due to an additional “=” sign included in their request, the exploitation fails.

Figure 9. POST request for the failed exploit attempt

Figure 10 shows the attacker try to create a “webconfig.txt.php” in the web root directory.

Figure 10. POST request for exploit modifying webconfig.txt.php

Figure 11 shows the content of “webconfig.txt.php” and it’s a one-line PHP webshell which would allow the attacker to send any command they live to the script and have it executed by the host.

Figure 11. Content after base64 decode

Figure 12 shows the third example, where the attackers try to overwrite the file bbcode.php.

Figure 12. Attacker tries to overwrite the bbcode.php

If successful, the evalCode() will turn into the following code:

By doing this, the compromised site can only execute code in the evalCode() function when the “epass” is sent through request with the value “2dmfrb28nu3c6s9j”. This would prevent other attackers from taking control of the compromised site and allow a botnet command-and-control (C2) server to exclusively exploit this vulnerability and issue commands to the targeted server.


There are multiple exploits already in the wild for this new vBulletin vulnerability. vBulletin is a very popular software package used by many high-profile organizations (See the vBulletin website for examples) and this makes it prized target.

To resolve this vulnerability, web administrator should update the vBulletin to version 5.5.2/3/4 Patch Level 1 or disable PHP, Static HTML, and Ad Module rendering setting in the administration panel.

Palo Alto Networks customers are protected from those two vulnerabilities by the following products and services:

  • Threat Prevention Signature 56632 and 56627.
  • URL Filtering marks the following IP addresses as suspicious, as these have been actively attempting to exploit this vulnerability.

Palo Alto Networks has shared our findings, including file samples and indicators of compromise, in this report with our fellow Cyber Threat Alliance members. CTA members use this intelligence to rapidly deploy protections to their customers and to systematically disrupt malicious cyber actors. For more information on the Cyber Threat Alliance, visit www.cyberthreatalliance.org.