[GWCTF 2019]枯燥的抽奖

 

查看源代码,发现了个check.PHP

$(document).ready(function(){
    $("#div1").load("check.PHP #p1");

        $(".close").click(function(){
                $("#myAlert").hide();
    });         

    $("#button1").click(function(){
        $("#myAlert").hide();
        guess=$("input").val();
        $.ajax({
       type: "POST",
       url: "check.PHP",
       data: "num="+guess,
           success: function(msg){
             $("#div2").append(msg);
             alertmsg = $("#flag").text(); 
             if(alertmsg=="没抽中哦,再试试吧"){
              $("#myAlert").attr("class","alert alert-warning");
              if($("#new").text()=="")
                 $("#new").append(alertmsg);
             }
             else{                 
                 $("#myAlert").attr("class","alert alert-success");
                 if($("#new").text()=="")    
                     $("#new").append(alertmsg);    
             }

         
           }
        }); 
        $("#myAlert").show();
        $("#new").empty();
         $("#div2").empty();
    });
});

于是直接访问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){x
        echo "<p id=flag>抽奖,就是那么枯燥且无味,给你flag{xxxxxxxxx}</p>";
    }
    else{
        echo "<p id=flag>没抽中哦,再试试吧</p>";
    }
}
show_source("check.PHP");

 

很明显上面的是一个采用随机数来抽取,而对于mt_rand()这个函数来说,它本质上来说是一个随机,因此如果它的种子是固定的,那么出现的随机数也是固定的。所以这个题目就可以利用这一点。

利用他给你的前几位来让它推算随机数的种子。

这里要用一个PHP_mt_rand的小工具来进行反向破解它的种子。

 

这里首先要把它生成随机数求出来,这里的随机数,是对应str_long1的下标。

 

然后利用python脚本把它转换成PHP_mt_rand可以识别的数列:

str1 ='8ToN2h1nNH'
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)

 

不过这里有一点我不太清楚的是为什么要把得到的随机数打印两遍,然后加上0再加上长度,我推测可能是这个小工具调用的时候就是要这么调用

 

然后把得到的数列用小工具跑

 

 得到了种子,于是用这个种子去调用mt_rand去生成随机

<?PHP
    mt_srand(854007932);
    $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>";
?> 

 

 

 把结果交上去就可以得到flag

 

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...