题目打开后得到的信息是
查看源码可知
很显然,想让我们利用源码去得到flag。
源码解析:
开始有三个变量:user,file,pass,但是我们发现这里的pass也就是password没什么用,所以我们重点关注前面两个变量。看下面的条件:
这里**isset的意思是查看变量是否存在,也就是说user不能为空**
file**_get_contents是把整个文件读入字符串中,这里也就是user这个变量(user显然是要一个文件)的内容以字符串的方式读出来并且要和welcome to the bugkuctf类型完全相等(类型和内容)。**
后面提示了我们所有**我们要在满足条件后读取file=hint.php**
知道了以上三个条件后我们就可以做第一步 ,就是如何满足他们的条件?
这里就要使用php伪协议了。这道题目为了解决第二个条件,要用到“php://input”**协议**。大致的意思是让txt=php://input,之后再post过去一个字符串
(当传进去的参数作为文件名变量去打开文件时,可以将参数php://传进,同时post方式传进去值作为文件内容,供php代码执行时当做文件内容读取)**类似**
(ps:此时的payload还不完整不能执行哈)
简单来说就是将指定的字符串作为文件传给txt,然后再将user的内容读出来。此时我们就满足了
此时我们得到
根据提示我们可以把包含的文件读出来了,这里要用到php的第二个**伪协议:php://fileter**
这里放上一个写的详细的blog(关于filter的):http://blog.csdn.net/wy_97/article/details/77431111
文件在index里有用到
即 **txt=php://input&file=php://filter/read=convert.base64-encode/resource=**hint.php(简单来说就是利用伪协议读取所包含文件的base64值)得到
base64解码得到:
之后我们可以继续利用伪协议读取一下index.php的源码
在index里面我们能读到:
这个乱码在index.php里我们发现是
所以我们不能直接读flag.php。在index我们看到
preg_match是正则
这意思是说file中国包含flag,那么就会给你退出。所有我们要想用其他办法读flag.php,我们去找有用的信息发现
这个else写如果我的file不包含flag,那么我就会把那个文件包含进来,之后将password反序列化一下。并输出password的结果,而我们根据上面的hint.php发现
我们**发现当flag方法当做字符串执行时,就会自动执行___tostring方法,方法中卸了如果file文件存在,那么就输出file文件中的内容。**
这不正是我们要解决的flag.php的内容的情况吗??所以我们要构造一个flag类型的参数,并把这个参数传给password然后get进去。并且这个file的值要是hint.php(因为要利用hint.php中的函数)
接之前的另一个解释:我们回到flag类那块,**看到里面有个$file属性,并且有个魔术方法_tostring(),这个方法的作用就是调用实例化对象时就会自动执行_tostring()这个方法,简单来说创造一个这个类的对象就会调用这个方法。而在_tostring()中会输出字符串的形式输出file,根据上面的这些条件,我们可以让$password为FLAG类型,并且让FLAG的$file就等于flag.php,这样我们就可以得到flag.php的内容弄了,不过要记得,前面$pasword进行了反序列化的操作。所以我们要先把它反序列化。写一个php脚本:**
得到
至此这道题目结束。不过应该会有同学问为何payload中有index.php,,我觉得index.php是默认的页面,不然你没有办法传给php页面参数,所以应该属于一种套路吧,记住就好。。。。