Laravel三处全版本RCE链分析

admin 2022年9月20日16:10:20代码审计评论6 views2285字阅读7分37秒阅读模式

0x00 漏洞环境

https://github.com/N0puple/php-unserialize-lib

进入对应的文件夹执行如下命令启动环境:

docker-compose up -d

访问 http://x.x.x.x/index.php/test ,看到 hello world 既搭建成功

测试代码

<?php
namespace AppHttpControllers;

class TestController extends Controller
{
public function index()
{
if(isset($_GET['a']))
{
unserialize(base64_decode($_GET['a']));
}
else
{
echo "hello world";
}
}
}

0x02 漏洞分析

反序列化链1

使用 laravel 最常见的入口 src/Illuminate/Broadcasting/PendingBroadcast.php::__destruct()

Laravel三处全版本RCE链分析

$this->events$this->event 可控,找某个类的 dispatch 方法,这里找到 src/Illuminate/Bus/Dispatcher.php::dispatch($command)

Laravel三处全版本RCE链分析

$this->queueResolver$command 可控,我们进入 $this->commandShouldBeQueued($command) ,查看代码

protected function commandShouldBeQueued($command)
{
return $command instanceof ShouldQueue;
}

因此需要传进来的 $commandShouldQueue 的实例,而 ShouldQueue 是一个接口,因此只要是实现此接口的类的实例即可

Laravel三处全版本RCE链分析

如上的都可以,此处选取 BroadcastEvent  类,然后进入 $this->dispatchToQueue 方法

Laravel三处全版本RCE链分析

$connection$command->connection ,而 $commandBroadcastEvent 的实例,因此 $connection 可通过设置一个 connection 值来控制,而 $this->queueResolver 也是可控的,因此可以直接命令执行

反序列化链2

开局依旧是 src/Illuminate/Broadcasting/PendingBroadcast.php::__destruct() ,然后以 __call 入手,这里使用的是 src/Illuminate/Validation/Validator.php::__call() ,我们看到这里的代码

Laravel三处全版本RCE链分析

$method 是传进来的方法名,值为 dispatch$parameters 可控,$method 进入 Str::snake 进行一定的转换,然后返回,这里我们不用看代码,直接让 dispatch 进入得到返回值即可,不影响结果

Laravel三处全版本RCE链分析

可以看到,返回的 $rule 为空,接下来 $this->extensions 可控,我们进入 $this->callExtension 方法,第一个参数为空字符串,第二个参数可控

Laravel三处全版本RCE链分析

这里写的很明了,$this->extensions 可控,$parameters 也可控,直接可进入 call_user_func_array($callback, $parameters); ,并且可以命令执行

反序列化链3

同样的入口  src/Illuminate/Broadcasting/PendingBroadcast.php::__destruct()

public function __destruct()
{
$this->events->dispatch($this->event);
}

找到 src/Illuminate/Bus/Dispatcher.php::dispatch($command)

Laravel三处全版本RCE链分析

进入 dispatchToQueue 方法

Laravel三处全版本RCE链分析

$this->queueResolver 可控,$connection$command 得到,$command 也是可控的,因此都是可控的,因此可以执行任意类,我们找到如下位置

MockeryLoaderEvalLoader::load(MockDefinition $definition)

Laravel三处全版本RCE链分析

在这里,很容易知道,我们要找到一个 MockDefinition 的实例化对象,接下来进入 getClassName 方法

public function getClassName()
{
return $this->config->getName();
}

找到任意一个存在 getName 方法的类加进来就可以了

最后会使用到 getCode() 方法来获取值,然后 eval 执行,控制 $this->code 就可以执行任意代码。

public function getCode()
{
return $this->code;
}

我在写链子的时候,$command 写的是另一个类,虽然某些版本可用,但是没法通杀,无奈最后用了 phpggc 中的 RCE5 中的,不得不说,该链子确实写的严谨,可以通杀所有版本。

0x03 漏洞复现

通过 exp.php 生成 payload ,然后直接打

Laravel三处全版本RCE链分析

0x04 链接

环境与 exp 都可以在如下链接获取

GitHub

https://github.com/N0puple/php-unserialize-lib

GitBook:

https://n0puple.gitbook.io/php-unserialize-lib/

公众号

公众号搜索:安全漏洞复现

扫码持续关注:

Laravel三处全版本RCE链分析


原文始发于微信公众号(安全漏洞复现):Laravel三处全版本RCE链分析

特别标注: 本站(CN-SEC.COM)所有文章仅供技术研究,若将其信息做其他用途,由用户承担全部法律及连带责任,本站不承担任何法律及连带责任,请遵守中华人民共和国安全法.
  • 我的微信
  • 微信扫一扫
  • weinxin
  • 我的微信公众号
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年9月20日16:10:20
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                  Laravel三处全版本RCE链分析 http://cn-sec.com/archives/1307240.html

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: