By kxlzx https://www.inbreak.net/
摘要:
这是一个随机函数破解的经典例子。在java程序中,获取随机数的做法有多种。但是我们实现一个随机token,并用于认证时,通常第一时间,想起来使用“System.currentTimeMillis”,本文会详细讲解一次破解随机数的经过。
正文:
“System.currentTimeMillis”这个方法,返回从UTC 1970年1月1日午夜开始经过的毫秒数。执行结果,可能是类似“1315395175327”这样的数字,因为后面的几位,是毫秒,所以执行结果就好像“随机”一样。
今天遇到的一个系统,相关业务逻辑场景,是用于找回密码。首先要求用户输入自己的邮箱,系统算出来一个token,发给用户邮箱,让用户使用token,执行修改密码的这一步。
1、输入邮箱。
2、发送邮件给用户邮箱。
3、根据邮箱中的链接,修改密码
就是说,只要能破解了服务器给用户生成的token,就可以直接修改用户密码。
在生成token时,采用了这样一段代码:
|
从代码上可以看到,Email的hashcode,在用户的email固定的情况下,是不变的,那么这个不变的数字,即使乘以21,依然是不变的。只要知道了用户的email,就可以知道这个数字。
真正随机的只有System.currentTimeMillis()
这个方法貌似随机,条件允许的情况下,其实是可以破解的。
利用系统时间可预测破解java随机数:
根据以上流程,只要攻击者提交
|
就可以给攻击者的邮箱,发一封EMAIL。
================
你好,空虚浪子心:
请点击链接重置密码。该链接24小时内有效。
或将以下链接拷贝到浏览器地址栏中:
|
该邮件由系统自动发送,请勿直接回复此邮件。
==============
随后的那个token,就是随机生成的数字。同理,输入另一个用户(被攻击者)的邮箱,也可以发送一封email。如果服务器上的时间,和攻击者机器上执行的时间一致,在不考虑网络传输成本的前提下,是可以直接得到token的。
当然,这不可能。
但是好在我们的时间速度,和服务器的时间速度,基本一致。注意,