知识点:
一些函数
session_start() 会创建新会话或者重用现有会话。 $_SESSION — Session 变量,当前脚本可用 SESSION 变量的数组。 rand() 函数返回随机整数。 mt_srand(seed)函数通过分发seed种子,然后种子有了后,靠mt_rand()生成随机数。
|
PHP mt_rand函数
产生伪随机数。它产生随机数值的平均速度比 libc 提供的 rand() 快四倍。由可确定的函数,通过一个种子产生的伪随机数。可以通过种子/已产生的随机数来获得接下来的序列信息。有两个可选参数 min 和 max,如果没有提供可选参数,mt_rand函数将返回返回 0 到 mt_getrandmax() 之间的伪随机数。
破解工具:php_mt_seed是一个破解mt_rand函数seed的工具。参数说明:四个参数(高级模式)下,前两个参数表示mt_rand第一次输出的区间,后两个参数表示mt_rand输出的区间。
link:https://www.freebuf.com/vuls/192012.html
|
解题:
Ctrl+U查看源代码(坑)
<script type="text/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(); }); }); </script>
|
发现包含了check.php,直接访问得
C0WhH1dqUB
<?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值是否为空,是则用rand函数生成一个值,再将其作为mt_srand()的种子,之后利用$str_long1和随机数生成一串字符,最后截取前10个字符呈现。
思路
由于我们可以通过工具进行爆破出种子,那么我们就可以重复操作得出完整的字符串
解
由题目选择,工具的模式(四个参数),前两个是第一次输出区间(即题目给的字符串对应的生成过程中的每个随机数),后两个是输出区间
生成格式脚本:
<?php $pass_now = "TxnDsJjdHq"; $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; } } }
|
用工具爆破。
工具下载到Linux中:git clone https://github.com/openwall/php_mt_seed.git 进入目录 make一下,然后使用 ./php_mt_seed 55 55 0 61 23 23 0 61 13 13 0 61 39 39 0 61 18 18 0 61 45 45 0 61 9 9 0 61 3 3 0 61 43 43 0 61 16 16 0 61 后得到不同版本的。 种子得是PHP7.1以上的(找不到哪里显示PHP版本,可能都试一试?) 得到种子:773675551 工具官网(https://www.openwall.com/php_mt_seed/)
|
后再用题目脚本来得出字符串
<?php mt_srand(773675551);
$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; >
|
最后根据题目post一下就有了。