某cms命令执行绕过分析

CraftCMS在4.4.14版本中存在服务器端模板注入的漏洞,经过身份验证的攻击者可以绕过路径过滤设置模板目录,将任意文件上传至Twig模板目录中,从而导致模板注入进而造成远程代码执行

CraftCMS在4.4.14版本中存在服务器端模板注入的漏洞,经过身份验证的攻击者可以绕过路径过滤设置模板目录,将任意文件上传至Twig模板目录中,从而导致模板注入进而造成远程代码执行。

0x01 环境搭建

这里使用craft cms 4.4.14版本,首先从github的Releases中下对应版本的压缩包解压,也可以通过composer或ddev进行安装,需要这里需要linux系统,并且php版本需要高于8.0,中间件为apache,因为程序安装完后会自动生成apache的伪静态配置文件,少一部配置过程。

composer create -y --no-scripts craftcms/craft=4.4.14

然后执行php craft setup进行设置安装

image-20230907141916580

设置数据库相关信息和管理员密码后会自动导入数据库进行安装,安装成功后访问如下即可

image-20230907113620674

0x02 漏洞复现及分析

    1. 设置Filesystem

首先进入后台,点击Settings设置Filesystem

Filesystem将资产管理(组织、权限和内容)与实际存储和服务文件的细节分离。

这里Name和Handle可以随便填,Base Path需要填写模板文件的路径,当我们直接填写模板文件的绝对路径时

image-20230907152102498

在保存时会提示Local volumes cannot be located within system directories.提示本地卷不能位于系统目录中。在之前的版本中,我们可以可以填写模板文件的路径,但是在之后的版本中进行修复,增加了validatePath方法对输入的路径进行检测

image-20230907114840910

image-20230907114854192

validatePath方法中,会分别获取需要验证的路径和系统路径进行一一对比,

如果为系统路径则报错Local volumes cannot be located within system directories.提示本地卷不能位于系统目录中,在SystemPaths中正好有模板目录的路径,所以这里会被拦截

image-20230907154950484

但是这里可以通过file协议来进行绕过,但是这里仅支持linux系统,因为在windows下路径的风格时采用反斜杠"\",所以程序会将输入的内容进行替换

image-20230907154402829

所以使用file://也会被替换成file:\\导致不会进入第二个红框里进行跳出,最后进入第三个红框中将所以路径用操作系统对应的分隔符进行拼接,最后形成

file:\C:\CraftCMS-4.4.14\templates

而在linux中则会在第二个判断协议中直接跳出判断,可以正常设置。所以这里只有linux才能复现成功。

image-20230907154850487

    1. 设置Asset

接下来就是创建资产,点击Settings设置Asset,新增一个Volumes(卷)

Craft 允许您像条目和其他内容类型一样管理媒体和文档文件(“Asset”)。Asset可以存在于任何地方——Web 服务器上的目录,或 Amazon S3 等远程存储服务。

资产被组织成,每个卷都位于文件系统之上,并具有自己的权限和内容选项。卷是从SettingsAssets配置的。

这里的Name和Handle可以随便填,Filesystem选择我们刚刚新建好的,然后点击右上角的保存

image-20230907162017888

    1. 上传模板文件

接下里就可以在模板目录里上传模板文件了,该cms使用的是Twig模板进行渲染的,所以这里我们可以使用Twig模板引擎注入进行RCE,

关于Twig模板注入已经有师傅在社区中研究过了,具体可以移步至 Twig 模板引擎注入详解学习

所以构造以下payload

{{123*123}}
{{['whoami']|map('system')|join}}
{{['id']|map('system')|join}}

这里简单说一下它和flask中的jinja2模板引擎差不多,都是使用一对大括号包裹语法。由于craft cms使用的twig模板引擎的版本是3.x,所以可以使用map过滤器进行构造payload,在模板中会被编译为如下图,第二行的代码手下按会经过twig_array_map然后执行twig_join_filter

image-20230908112313933

查看map过滤器的源码:

image-20230908111901556

这里$r[$k] = $arrow($v, $k),只要控制传过来的两个参数$arrow$array就可以实现函数调用

由于map过滤器返回的是一个array类型,所以还需要用join将其转传承string才能正常显示。

image-20230908112729791

将该内容保存为poc.txt,然后在Assets中上传文件

image-20230907172347183

这里上传文件时,会首先对前面设置的Filesystem中的路径进行创建,

image-20230907174019881

这里使用的是mkdir方法,通过查看官方文档查看file://mkdir

image-20230907173608186

image-20230907173846702

    1. 设置路由

在Settings然后点击New route新建一个路由,URI设置test(当然也可以设置为*),Template设置poc.txt

image-20230907172608116

最后访问设置的路由即可实现rce

image-20230907172642016

0x03 修复方式

官方已经发布了修复方式

image-20230907172831401

对输入的路径移除最左边的file://

  • 发表于 2023-09-22 09:00:02
  • 阅读 ( 17914 )
  • 分类:漏洞分析

0 条评论

请先 登录 后评论
中铁13层打工人
中铁13层打工人

79 篇文章

站长统计