# [GWCTF 2019] 枯燥的抽奖
# 知识点:伪随机数:mt_rand () 函数
伪随机数(引用上面的链接内容)
伪随机数是用确定性的算法计算出来的随机数序列,它并不真正的随机,但具有类似于随机数的统计特征,如均匀性、独立性等。在计算伪随机数时,若使用的初值(种子)不变,那么伪随机数的数序也不变。伪随机数可以用计算机大量生成,在模拟研究中为了提高模拟效率,一般采用伪随机数代替真正的随机数。模拟中使用的一般是循环周期极长并能通过随机数检验的伪随机数,以保证计算结果的随机性。伪随机数的生成方法有线性同余法、单向散列函数法、密码法等。
mt_rand 就是一个伪随机数生成函数,它由可确定的函数,通过一个种子产生的伪随机数。这意味着:如果知道了种子,或者已经产生的随机数,都可能获得接下来随机数序列的信息(可预测性)。
进来是这样的界面,发现是要写一些字符串,要写出剩下的字符串,源码有 check.php, 进去发现是源码
5qfWJ4LPJv
<?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){x
echo "<p id=flag>抽奖,就是那么枯燥且无味,给你flag{xxxxxxxxx}</p>";
}
else{
echo "<p id=flag>没抽中哦,再试试吧</p>";
}
}
show_source("check.php");
发现 mt_rand 函数,直接 php_mt_seed 启动!!!(不不不,还没,先把要字符串改成 php_mt_rand 看得懂的东西再说)
str1='abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
str2='8D2SWQCXgH'
length = len(str2)
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:
make
./php_mt_seed 这串数字
获得 seed 后通过脚本:
<?php | |
mt_srand(你的种子,如880310233); | |
$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 $str; | |
?> |
直接写入后获得 flag
(工具真难下)