首页 » 网站推广 » php5627问题技巧_e107 CMS 小于等于212 权限提升马脚分析

php5627问题技巧_e107 CMS 小于等于212 权限提升马脚分析

访客 2024-12-19 0

扫一扫用手机浏览

文章目录 [+]

翻译:西风微雨

预估稿费:100RMB(不服你也来投稿啊!

php5627问题技巧_e107 CMS 小于等于212 权限提升马脚分析

投稿办法:发送邮件至linwei#360.cn,或上岸网页版在线投稿

php5627问题技巧_e107 CMS 小于等于212 权限提升马脚分析
(图片来自网络侵删)

0x00 漏洞背景

e107 CMS是一个基于PHP、Bootstrap、Mysql的网站内容管理系统,可广泛用于个人博客、企业建站,在环球范围内利用较为广泛。

0x01 漏洞影响版本

version <=2.1.2

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行的代码

123353 $new_data = base64_decode($_POST['updated_data']); ...387 $changedUserData = unserialize($new_data);

353行中用户可控变量$_POST['updated_data']未经进一步处理就直接在387行中进行了反序列化,并将数据赋值给$changedUserData变量,以便进一步操作.

连续跟进$changedUserData变量

123455 $changedData['data'] = $changedUserData; ...460 if (FALSE === $sql->update('user', $changedData))

$changedUserData变量在460行进入mysql类方法,跟进/e107_handlers/mysql_class.php中的update函数

12341160 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函数

1234567891083 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函数

1234561247 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语句检讨:

123358 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

123456/ 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 在修正邮箱时会验证密码,我们只修正校验了密码之后的数据包,如下图:)

成功反序列化:

查看数据库字段,创造test2用户的user_admin字段已经被成功修正为1,权限提升成功

test2用户成功进入后台管理面板:

0x04 漏洞修复

升级e107 CMS至2.1.3版本

0x05 漏洞总结

此漏洞的修复过程也有些许奇妙,Kacper Szurek安全研究员早在2016年6月就在2.1.1版本创造了此漏洞,官方多次修复均被饶过,并且在2.1.2版本中仍未修复,或许官方暂未找到更好的修复方法,此漏洞便一度被搁置;直到2016年11月RIPS再次报告漏洞,官方终于在2.1.3版本的修复中完备重写了usersettings.php文件,以修复包括此漏洞在内的多个漏洞。
其余,此篇文章在我的个人博客中也有备份:https://lightrains.org/e107-cms-privilege-escalation/。

0x06 参考链接

https://blog.ripstech.com/2016/e107-sql-injection-through-object-injection/

http://security.szurek.pl/e107-cms-211-privilege-escalation.html

https://github.com/e107inc/e107/commit/6a306323d4a14045d9ee4fe80f0153a9555fadff#diff-dbac6e5a7c66d48e23884c0968e6dad7

https://github.com/e107inc/e107/commit/0af67301ea2743536ba8f3fe74751e000e3f495d#diff-dbac6e5a7c66d48e23884c0968e6dad7

https://github.com/e107inc/e107/commit/dd2cebbb3ccc6b9212d64ce0ec4acd23e14c527

相关文章

php常量率低技巧_PHP 常量详解教程

PHP 常量常量是单个值的标识符(名称)。在脚本中无法改变该值。有效的常量名以字符或下划线开头(常量名称前面没有 $ 符号)。注释...

网站推广 2024-12-19 阅读0 评论0