欢迎光临
我们一直在努力

CTFshow Web25:深入解析php_mt_seed工具在伪随机数爆破中的实战应用

1. 从“爆个锤子”到“伪随机数”的认知升级

做CTF题目最怕什么?不是题目难,而是思路一开始就错了。我刚开始做CTFshow Web25这道题时,就犯了个低级错误——看到代码里有个md5($flag),然后截取前8位转十进制作为种子,我下意识以为种子就是ctfshow{
这八个字符的MD5值。结果折腾了半天,发现完全不对路。

后来仔细看代码才明白,人家是先对整个flag进行MD5加密,然后取前8位十六进制,再转换成十进制作为种子。这个区别可大了去了,就像你以为密码是“123456”,结果人家用的是“123456”的SHA256值,完全是两码事。

这道题的核心逻辑其实挺有意思的。代码里有个关键判断:if((!$rand)),意思是只有当$rand为0时,才会执行后面的token验证逻辑。而$rand的计算方式是intval($r)-intval(mt_rand())。所以最简单的思路就是让$r等于mt_rand()的值,这样两者相减就是0。

但问题来了,我们不知道mt_rand()会生成什么值啊。这时候有个小技巧:我们可以先传?r=0,这样$rand就等于-mt_rand(),服务器会把这个负的随机数回显给我们。比如我测试时得到了-646081337,那么mt_rand()就是646081337。

你以为这就完了?更麻烦的还在后面。代码里验证token的逻辑是:$_COOKIE[\’token\’]==(mt_rand()+mt_rand())。注意这里的mt_rand()+mt_rand()可不是同一个随机数加两次,而是连续调用两次mt_rand()得到两个不同的值再相加。

我刚开始也犯糊涂,以为token就是2*mt_rand(),写了个小测试就发现不对:

<?php
mt_srand(123456);
$rand1 = mt_rand();
$rand2 = mt_rand();
echo $rand1,\”\\n\”,$rand2;
?>

同样的种子,第一次和第二次生成的随机数完全不同。所以我们需要的是第二次和第三次mt_rand()的和,因为第一次已经被我们用?r=0的方式“消耗”掉了。

2. php_mt_seed:伪随机数的“时光倒流”机器

知道了随机数值,怎么反推种子呢?理论上可以写脚本爆破,但32位的种子空间有40多亿种可能,纯暴力破解太慢了。这时候就该php_mt_seed这个神器出场了。

我在实际

赞(0)
未经允许不得转载:171主机测评 » CTFshow Web25:深入解析php_mt_seed工具在伪随机数爆破中的实战应用
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址