枯燥的抽奖

[GWCTF 2019]枯燥的抽奖

image-20210411205041425

提交一个数字,network里发现提交给了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");

在session中随机生成一个种子,如果种子确定,则后来生成的随机数也是确定的……

更改session,相同的session出现的字符串前十位不变

生成的字符串由种子确定的随机数确定,我们要从已有的几组数据中爆破出种子

本来想用php写个脚本,发现这个想法不现实,性能拉跨……

php_mt_seed-4.0工具可以帮助我们完成破解,但首先我们要还原数据为合法的格式

一个参数

当只有一个参数的时候,这个参数代表mt_rand第一次输出的值。

两个参数

当有两个参数的时候,他们代表mt_rand第一次输出应该位于什么区间内。

第一个参数为最小值,第二个参数为最大值。

四个参数

前两个参数表示mt_rand第一次输出的区间,后两个参数表示mt_rand输出的区间。

多于五个参数

每四个参数一组,但是最后一组可以是1,2或4个参数。每一组引用对应的输出。

还原脚本:

1
2
3
4
5
6
7
8
9
10
11
str1='abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
str2=''
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)

image-20210411210432842

第一次输出的区间:固定相同的两个数

mt_rand输出的区间:只能是0-61

放到php_mt_seed里:

image-20210411210619599

得到seed,再根据seed找到完整字符串即可~

作者

inanb

发布于

2021-04-11

更新于

2021-08-23

许可协议


:D 一言句子获取中...