Bugtraq mailing list archives

vBulletin allows arbitrary code execution


From: Jouko Pynnonen <jouko () SOLUTIONS FI>
Date: Thu, 15 Mar 2001 14:27:19 +0200

OVERVIEW
========

vBulletin (http://www.vbulletin.com) 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 an 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.




DETAILS
=======

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.
(for simplicity not %-escaped)

http://www.site.url/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 wouldn't be 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 I found some of the commercial versions also
have an eval() problem with URL redirecting, e.g.

http://www.site.url/member.php?action=login&username=myuser&password=mypass&url=hello"world

and a similar one in the Lite version:

http://www.site.url/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
and hasn't replied my query concerning it, so here is a quick fix
(I haven't programmed in PHP so anyone more PHP-literate, feel free to
correct):

  $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);




CREDITS AND ACKNOWLEDGEMENTS
============================

The vulnerabilities were found by Jouko Pynnönen. Thanks to
Mike Sullivan of Jelsoft Enterprises Ltd.




--
Jouko Pynnonen          Online Solutions Ltd       Secure your Linux -
jouko () solutions fi                                 http://www.secmod.com


Current thread: