Laravel刚刚发布的远程代码执行漏洞如何解决

1. 运行环境

1). 当前使用的 Laravel 版本?

2). 当前使用的 php/php-fpm 版本?

PHP 版本:laravel 5.8.38

php-fpm 版本:7.2

3). 当前系统 Windows 10

4). 业务环境 生产环境

5). 相关软件版本

2. 问题描述?

laravel刚刚发布的一个针对 5.8.38 版本的远程代码执行漏洞如何解决,以下是参考链接。
www.cnvd.org.cn/flaw/show/CNVD-202...

里面说了一个解决方式,参考链接
github.com/guoyanan1g/Laravel-vul/...
这个好像是没用啊,还是用的不对?如果用的不对的话,麻烦各位大神给出正确的使用方式,或者针对此漏洞给出解决方案(不能升级到更高版本的laravel,会有问题)

3. 您期望得到的结果?

4. 您实际得到的结果?

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
leo
最佳答案

看了下 poc 看起来是需要依赖 Mockery 这个包才能执行,正常线上项目 composer install --no-dev 是不会包含 Mockery 的,所以不用修。

6个月前 评论
lazyyy_boy (楼主) 6个月前
讨论数量: 6

由于本 CVE-2021-43503 我没有复现(在对应的 issue 中询问了为什么复现不了),但是在其 issue 中发现了另外一个 CVE-2022-30778,我成功复现了,所以下面会谈 CVE-2022-30778,而不是 CVE-2021-43503。

对于 CVE-2022-30778 具体可以看这个仓库,根据 README 中的步骤可以实现 RCE,示例会在 public/ 目录下创建一个 hello/ 目录。

Laravel

该漏洞是利用 PHP 反序列化。

首先来看一下 POP 链:

// vendor/laravel/framework/src/Illuminate/Broadcasting/PendingBroadcast.php, __destruct
public function __destruct()
{
    $this->events->dispatch($this->event);
}

// vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php, dispatch
public function dispatch($command)
{
    return $this->queueResolver && $this->commandShouldBeQueued($command)
                    ? $this->dispatchToQueue($command)
                    : $this->dispatchNow($command);
}

// vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php, dispatchToQueue
public function dispatchToQueue($command)
{
    $connection = $command->connection ?? null;

    $queue = call_user_func($this->queueResolver, $connection);

    if (! $queue instanceof Queue) {
        throw new RuntimeException('Queue resolver did not return a Queue implementation.');
    }

    if (method_exists($command, 'queue')) {
        return $command->queue($queue, $command);
    }

    return $this->pushCommandToQueue($queue, $command);
}

源头出在 __destruct(),反序列化 PendingBroadcast 类时会调用该方法,这也是很多反序列化漏洞的突破口。

实际执行危险代码的是 dispatchToQueue() 中的 $queue = call_user_func($this->queueResolver, $connection);

其中 call_user_func(callable $callback, mixed ...$args) 会调用 $callback 并将 ...$args 作为参数。

在我的 repo 中的 PoC 的例子中,构造上述 POP 链,来自定义 $this->queueResolver$connection 值。在我的例子中为 $this->queueResolver = "system", $connection = "mkdir hello",也就是在 public 目录下创建 hello 目录。

CVE-2022-30778 有多大危害

根据上述的推理,触发 CVE-2022-30778 需要使用 unserialize() 并且其中还能接受用户输入。文档中也明确定义了这么做是危险的。

file

用 SQL 注入来做对比,在 Laravel 中 DB::raw($value) 会原样执行 $value 中的内容,如果 $value 是用户输入的,则会产生 SQL 注入。但我们不会这么写代码,我们会保证 $value 是可控制的,不让用户输入,这样就不会造成 SQL 注入。(在这个 issue 的 reply 中同样举了关于 ROP 的例子。)

回到本漏洞,只要你的系统中没有用到 unserialize() 并且其参数能接受用户输入的话,就不会触发该漏洞。反之,如果用到,至少会触发 CVE-2022-30778。为什么说至少,因为可能还有其他漏洞没有被发现。

6个月前 评论

有哪位可以分析一下这个漏洞的具体应用吗?影响面

6个月前 评论
leo

看了下 poc 看起来是需要依赖 Mockery 这个包才能执行,正常线上项目 composer install --no-dev 是不会包含 Mockery 的,所以不用修。

6个月前 评论
lazyyy_boy (楼主) 6个月前

好的,多谢啦!

6个月前 评论

由于本 CVE-2021-43503 我没有复现(在对应的 issue 中询问了为什么复现不了),但是在其 issue 中发现了另外一个 CVE-2022-30778,我成功复现了,所以下面会谈 CVE-2022-30778,而不是 CVE-2021-43503。

对于 CVE-2022-30778 具体可以看这个仓库,根据 README 中的步骤可以实现 RCE,示例会在 public/ 目录下创建一个 hello/ 目录。

Laravel

该漏洞是利用 PHP 反序列化。

首先来看一下 POP 链:

// vendor/laravel/framework/src/Illuminate/Broadcasting/PendingBroadcast.php, __destruct
public function __destruct()
{
    $this->events->dispatch($this->event);
}

// vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php, dispatch
public function dispatch($command)
{
    return $this->queueResolver && $this->commandShouldBeQueued($command)
                    ? $this->dispatchToQueue($command)
                    : $this->dispatchNow($command);
}

// vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php, dispatchToQueue
public function dispatchToQueue($command)
{
    $connection = $command->connection ?? null;

    $queue = call_user_func($this->queueResolver, $connection);

    if (! $queue instanceof Queue) {
        throw new RuntimeException('Queue resolver did not return a Queue implementation.');
    }

    if (method_exists($command, 'queue')) {
        return $command->queue($queue, $command);
    }

    return $this->pushCommandToQueue($queue, $command);
}

源头出在 __destruct(),反序列化 PendingBroadcast 类时会调用该方法,这也是很多反序列化漏洞的突破口。

实际执行危险代码的是 dispatchToQueue() 中的 $queue = call_user_func($this->queueResolver, $connection);

其中 call_user_func(callable $callback, mixed ...$args) 会调用 $callback 并将 ...$args 作为参数。

在我的 repo 中的 PoC 的例子中,构造上述 POP 链,来自定义 $this->queueResolver$connection 值。在我的例子中为 $this->queueResolver = "system", $connection = "mkdir hello",也就是在 public 目录下创建 hello 目录。

CVE-2022-30778 有多大危害

根据上述的推理,触发 CVE-2022-30778 需要使用 unserialize() 并且其中还能接受用户输入。文档中也明确定义了这么做是危险的。

file

用 SQL 注入来做对比,在 Laravel 中 DB::raw($value) 会原样执行 $value 中的内容,如果 $value 是用户输入的,则会产生 SQL 注入。但我们不会这么写代码,我们会保证 $value 是可控制的,不让用户输入,这样就不会造成 SQL 注入。(在这个 issue 的 reply 中同样举了关于 ROP 的例子。)

回到本漏洞,只要你的系统中没有用到 unserialize() 并且其参数能接受用户输入的话,就不会触发该漏洞。反之,如果用到,至少会触发 CVE-2022-30778。为什么说至少,因为可能还有其他漏洞没有被发现。

6个月前 评论

该漏洞后续:本帖作者给出的 CVE-2021-43503 和我分析的 CVE-2022-30778 都已经被拒绝,不再属于漏洞。更多上下文可以看这条 issue

3个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!