[GWCTF 2019]枯燥的抽奖
知识点:伪随机数构造
文章目录
解题过程
打开题目,是个这,让我们去搞一个20位的字符串,已经给了一部分字符串
同时发现了check.php,注意这个php函数中含有mt_rand函数,这牵扯到一个安全问题。贴一下大牛的链接:PHP mt_rand安全杂谈及应用场景详解
Hg11vtADEm
<?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");
1. 伪随机数(引用上面的链接内容)
伪随机数是用确定性的算法计算出来的随机数序列,它并不真正的随机,但具有类似于随机数的统计特征,如均匀性、独立性等。在计算伪随机数时,若使用的初值(种子)不变,那么伪随机数的数序也不变。伪随机数可以用计算机大量生成,在模拟研究中为了提高模拟效率,一般采用伪随机数代替真正的随机数。模拟中使用的一般是循环周期极长并能通过随机数检验的伪随机数,以保证计算结果的随机性。伪随机数的生成方法有线性同余法、单向散列函数法、密码法等。
mt_rand就是一个伪随机数生成函数,它由可确定的函数,通过一个种子
产生的伪随机数。这意味着:如果知道了种子,或者已经产生的随机数,都可能获得接下来随机数序列的信息(可预测性)。
所以:大致过程就明了了,我们根据已经给出的部分随机数,利用工具找出seed(种子),然后得到完整的随机数。
2. 将已知的部分伪随机数转化为php_mt_seed工具可以看懂的数据
str1 ='Hg11vtADEm'
str2 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
result =''
length = str(len(str2)-1)
for i in range(0,len(str1)):
for j in range(0,len(str2)):
if str1[i] == str2[j]:
result += str(j) + ' ' +str(j) + ' ' + '0' + ' ' + length + ' '
break
print(result)
结果:
43 43 0 61 6 6 0 61 27 27 0 61 27 27 0 61 21 21 0 61 19 19 0 61 36 36 0 61 39 39 0 61 40 40 0 61 12 12 0 61
3. 下载php_mt_seed工具并且使用
下载链接:php_mt_seed - PHP mt_rand() seed cracker
下载后,放入linux环境,并且运行
得到种子348806110
,同时要注意php版本是php7.1以上
的。
4. 得到完整字符串
执行代码的环境要是php7.1以上的,我当时就踩了一下这个坑。
<?php
mt_srand(348806110);
$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环境是php7.0.33,执行的结果是
肯定是错的,前10个字符和环境给的就不一样
然后在php7.4环境下运行,结果是对的。
将完整的字符串提交,就可得到flag.