打开题目,有效代码伪:
error_reporting(0); include("flag.php"); if(isset($_GET['r'])){ $r = $_GET['r']; mt_srand(hexdec(substr(md5($flag), 0,8))); $rand = intval($r)-intval(mt_rand()); if((!$rand)){ if($_COOKIE['token']==(mt_rand()+mt_rand())){ echo $flag; } }else{ echo $rand; } }else{ highlight_file(__FILE__); echo system('cat /proc/version');
这次取seed的值为md5加密$flag的前八位字符,并将加密后的值十六进制转换为十进制,然后判断是否有rand,如果有rand的值则输出$rand;没有则进行$_COOKIE[‘token’]==(mt_rand()+mt_rand())的比较,等于则输出flag。
从$rand = intval($r)-intval(mt_rand()中,首先我们可以传r=0让其输出第一个mt_rand()的值为1928644078,每一次不一样(因为flag值在变化) ,然后下载 php_mt_seed4.0 (本文末可下载)我们在linux下面使用 gcc进行编译 gcc php_mt_seed.c -o php_mt_seed ,这里以Kali作演示,下载解压到Kali桌面,选择在这里打开终端,
第一次进入php_mt_seed需要先执行make命令,之后运行脚本添加随机数 ./php_mt_seed 928644078
因为抓包可以发现题目PHP版本为7.3.11,所以我们这里选择7.0.1+的seed,3588771068,使用PHP跑一下两个随机数相加:
error_reporting(0); mt_srand(3588771068); echo mt_rand(); echo "-"; echo (mt_rand()+mt_rand());
得到928644078-2937317061,第二串数字即为token值,使用浏览器或者burpsuite在cookies中加入token,并同时提交get请求/?r=928644078,得到flag。
解释:
传这个值的原因是得到第一个mt_rand()的值为928644078,然后r-mt_rand()=0满足!$rand,才可以进行下一步$_COOKIE[‘token’]的比较。
if((!$rand)){ if($_COOKIE['token']==(mt_rand()+mt_rand())){ echo $flag; }
只有在$rand不存在时,$_COOKIE[‘token’]==(mt_rand()+mt_rand() 才能执行,而1928644078是我们在传?r=0时页面输出的随机数,
$rand = intval($r)-intval(mt_rand());
此时的$rand = mt_rand()即第一个生成的随机数,因此只要我们使$r=mt_rand()=1928644078,就能让$rand=0,不存在,从而执行接下来的代码。