BUUCTF WEB 枯燥的抽奖1

本文详细分析了一个基于PHP的猜数游戏,揭示了如何通过代码审计找到固定种子并进行伪随机数的爆破。通过理解mt_srand函数和随机数生成机制,作者展示了如何利用特定工具反推出种子,最终成功预测随机数序列,解决爆破问题。文章还提供了相关代码实现和爆破过程,适合对信息安全和PHP编程感兴趣的读者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码审计,打开页面,就发现了

$(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"); 

看起来是考的伪随机数,其实就是一个有伪随机数的爆破问题,只要有固定的种子,那么生成随机数序列是固定的。这也就是为什么你刷新页面这个随机数都不会变的原因

session里的种子我们读不到,但是可以爆破
str1 ='OYn87LsZj5'
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)

这里是对根据代码原先的逻辑进行处理,j是随机出的值,length代表取数区间
得到:50 50 0 61 60 60 0 61 13 13 0 61 34 34 0 61 33 33 0 61 47 47 0 61 18 18 0 61 61 61 0 61 9 9 0 61 31 31 0 61
然后根据求出的值利用php_mt_seed进行爆破,爆破出种子
./php_mt_seed 50 50 0 61 60 60 0 61 13 13 0 61 34 34 0 61 33 33 0 61 47 47 0 61 18 18 0 61 61 61 0 61 9 9 0 61 31 31 0 61
结果输出php7.1.0版本往上爆破出种子299287931(随机数算法和php版本也有关)
有了种子,我们就可以顺利反推了

<?php
mt_srand(299287931);
$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>";
?> 

顺利得到结果
OYn87LsZj59lqv9q0Z92
和运期结果一样,顺利提交flag
参考视频链接:https://www.bilibili.com/video/BV1NZ4y1C7gf/

根据提供的源代码和引用的内容来看,[GWCTF 2019]枯燥抽奖 1是一道PHP伪随机数的题目。该题目中使用了mt_rand()函数生成伪随机数,并通过种子来控制生成的序列。通过审计代码,我们可以看到check.php是存在的,并且在其中进行了抽奖的逻辑判断。如果用户输入的num与生成的随机数str相等,则会显示抽奖成功的提示信息,否则会显示抽奖失败的提示信息。为了解决这道题目,可以使用提供的Python脚本来转换伪随机数生成的序列,从而得到正确的种子。具体的转换过程可以参考脚本中的代码实现。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [[GWCTF 2019]枯燥抽奖1](https://blog.youkuaiyun.com/qq_63940076/article/details/128634284)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [[GWCTF 2019]枯燥抽奖 1](https://blog.youkuaiyun.com/qq_50454266/article/details/115407565)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值