WooYun-2014-67410:Hdwiki设计缺陷知邮箱可改密码(包括管理员)
漏洞作者: ′雨。
来源:http://www.wooyun.org/bugs/wooyun-2014-067410
简要描述
上Hdwiki官网 发现更新日期一直都没变。 还以为一直都没更新了, 结果今天下载一个下来看看。 发现之前发的洞竟然都补掉了。 看了看之前这个改密码那个 对比了一下。 发现增强了点验证。 加入了一个算法。
不过。。。。。。
——————————————————————————————————
ps. 更新程序了应该还是把日期更新了一下 要不别人会一直以为没更新的。
详细说明
http://**.**.**.**/bugs/wooyun-2014-055786
上次的 现在来看看现在的。
依旧是control/user.php
}else{
$timetemp=date("Y-m-d H:i:s",$this->time);
$auth = util::strcode($timetemp, 'ENCODE');
$verification= rand(1000,9999);
$encryptstring=md5($this->time.$verification.$auth);
$reseturl=WIKI_URL."/index.php?user-getpass-".$user['uid'].'-'.$encryptstring;
$_ENV['user']->update_getpass($user['uid'],$encryptstring);
$mail_subject = $this->setting['site_name'].$this->view->lang['getPass'];
$mail_message = $this->view->lang['resetPassMs1'].$user['username'].$this->view->lang['resetPassMs2'].$timetemp.$this->view->lang['resetPassMs3']."<a href='".$reseturl."' target='_blank'>".$reseturl."</a>".$this->view->lang['resetPassMs4'].$this->setting['site_name'].$this->view->lang['resetPassMs5'].$this->setting['site_name'].$this->view->lang['resetPassMs6'];
$this->load('mail');
$_ENV['mail']->add(array(), array($email), $mail_subject, $mail_message, '', 1, 0);
$this->message($this->view->lang['emailSucess'],'index.php?user-login',0);
}
}
$encryptstring=md5($this->time.$verification.$auth);
现在所验证的 对比之前的可以发现多了一个$auth 来看看怎么来的。
$timetemp=date("Y-m-d H:i:s",$this->time);
$auth = util::strcode($timetemp, 'ENCODE');
这里获取了一下时间 然后
function strcode($string,$action='ENCODE'){
$key = substr(md5($_SERVER["HTTP_USER_AGENT"].PP_KEY),8,18);
$string = $action == 'ENCODE' ? $string : base64_decode($string);
$len = strlen($key);
$code = '';
for($i=0; $i < strlen($string); $i++){
$k = $i % $len;
$code .= $string[$i] ^ $key[$k];
}
$code = $action == 'DECODE' ? $code : base64_encode($code);
return $code;
}
主要关注他的key怎么来的。
$key = substr(md5($_SERVER["HTTP_USER_AGENT"].PP_KEY),8,18);
首先对USER_AGENT.PP_KEY MD5一次 然后再来取。
等等。。 user agent 是用户可控的, PP_KEY呢?
竟然没有初始化, 那么PP_KEY就是PP_KEY 那么这个$key 全部就可控了。
所以我们可以想对什么加密就对神马加密了。
$timetemp=date("Y-m-d H:i:s",$this->time);
$auth = util::strcode($timetemp, 'ENCODE');
然后这个是对时间加密一次 如果知道时间的话就能知道$auth
然后继续$this->time.$verification.$auth
第一个就是时间戳 第二个rand(1000,9999) 有8999种可能 直接枚举 第三个 知道时间就可以了。
漏洞证明
这里由于管理员和用户在同一个表所以可以直接改管理员的密码。
首先 http://**.**.**.**/web/hdwiki/index.php?user-getpass
然后把要管理员的邮箱输入进去。
在点提交之前打开 (提交的时候一定要改一下user agent 如果不改user agent 会对应不上的 我这里改成的是asd)
http://**.**.**.**/Tools/unixtime.aspx
然后在点提交的时候 看一下时间戳 并记录下来。
(我本地时间有点不准 无伤大雅)
以我演示的为例, 时间戳为 1405589070
然后把这个时间戳转换为时间
1405589070 -> 2014/7/17 17:24:30 (时间不准 别在意哈哈)
$timetemp=date("Y-m-d H:i:s",$this->time)
Y-m-d H:i:s 这个的格式是这样的 年份-月份-日子 小时:分钟:秒
所以把2014/7/17 17:24:30对应下来为2014-7-17 17:24:30
但是这样是不对的 因为 Y-m-d H:i:s获取的是 格林威治标准时间
与北京时间正好相差8个小时 所以$timetemp=2014-07-17 09:24:30
然后带入那个算法当中
然后这样就拿到了$auth
然后写个脚本 把8999种情况 全部遍历出来
1405589070$iBlMHBUkAVkwHBxYICw8BVw0BBA==
把8999种情况全部导出来 然后载入burpsuite
前面那uid那里就是管理员的id 肯定是为1的。
修复方案
增强验证
增强算法
随机生成一个Key咋样。