[GWCTF 2019] 枯燥的抽奖

发布于 2021-08-06  64 次阅读


知识点

mt_rand:每一次调用mt_rand()函数的时候,都会检查一下系统有没有播种。(播种是由mt_srand()函数完成的),当随机种子生成后,后面生成的随机数都会根据这个随机种子生成。所以前面也说到,同一个种子下随机生成的随机数值是相同的。因此,这是一个伪随机数,只要知道随机种子的值,就能破解.

爆破工具:https://github.com/lepiaf/php_mt_seed

伪随机数文章:https://www.freebuf.com/vuls/192012.html

解题

image-20210110171648147

猜字符串都游戏,看到输入框,尝试SQL注入和XSS

image-20210110171808812
image-20210110171841807

查看源码:

image-20210110172059562

前端传参处,存在一处url,尝试访问

image-20210110172302172

得到抽奖程序的源码,真不错,分析一下源码

<?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");

通过阅读源码可发现,通过随机数,生成一个长度为20的密码,输入密码就可以获取flag.

首先将得到的前十个密码解析成php_mt_seed需要的参数Exp如下:

<?php
$pass_now = "FpCyLNvPOj";
$allowable_characters = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';

$length = strlen($allowable_characters) - 1;

for ($j = 0; $j < strlen($pass_now); $j++) {
for ($i = 0; $i < $length; $i++) {
if ($pass_now[$j] == $allowable_characters[$i]) {
echo "$i $i 0 $length ";
break;
}
}
}
?>
image-20210110183201547
image-20210110184125595

利用工具爆破得到种子,根据种子构造解密字符串的Exp:

image-20210110184328827
image-20210110184343976