前置知识
php根据mt_srand()
设置种子
同一个种子生成出来的随机数列相同
使用mt_rand()
生成随机数
生成的随机数列会由于php版本有所不同
例子:
1 2 3 4 5
| <?php mt_srand(123); echo mt_rand()."\n"; echo mt_rand()."\n"; echo mt_rand()."\n";
|
结果
每次的结果都一样
例题1
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
| <?php
error_reporting(0); include("flag.php"); if(isset($_GET['r'])){ $r = $_GET['r']; mt_srand(372619038); if(intval($r)===intval(mt_rand())){ echo $flag; } }else{ highlight_file(__FILE__); echo system('cat /proc/version'); }
?>
|
也就是预判到了mt_rand()
的值就会输出flag,由于设置了种子,所以每次生成的随机数列相同,可以在本地使用相同版本的php生成
1 2 3 4 5
| <?php mt_srand(372619038); echo mt_rand()."\n"; echo mt_rand()."\n"; echo mt_rand()."\n";
|
payload:
例题2
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 29 30 31
| <?php
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'); }
|
首先会截取flag的前8位转换为十进制作为种子,然后生成随机数列,首先要获取第一次生成的种子值,先传入?r=0
,得到负数-190739760,拿去爆破种子,这里使用php_mt_seed工具
用法:
本地使用的是7.4的php版本,所以存在两个可能0xcf8ac542 = 3481978178
和0xe56eff61 = 3849256801
,试了试发现是3481978178,生成随机数列
将后两个相加,添加token=2309072205
即可拿到flag