搜索
首页后端开发php教程PHP 使用 rand() 函数生成令牌安全吗?

Web 应用经常需要创建一个难以被猜解的令牌,例如,会话令牌、CSRF 令牌或者在忘记密码功能中用于邮件重置密码使用的令牌。这些令牌本应该被进行加密保护,但实际中却经常被使用多次调用 rand函数并转换输出为字符串来表示。本文将展示预测使用 rand产生的令牌其实并不那么困难。

rand 是如何工作的

在 PHP 中,函数 rand 用于产生伪随机数,而初始化随机数的种子是由 srand 产生的。如果用户不选择调用 srand,那么 PHP 会将一个非常难以猜测的数字作为随机数生成器的种子。由 srand产生的种子将完全决定了 rand函数生成的随机数。

随机数生成器会保持由 srand初始化过后的状态,并在每次调用 rand后改变。这个状态与进程状态相关,所以两个进程通常不会返回相同的 rand随机数。

示例程序

我们使用的实例程序为 EZChatter,一个用于生成 CSRF 令牌的小程序,但在创建时没有很好的考虑安全性:

public static function gen($len = 5){    $token = '';    while($len--){        $choose = rand(0, 2);        if ($choose === 0)            $token .= chr(rand(ord('A'), ord('Z')));        else if($choose === 1)            $token .= chr(rand(ord('a'), ord('z')));        else            $token .= chr(rand(ord('0'), ord('9')));    }    return $token;}

如你所见,上述代码首先调用 rand来决定是使用大写字母、小写字母还是数字,然后在选择一个特定的字母或数字。每当我们请求 index.php 时都会产生一个新的 CSRF 令牌,所以我们可以随意的发出请求以产生我们需要的令牌。我们的目标是预测分配给用户的令牌,这样我们就可以进行 CSRF 攻击了。

猜解种子

正如前文所说,随机数序列完全由种子所决定的,所以我们可以简单的尝试每一个可能的数字作为 srand的参数来猜测到正确的随机数生成器状态。但请注意,这在 Linux 上只有服务器进程是新创建的才能奏效,如果服务器已经产生了很多 rand调用,那么我们就需要在破解程序中重复同样次数的调用以获取到相同的状态。而在 Windows 上,随机数生成器的状态只与 srand的参数有关,所以就不需要进行一个重复的过程了。

如果想从一个新创建的进程中获取到一个令牌,那么可以使用下列的 PHP 脚本来进行破解:

for ($i = 0; $i < PHP_INT_MAX; $i++) {    srand($i);    if (Token::gen(10) == "2118Jx9w3e") {        die("Found: $i \n");    }}

为了搜索 srand总计 4294967295 个可能的参数值,大概要花费12小时。然而,由于 PHP 仅仅只是调用了 glibc 的 rand函数,我们可以重新转换 PHP 代码为 C 来加快运行速度。这里给出两个版本的代码,一个调用的是 glibc rand,另一个模仿的是 Windows rand。它是基于 token.php中的 PHP 代码,使用 PHP 中的宏 ext/standard/rand.c来循环尝试找出可能的种子。在 Windows 上大约只需要十来分钟,Linux 上大约需要几个小时。

一旦攻击完成,就拥有了跟服务器处在相同状态下的随机数生成器,从而可以同服务器产生相同的令牌。通过将自己生成的令牌与服务器返回的令牌进行比对,就可以知道哪些令牌已经被分配给了用户,进而可以开始攻击。

Linux 上的状态攻击

在 Windows 上,猜解 srand参数和随机数生成器的状态是一回事,但在 Linux 上则不同。glibc 的 rand()保持一系列的数字,并决定下一个状态像下面这样:

state[i] = state[i-3] + state[i-31]return state[i] >> 1

所以每一个输出近似是之前 3 和 31 的结果之和。考虑如下令牌:

  • 6ZF5kNgonV
  • 9h3byovpGR
  • gGt0A94U92

现在,该决定下一个随机数是否为大写字母、小写字母还是数字。这将由之前第 3 和 31 次的结果决定, gGt0A94U92中的 9 和 9h3byovpGR中的 y。所以,我们预计下一个 rand(0, 2)输出会近似于⌊10/10 + 25/26 × 3⌋ = 2 mod 3,这意味着我们将得到一个数字。下面假设我们可以预测到这个数字,则下一次调用 rand得到的数字将由之前第 3 次调用 rand得到的数字和之前第 31 次调用的 rand得到小写字母决定。这个数字将介于 ⌊2/3 + 1/3 × 10⌋ = 0 mod 10 和  ⌊3/3 + 2/3 × 10⌋ = 6 mod 10 之间。因此我们预计值将介于 0 到6,最终结果为 4:

  • 43J2d2ew31

如你所见,我们没法通过这种方法精确的预测下一个随机数,但也很清楚,我们可以预测到大致的范围,你已经不可以称其为随机数了。另外也可以使用同样的方式猜解 glibc的随机数生成器的状态,尽管这里没有在进行尝试。

总结

应当使用安全加密的随机数生成器。如果使用 rand产生随机数,很多情况下是可以对其随机数生成器进行猜解的,这样令牌将变得可以被预测。在 Linux 上预测令牌会相对困难一些,但这仍然并不安全。Windows 上的随机数生成器相对更容易被利用,因为其随机数生成器状态可以在数分钟内被猜解出来。

*原文: sjoerdlangkemper.nl,FB小编xiaix编译,转自须注明来自FreeBuf黑客与极客(FreeBuf.COM)

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
超越炒作:评估当今PHP的角色超越炒作:评估当今PHP的角色Apr 12, 2025 am 12:17 AM

PHP在现代编程中仍然是一个强大且广泛使用的工具,尤其在web开发领域。1)PHP易用且与数据库集成无缝,是许多开发者的首选。2)它支持动态内容生成和面向对象编程,适合快速创建和维护网站。3)PHP的性能可以通过缓存和优化数据库查询来提升,其广泛的社区和丰富生态系统使其在当今技术栈中仍具重要地位。

PHP中的弱参考是什么?什么时候有用?PHP中的弱参考是什么?什么时候有用?Apr 12, 2025 am 12:13 AM

在PHP中,弱引用是通过WeakReference类实现的,不会阻止垃圾回收器回收对象。弱引用适用于缓存系统和事件监听器等场景,需注意其不能保证对象存活,且垃圾回收可能延迟。

解释PHP中的__ Invoke Magic方法。解释PHP中的__ Invoke Magic方法。Apr 12, 2025 am 12:07 AM

\_\_invoke方法允许对象像函数一样被调用。1.定义\_\_invoke方法使对象可被调用。2.使用$obj(...)语法时,PHP会执行\_\_invoke方法。3.适用于日志记录和计算器等场景,提高代码灵活性和可读性。

解释PHP 8.1中的纤维以进行并发。解释PHP 8.1中的纤维以进行并发。Apr 12, 2025 am 12:05 AM

Fibers在PHP8.1中引入,提升了并发处理能力。1)Fibers是一种轻量级的并发模型,类似于协程。2)它们允许开发者手动控制任务的执行流,适合处理I/O密集型任务。3)使用Fibers可以编写更高效、响应性更强的代码。

PHP社区:资源,支持和发展PHP社区:资源,支持和发展Apr 12, 2025 am 12:04 AM

PHP社区提供了丰富的资源和支持,帮助开发者成长。1)资源包括官方文档、教程、博客和开源项目如Laravel和Symfony。2)支持可以通过StackOverflow、Reddit和Slack频道获得。3)开发动态可以通过关注RFC了解。4)融入社区可以通过积极参与、贡献代码和学习分享来实现。

PHP与Python:了解差异PHP与Python:了解差异Apr 11, 2025 am 12:15 AM

PHP和Python各有优势,选择应基于项目需求。1.PHP适合web开发,语法简单,执行效率高。2.Python适用于数据科学和机器学习,语法简洁,库丰富。

php:死亡还是简单地适应?php:死亡还是简单地适应?Apr 11, 2025 am 12:13 AM

PHP不是在消亡,而是在不断适应和进化。1)PHP从1994年起经历多次版本迭代,适应新技术趋势。2)目前广泛应用于电子商务、内容管理系统等领域。3)PHP8引入JIT编译器等功能,提升性能和现代化。4)使用OPcache和遵循PSR-12标准可优化性能和代码质量。

PHP的未来:改编和创新PHP的未来:改编和创新Apr 11, 2025 am 12:01 AM

PHP的未来将通过适应新技术趋势和引入创新特性来实现:1)适应云计算、容器化和微服务架构,支持Docker和Kubernetes;2)引入JIT编译器和枚举类型,提升性能和数据处理效率;3)持续优化性能和推广最佳实践。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
4 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器