Z1d10tのBlog

A note for myself,have fun!

  1. 1. 碎碎念:
  2. 2. 解题:

[GWCTF 2019]枯燥的抽奖

碎碎念:

这道题是一道关于伪造伪随机数的题目,之前从未接触过,这次来记录一下

解题:

进入题目之后查看源码 发现check.php

img

发现源码:

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()

img

简单说就是这个函数给mt_rand()函数提供一个种子 然后mt_rand()函数去生成一个随机数,但是这个随机数其实是一个伪随机数

那么如果我们能破解出这个种子 这道题目就迎刃而解了

这里要用到php_mt_seed脚本去破解这个种子 脚本下载地址:https://www.openwall.com/php_mt_seed/

img

然后装到我的kali上

先make 一下

这里make一开始不知道是什么东西然后去查了查还是有东西的

img

img

然后这个脚本要先把这字符串转化为一个可识别的数列

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)

但是我没有搞懂这个脚本的目的和原理

进行爆破 发现种子 这里调用脚本通过./调用其实就是运行该脚本的意思

img

再根据这个种子 重新生成题目中的字符串 直接用题目的代码稍加修改就行

脚本如下:

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;
?>

img

拿到flag

img

本文最后更新于 天前,文中所描述的信息可能已发生改变