[GWCTF 2019]枯燥的抽奖
碎碎念: 这道题是一道关于伪造伪随机数的题目,之前从未接触过,这次来记录一下
解题: 进入题目之后查看源码 发现check.php
发现源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <?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");
总体分析一下就是我们要输入一个num参数 当num等于他产生的随机长为20的字符串 就能拿到flag
mt_srand()
简单说就是这个函数给mt_rand()函数提供一个种子 然后mt_rand()函数去生成一个随机数,但是这个随机数其实是一个伪随机数
那么如果我们能破解出这个种子 这道题目就迎刃而解了
这里要用到php_mt_seed脚本去破解这个种子 脚本下载地址:https://www.openwall.com/php_mt_seed/
然后装到我的kali上
先make 一下
这里make一开始不知道是什么东西然后去查了查还是有东西的
然后这个脚本要先把这字符串转化为一个可识别的数列
python脚本如下:
1 2 3 4 5 6 7 8 9 10 11 str1='abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' str2='QJlBBqs6ji' str3 = str1[::-1] length = len(str2) res='' for i in range(len(str2)): for j in range(len(str1)): if str2[i] == str1[j]: res+=str(j)+' '+str(j)+' '+'0'+' '+str(len(str1)-1)+' ' break print(res)
但是我没有搞懂这个脚本的目的和原理
进行爆破 发现种子 这里调用脚本通过./
调用其实就是运行该脚本的意思
再根据这个种子 重新生成题目中的字符串 直接用题目的代码稍加修改就行
脚本如下:
1 2 3 4 5 6 7 8 9 10 <?php mt_srand(672026733); $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; ?>
拿到flag