Critical vBulletin Vulnerability Exposes Forums to Remote Code Execution

A significant security flaw has been identified in vBulletin, a widely used forum software, potentially compromising thousands of online communities. This vulnerability allows unauthenticated attackers to execute arbitrary code remotely, leading to full system control.

Understanding the Vulnerability

The issue affects vBulletin versions 5.x and 6.x operating on PHP 8.1 or later. It stems from vBulletin’s use of PHP’s Reflection API within its custom Model-View-Controller (MVC) framework and API system. This architecture employs dynamic routing, mapping API endpoints to controller methods based on incoming HTTP requests. For instance, an AJAX call to `/ajax/api/user/fetchProfileInfo` is routed to the `vB_Api_User::fetchProfileInfo()` method.

The crux of the vulnerability lies in how vBulletin utilizes the `ReflectionMethod::invoke()` and `ReflectionMethod::invokeArgs()` functions. With the advent of PHP 8.1, these functions can invoke protected and private methods without the need for `setAccessible(true)`, a departure from previous PHP versions. This change means that methods intended for internal use can now be accessed directly by remote users if the application doesn’t enforce visibility checks.

A simplified example of the vulnerable code pattern is as follows:

“`php
$controller = new $controllerName();
$method = new ReflectionMethod($controller, $methodName);
$method->invokeArgs($controller, $params);
“`

In this scenario, a request to `/api.php?method=protectedMethod` would invoke the protected method directly on PHP 8.1+, bypassing intended access controls.

Exploitation Path

The ability to invoke protected methods is inherently dangerous. The real threat emerges when such methods can be exploited for code execution. In vBulletin, the `vB_Api_Ad::replaceAdTemplate()` method is a protected function designed to insert or update advertisement templates. Attackers have discovered that by invoking this method through a crafted HTTP POST request, they can inject arbitrary template code into the system.

The vBulletin template engine supports conditional logic using `` tags. Due to a separate flaw in how the template parser filters input, attackers can bypass restrictions and inject PHP code using variable function calls. For example:

“`php

{$_POST[‘cmd’]()}

“`

This template, once injected, allows the attacker to execute system commands sent via POST requests, effectively granting a webshell on the server.

A proof-of-concept exploit demonstrates how an attacker can gain shell access, run arbitrary commands, and fully compromise the underlying system, all without authentication. This exploit chain has been confirmed to work on vBulletin versions 5.1.0, 5.7.5, 6.0.1, and 6.0.3 running on PHP 8.1+. The vulnerability is believed to be patched in version 6.0.4.

Implications and Recommendations

This vulnerability serves as a stark reminder for developers: relying on method visibility (public, protected, private) as a security boundary is fundamentally unsafe, especially when using dynamic dispatch and reflection. The introduction of new behaviors in PHP 8.1, where `ReflectionMethod` can invoke protected and private methods by default, necessitates explicit enforcement of access control at the application level.

The vBulletin RCE vulnerability underscores the importance of explicit access control and the dangers of relying on language-level visibility for security in dynamic web frameworks.