Noname's Blog
信息安全专业的小萌新,立志走上更大的舞台
php伪随机数

php伪随机数

好久不学习了。。打开一个题目边学边记录一下
0.png
注:之前重启了一次,所以题目和下面题解的随机字符串不一样(也就是因为懒了
题目给了一个简短的字符串,但是一共有二十位,所以后面有一部分需要自己爆出来
爆源码的多种姿势后。。
1.png

源码显示随机生成了一个字符串,所以要通过伪随机数的预测来破解
相关函数:

mt_rand( void) : int
mt_rand( int $min, int $max) : int

缺陷:生成的随机数跟seed和调用该函数的次数有关,也就是只要种子是一样的,任何人拿该种子去生成的随机数都是可预测的,顾名思义伪随机数
所以解决方法就是要找到该种子

mt_srand([ int $seed] ) : void

用 seed 来给随机数发生器设置种子。 没有设定 seed 参数时,会被设为随时数(一般可以根据本地时间,来使得rand一类函数得到的数字达到随机的效果)。使用者在进行一次mt_srand()操作后,seed数值将被固定下来,给接下来的mt_rand()函数使用。

参考一篇解析原理的文章
https://www.freebuf.com/column/205240.html

使用工具:

http://www.openwall.com/php_mt_seed/

这里如果版本对应不正确是安排不了的,很奇怪
将压缩包拉到linux下

tar -zxvf php_mt_seed-4.0.tar.gz
cd到目录下后
make

这里顺便学习一下make命令
http://www.ruanyifeng.com/blog/2015/02/make.html

根据README,我们要将数据处理成便于种子爆破的格式,所以要根据源码写脚本进行数据处理,即获取"样本随机数"

https://github.com/lepiaf/php_mt_seed
根据源码的思路逆向
脚本:

str1 = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
str2 = 'Z7M56fQQBN'
res = ''
for i in range(len(str2)):
	for j in range(len(str1)):
		if(str2[i] == str1[j]):
			res += str(j)+' '+str(j)+' '+'0'+' '+str(len(str1)-1)+' '
			break
print(res)

得到一串数据
进到目录里丢到php_mt_seed中

./php_mt_seed ....

可以得到种子和php版本
QQ截图20200320143552.png

<?php
mt_srand(474122877);
$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$str='';
$len1=20;
for ( $i = 0; $i < $len1; $i++ ){
    $str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1);       
}
echo "<p id='p1'>".$str."</p>";

最后这里同样是要注意php的版本,只好即可得flag

书鱼师傅的文章思路很清晰~
https://st4ck.gitee.io/2019/12/03/wei-sui-ji-shu/