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了。
第一步重置密码,发送验证码到邮箱:
第二步填写验证码和新密码,抓包:
第三步遍历爆破验证码即可:
此时已经成功重置了该用户的密码。
1、增加验证码的爆破难度2、添加验证测次数限制
危害等级:高
漏洞Rank:20
确认时间:2014-05-11 17:32
增加验证码,验证失败认证码重置
暂无