COMMAND

    vBulletin

SYSTEMS AFFECTED

    vBulletin

PROBLEM

    Jouko Pynnonen found following.  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 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.

    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 we 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 query concerning it, 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);