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

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

缺陷编号:wooyun-2014-060197

漏洞标题:FineCMS任意用户密码重置

相关厂商:dayrui.com

漏洞作者: xfkxfk

提交时间:2014-05-11 15:42

修复时间:2014-08-09 15:44

公开时间:2014-08-09 15:44

漏洞类型:设计缺陷/逻辑错误

危害等级:高

自评Rank:15

漏洞状态:厂商已经确认

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2014-05-11: 细节已通知厂商并且等待厂商处理中
2014-05-11: 厂商已经确认,细节仅向厂商公开
2014-05-14: 细节向第三方安全合作伙伴开放
2014-07-05: 细节向核心白帽子及相关领域专家公开
2014-07-15: 细节向普通白帽子公开
2014-07-25: 细节向实习白帽子公开
2014-08-09: 细节向公众公开

简要描述:

FineCMS任意用户密码重置

详细说明:

finecms最新版2.3.0,官方2014年4月18号更新。
finecms在密码找回功能处存在设计缺陷,导致可重置任意用户密码。
来看看密码找回的代码:

/**
* 找回密码
*/
public function find() {

$step = max(1, (int)$this->input->get('step'));
$error = '';

if (IS_POST) {
switch ($step) {
case 1:
if ($uid = get_cookie('find')) {
$this->member_msg(
lang('m-093'),
dr_member_url('login/find', array('step' => 2, 'uid' => $uid)),
1
);
} else {
$name = $this->input->post('name', TRUE);
$name = in_array($name, array('email', 'phone')) ? $name : 'email';
$value = $this->input->post('value', TRUE);
$data = $this->db
->select('uid,username,randcode')
->where($name, $value)
->limit(1)
->get('member')
->row_array();
if ($data) {
$randcode = rand(1000, 9999);
if ($name == 'email') {
$this->load->helper('email');
if (!$this->sendmail($value, lang('m-014'), dr_lang('m-187', $data['username'], $randcode, $this->input->ip_address()))) {
$this->member_msg(lang('m-189'));
}
set_cookie('find', $data['uid'], 300);
$this->db
->where('uid', $data['uid'])
->update('member', array('randcode' => $randcode));
$this->member_msg(lang('m-093'), dr_member_url('login/find', array('step' => 2, 'uid' => $data['uid'])), 1);
} else {
$result = $this->member_model->sendsms($value, dr_lang('m-088', $randcode));
if ($result['status']) { // 发送成功
set_cookie('find', $data['uid'], 300);
$this->db
->where('uid', (int)$data['uid'])
->update('member', array('randcode' => $randcode));
$this->member_msg(lang('m-093'), dr_member_url('login/find', array('step' => 2, 'uid' => $data['uid'])), 1);
} else { // 发送失败
$this->member_msg($result['msg']);
}
}
} else {
$error = $name == 'phone' ? lang('m-182') : lang('m-185');
}
}
break;
case 2:
$uid = (int)$this->input->get('uid');
$code = (int)$this->input->post('code');
$data = $this->db
->where('uid', $uid)
->where('randcode', $code)
->select('salt,uid,username,email')
->limit(1)
->get('member')
->row_array();
if (!$data) {
$this->member_msg(lang('m-000'));
}

$password1 = $this->input->post('password1');
$password2 = $this->input->post('password2');
if ($password1 != $password2) {
$error = lang('m-019');
} elseif (!$password1) {
$error = lang('m-018');
} else {
// 修改密码
$this->db
->where('uid', $data['uid'])
->update('member', array(
'randcode' => 0,
'password' => md5(md5($password1).$data['salt'].md5($password1))
));
if ($this->get_cache('MEMBER', 'setting', 'ucenter')) {
uc_user_edit($data['username'], '', $password1, '', 1);
}
$this->member_msg(lang('m-052'), dr_url('login/index'), 1);
}
break;
}
}

$this->template->assign(array(
'step' => $step,
'error' => $error,
'action' => 'find',
'mobile' => $this->get_cache('member', 'setting','ismobile'),
'meta_name' => lang('m-014'),
'result_error' => $error,
));
$this->template->display('find.html');
}


可以看到:
首先通过email,发送4为数字的验证码到email的邮箱。
然后跳转到重置密码的链接。
输入验证码和新密码就可重置密码了。
这里的uid已经返回在重置密码的链接里面了。
所以我们只需要用户注册的email地址,然后重置此用户名的密码。
然后爆破4位数字就可,一共的可能只有9000种可能,而且这里没有次数限制,爆破这样的数字太easy了。

漏洞证明:

第一步重置密码,发送验证码到邮箱:

111.png


第二步填写验证码和新密码,抓包:

222.png


第三步遍历爆破验证码即可:

333.png


此时已经成功重置了该用户的密码。

修复方案:

1、增加验证码的爆破难度
2、添加验证测次数限制

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


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:20

确认时间:2014-05-11 17:32

厂商回复:

增加验证码,验证失败认证码重置

最新状态:

暂无