‘vBulletin Vulnerability Allows Remote Code Execution’

Summary

vBulletin is a commonly used web forum system written in PHP. One of its key features is use of templates, which allow the board administrator to dynamically modify the look of the board.

vBulletin templates are parsed with the eval() function. This could be somewhat safe as long as the parameters to eval() are under strict control. Unfortunately, this is where vBulletin fails. With a URL crafted in a certain way, a remote user may control the eval() parameters and inject arbitrary PHP code to be executed.

A remote user may thus execute any PHP code and programs as the web server user, typically ‘nobody’, start an interactive shell and try to elevate their privilege. The configuration files are accessible for the web server so the user can in any case access the MySQL database containing the forums and user information.

According to the authors, the vulnerability exist in all versions of vBulletin up to 1.1.5 and 2.0 beta 2. The bug does not involve buffer overrun or other platform-dependant issues, so it’s presumably exploitable under any OS or platform.’

Credit:

‘The vulnerabilities were found by Jouko Pynnonen. ‘


Details

Vulnerable systems:
All versions of vBulletin up to 1.1.5 and 2.0 beta 2.

Immune systems:
vBulletin versions 1.1.6 and 2.0 beta 3

vBulletin templates are implemented in the following way: the gettemplate() function in global.php is used to fetch a template from database. The code is then passed to eval(). If we take index.php for an example, there’s this code:

  if ($action==’faq’) {
    eval(‘echo dovars(”.gettemplate(‘faq’).”);’);
  }

The dovars() function does some variable replacing, such as replace
<largefont> with <font size=’10’>.

The gettemplate() function is defined in global.php:

  function gettemplate($templatename,$escape=1) {
    // gets a template from the db or from the local cache
    global $templatecache,$DB_site;

    if ($templatecache[$templatename]!=”) {
      $template=$templatecache[$templatename];
    } else {
      $gettemp=$DB_site->query_first(‘SELECT template FROM template WHERE title=”. addslashes($templatename).”’);
      $template=$gettemp[template];
      $templatecache[$templatename]=$template;
    }

    if ($escape==1) {
      $template=str_replace(”’,’\”,$template);
    }
    return $template;
  }

For effectiveness, the function implements a simple cache for template strings. After fetching them from the database they’re stored in the templatecache[] array. This array is checked for the template before doing the SQL query. Unfortunately, the array is never initialized, so a user can pass array contents in the URL, e.g.
(Not %-escaped for simplicity)

http://www.example.com/index.php?action=faq&templatecache[faq]=hello+world

With this URL, you won’t get the FAQ page, but just a blank page with the words ‘hello world’.

The eval() call above will execute

  echo dovars(‘hello world’);

As if this isn’t bad enough, a remote user may as well pass a value containing quotation marks and other symbols. Quotation marks aren’t always escaped as seen in the code above, in which case index.php could end up executing code like:

  echo dovars(‘hello’world’);

This would produce a PHP error message due to unbalanced quotes. It doesn’t take a rocket scientist to figure out how a remote user could execute arbitrary code from here, so further details about exploitation aren’t necessary. If your vBulletin board produces an error message with an URL like the one above prefixed with a single quotation mark, it’s definitely vulnerable.

The above example works with the ‘Lite’ version. The commercial versions are vulnerable too, but details may differ. After a little experimenting on the Jelsoft’s test site it seems some of the commercial versions also have an eval() problem with URL redirecting, e.g.

http://www.example.com/member.php?action=login&username=myuser&password=mypass&url=hello’world

and a similar one in the Lite version:

http://www.example.com/search.php?action=simplesearch&query=searchthis&templatecache[standardredirect]=hello’world

Solution:

The vendor (Jelsoft Enterprises Ltd) was contacted March 2nd, and has released fixed commercial versions 1.1.6 and 2.0 beta 3.

The vendor hasn’t fixed the free ‘Lite’ version of the software so far, so here is a quick fix:

  $templatecache=array();

Add that line to the beginning of global.php after the ‘<?php’ line. It will initialize the template cache and override any values a remote user may have tried to pass in the URL.

Fix for the redirect problem: replace global.php line 99

  $url=$redirectloc;

with this line:

  $url=addslashes($redirectloc);’

Categories: News