wecome to bugku 的解题思路
在我准备做题的时候,bugku上的这个题目打不开了,我只能百度源码在自己的phpstudy上搭建然后实验
首先可以看到题目
查看源代码
根据这段源码的意思是有三个参数:txt、file、password,
1、isset($user)是用来检测user变量是否为空,即user不能为空
2、&&后面的意思是以字符串的形式读取变量user中文件的内容与字符串“welcome to the bugkuctf”作比较,要是完全相等
3、如果满足上边两个条件的情况下,就会输出“hello admin”,并且包含了变量file,提示我们要使file=hint.php
如果不满足就会输出“you are not admin ! ”
知道了源码的意思我们就可以构造payload
满足第一个条件就是传入参数txt,这里用到协议php://input, 意思就是将参数以post的方式提交,然后传入相同的字符串
这样就把包含的文件读出来了
然后我们要用php://filter,读取源代码,满足第三个条件,构造payload
txt=php://input&file=php://filter/read=convert.base64-encode/resource=hint.php
就会有一串base64
解码就会得到hint.php的源码
然后我们再用伪协议得到index.php的源码
我们这时看一下这两个源码的意思,
1、第一个源码里提示了我们有flag.php,第二个源码说如果我们的参数file中包含flag,就会弹出“现在不能就给你flag哦”,然后退出
然后看else的条件说如果不包含flag的话就会把文件包含进来,然后将password反序列化之后输出来
2、hint.php源码中定义了一个类,其中有个 __tostring 方法,这个方法可以理解为将这个类作为字符串执行时会自动执行__tostring方法,
所以我们让password=这个类,就会执行__tostring方法,
这个方法写了如果变量file存在,就输出$file的文件中的内容,这个文件中的内容就可以是我们想要的flag.php的内容,
所以根据条件我们可以让$password等于Flag这个类,并且让$file=flag.php,因为password在第二段代码中会进行反序列化,要先把类序列化之后再传入
0:4:"Flag":1:{s:4:“file”;s:8:"flag.php";}
然后传入参数,
查看源码就可以得到flag
#代码中一些函数的意义:
file_get_contents() 函数把整个文件读入一个字符串中。
isset()函数检测变量是否已设置并且非 NULL
__toString() 方法用于一个类被当成字符串时应怎样回应,在这个题中就是,类Flag被当成了字符串flag,触发了这个方法
preg_match()函数是用来正则匹配的函数
unserialize()函数是反序列化函数,就是在适当的时候把序列化后的字符串再转化成原来的变量使用