自能生羽翼,何必仰云梯
代码:
1 |
|
error_reporting(0)
关闭所有PHP错误报告
session_start()
初始化session
highlight_file(__FILE__)
对当前文件进行语法高亮显示
开头先包含了一个 flag.php
文件进来,然后通过 GET
传入 id
赋值给 login
变量
1 | include "flag.php"; |
判断,如果 login
里没有 cookie
这个参数,或者 cookie
参数不等于 md5
后的 session flag
值 ,满足一个条件,就直接 die
1 | if(!@isset($login['cookie'])||$login['cookie'] != @md5($_SESSION['flag'])){ |
满足这个条件很简单,cookie
设置 flag=123456
,然后把 123456
进行 md5
加密后传给cookie
走进 else
里面
1 | mt_srand(substr($login['cookie'],17,7)); |
把传入的 cookie
值从第17位起,后面的7位截取出来做种子(我这里截取出来就是 9800998
),然后传给 mt_srand()
函数做种子
mt_scand(seed)
这个函数分发种子,然后再通过 mt_rand()
函数来生成随机数
这个题的核心考点也就是关于这个函数使用不当产生的漏洞利用:同一个种子下生成的随机数值是相同的
网上有大佬做的实验:
设置固定种子后,后面每次执行,随机数也都相同,这证明了破解随机种子的可行性
再往下
1 | $content = "<?php \$flag="."'".$flag."'"."?>"; |
写入内容赋值给 content
变量里,变量 flag
应该是包含开头的 flag.php
文件里面的
然后 filename
等于一个 mt_rand()
生成的随机数,使用我们的种子(9800998)生成一个随机数看看
生成的第一个随机数是:1160121479,证明我们生成的文件名应该就是 1160121479.php
然后就是把第一行的内容写入到第二行的文件里面,生成文件
继续往下
1 | mt_srand(mt_rand()); |
发现又使用了新的种子,我们在本地也模拟一下
发现使用新的种子生成的随机数是 954576979
1277894509
…
得出后续的随机数后,继续往下跟
1 | if ($_POST['key'] == mt_rand()) |
判断POST里面的 key
需要等于 mt_rand()
随机值,我们把新种子生成的第一个随机数 954576979
传进去
成功走进 if
里面,然后下面就是一个动态变量覆盖,不过他的值又需要下一个随机数,我们上面已经算出来了,下一个随机数是1277894509
然后我们把变量 filename
传给他,他可以直接请求到变量文件里面的 flag
最后一个语句就类似变成了 file_get_contents($filename)
,把 flag
文件给我们读取出来了