mt_rand()伪随机数伪造
来自
[GWCTF 2019]枯燥的抽奖
打开网页是个猜flag的东西,显然不可能真去猜,重新加载一下网页f12看到了个check.php的请求,我们访问得到源码:
看看代码逻辑:
1.生成种子
2.设置生成的字符
3.生成长度为20的随机字符
其中$str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1); 的意思就是截取$str_long1的某个字符
这里用了rand和mt_rand,看似这个随机数没办法找,但是果真如此吗?
可以注意到,我们猜测字符串是采用伪随机函数依据种子生成的,所以我们当然可以利用脚本通过给出的部分字符串逆推出伪随机函数采用的种子。
先写个php把这串字符串梭成需要的数据格式:
<?php //生成解密序列 $pass_now = "1SkXefogcb"; $allowable_characters = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; $len = strlen($allowable_characters) - 1; for($j = 0; $j < strlen($pass_now); $j++) { for ($i = 0; $i < $len; $i++) { if($pass_now[$j] == $allowable_characters[$i]) { echo "$i $i 0 61 "; break; } } }
然后用一个php_mt_seed的工具:
得到种子:248292462
生成字符串脚本:
<?php //生成伪造字符串 function user_password($length = 20) { $allowable_characters = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; $len = strlen($allowable_characters) - 1; $pass = ''; for ($i = 0; $i < $length; $i++) { $pass .= $allowable_characters[mt_rand(0, $len)]; } return $pass; } mt_srand(248292462); echo user_password(), "\n";
然后一搜就有了: