# 0ctf writeup
**Author:双螺旋安全研究院**
0x00 Rand_2(web)
================
* * *
访问http://202.120.7.202:8888/,即可获取到题目的源码:
“`
60){
session_destroy();
die(‘timeout’);
} else {
$_SESSION[‘time’] = time();
}
echo rand();
if(isset($_GET[‘go’])){
$_SESSION[‘rand’] = array();
$i = 5;
$d = ”;
while($i–){
$r = (string)rand();
$_SESSION[‘rand’][] = $r;
$d .= $r;
}
echo md5($d);
}else if(isset($_GET[‘check’])){
if($_GET[‘ckeck’] === $_SESSION[‘rand’]){
echo $flag;
} else {
echo ‘die’;
session_destroy();
}
} else {
show_source(__FILE__);
}
?>
“`
由源码可以得知,在没有GET参数go的时候,会生成并输出一个随机数,当带上GET参数go的时候,会在session中写入五个随机数,并将他们组合起来的hash返回,如果提交的check和`session[‘rand’]`的值相等,则返回flag。
参考:[http://www.sjoerdlangkemper.nl/2016/02/11/cracking-php-rand/](http://www.sjoerdlangkemper.nl/2016/02/11/cracking-php-rand/)
文章中提到了:
“`
state[i] = state[i-3] + state[i-31]
return state[i] >> 1
“`
根据这一思路,如果我们能得到连续的超过32个生成的随机数,就可以预测后面生成的数字。为了得到连续的随机数,使用requests.session来keep-alive。
在实际测试中,我发现有时候预测出来的结果会和实际得到的结果差1,不过没有找到规律,所以没有管他,直接多跑了几遍就出来了flag,脚本如下:
“`
import requests
while 1:
s = requests.session()
l = []
for i in range(50):
l.append(int(s.get(‘http://202.120.7.202:8888/’).content.split(‘