查看页面源码可以看到一段JS代码:
javascript
$(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 交互的功能,通过 AJAX 提交用户输入,根据后端返回结果显示不同的提示信息。
通过抓包获取后端响应:
php
y5DXaGgCOC
没抽中哦,再试试吧
<?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");
随机生成一个SESSION['seed']并且当作生成随机数的种子值。同一个种子每次运行随机生成的序列都是相同的:

但是在本题中种子值也是随机生成的,我们不知道。但是我们可以本地跑出来,因为给了我们随机序列的前十位。
种子随机范围太大了。跑不了一点。只能换个思路.......
用爆破工具php_mt_seed。首先将题中给出的前十位转换成原始数列:
php
<?php
$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$max = strlen($str_long1)-1;
$min = 0;
$str = 'ZrNsqX9wYd';
for ($i = 0; $i < strlen($str); $i++) {
$s = $str[$i];
$num = strpos($str_long1, $s);
if ($num !== false) {
echo "$num $num $min $max "; //这是官方文档指定的格式
}
}
得到
61 61 0 61 17 17 0 61 49 49 0 61 18 18 0 61 16 16 0 61 59 59 0 61 35 35 0 61 22 22 0 61 60 60 0 61 3 3 0 61

然后使用php7.1.1+使用该随机种子利用题目源码生成序列:
php
<?php
mt_srand(798533660);
$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_show = substr($str, 0, 20);
最后成功拿到flag。
总结一下:首先客户端网页源代码是由JS程序控制,需要通过抓包直接查看服务端响应获得源码提示。然后利用php_mt_seed工具爆破随机种子。