- php_mt_seed种子爆破
- mt_srand()伪随机数
进去看到朱一旦
查看源码发现妖腻有check.php
访问得到源码
<?php
#这不是抽奖程序的源代码!不许看!
header("Content-Type: text/html;charset=utf-8");
session_start();
if(!isset($_SESSION['seed'])){
$_SESSION['seed']=rand(0,999999999);
}
mt_srand($_SESSION['seed']);
$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$str='';
$len1=20;
for ( $i = 0; $i < $len1; $i++ ){
$str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1);
}
$str_show = substr($str, 0, 10);
echo "<p id='p1'>".$str_show."</p>";
if(isset($_POST['num'])){
if($_POST['num']===$str){
echo "<p id=flag>抽奖,就是那么枯燥且无味,给你flag{xxxxxxxxx}</p>";
}
else{
echo "<p id=flag>没抽中哦,再试试吧</p>";
}
}
show_source("check.php");
mt_srand()伪随机数
mt_srand() 函数播种 Mersenne Twister 随机数生成器。
**提示:**从 PHP 4.2.0 开始,随机数生成器自动播种,因此没有必要使用该函数。
mt_rand()
mt_rand() 函数使用 Mersenne Twister 算法生成随机整数。
**提示:**该函数是产生随机值的更好选择,返回结果的速度是 rand() 函数的 4 倍。
**提示:**如果您想要一个介于 10 和 100 之间(包括 10 和 100)的随机整数,请使用 mt_rand (10,100)。
mt_rand返回的是使用mt_srand种子生成的随机数,这个随机数是可以预测的
mt_srand('123');
echo mt_rand(),PHP_EOL;
echo mt_rand(),PHP_EOL;
//不管运行多少次,其输出值和顺序都是一样的
1495656191
1531059894
mt_srand('123');
echo mt_rand(0,12),PHP_EOL;
echo mt_rand(0,12),PHP_EOL;
//即使有范围也一样
6
1
所以只要知道种子就可以得到完整的随机数序列
审计
看题目是使用
if(!isset($_SESSION['seed'])){
$_SESSION['seed']=rand(0,999999999);
}
mt_srand($_SESSION['seed']);
来进行播种
而且这个种子值是不会变的
所以我们只要知道这个种子是多少就行
这里使用php_mt_seed
来进行爆破种子
https://www.openwall.com/php_mt_seed/README
https://www.openwall.com/php_mt_seed/
题目给了前10位:PT00unN1RX
所以先用下面的脚本来获取前10次mt_rand()返回的值
<?php
$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$str = 'PT00unN1RX';
$length=strlen($str_long1)-1;
for($i=0;$i<strlen($str);$i++){
for($j=0;$j<$length;$j++){
if($str[$i]==$str_long1[$j]){
echo $j.' '.$j.' 0 '.$length;
echo ' ';
break;
}
}
}
//得到
//51 51 0 61 55 55 0 61 26 26 0 61 26 26 0 61 20 20 0 61 13 13 0 61 49 49 0 61 27 27 0 61 53 53 0 61 59 59 0 61
这里使用51 51 0 61 的格式,是php_mt_seed要求的
51 51是获得的伪随机数 0 61 是指随机数的范围,即mt_rand(0,61)
然后给php_mt_seed传参,得到种子:218716996
然后用这个种子来执行源码里的脚本获取字符串,输入字符串,得到flag
<?php
mt_srand('218716996');
$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$str='';
$len1=20;
for ( $i = 0; $i < $len1; $i++ ){
$str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1);
}
$str_show = substr($str, 0, 10);
echo $str;
//PT00unN1RXVPNQqs5XpR