【漏洞分析】Modx Revolution远程代码执行漏洞CVE-2018-1000207

近日,MODx官方发布通告称其MODx Revolution 2.6.4及之前的版本存在2个高危漏洞,攻击者可以通过该漏洞远程执行任意代码,从而获取网站的控制权或者删除任意文件。 本文分析其中的CVE-2018-1000207漏洞,并分别分析MODx 2.5.1和2.6.4版本漏洞形成原因和PoC构造。

0x01 概述

近日,MODx官方发布通告称其MODx Revolution 2.6.4及之前的版本存在2个高危漏洞,攻击者可以通过该漏洞远程执行任意代码,从而获取网站的控制权或者删除任意文件。 本文分析其中的CVE-2018-1000207漏洞,并分别分析MODx 2.5.1和2.6.4版本漏洞形成原因和PoC构造。

0x02 环境搭建

分别安装MODx 2.5.12.6.4版本

0x03 漏洞分析

2.5.1版本

漏洞发生在phpthumb模块,该模块的作用是提供缩略图对象

1532080364911

当我们把光标放到文件系统中的图片上的时候,可以看到弹出了图片的缩略图,此时就调用了phpthumb接口

请求接口类似这样

http://127.0.0.1/connectors/system/phpthumb.php?src=1.png&w=116&h=0&HTTP_MODAUTH=modx5b5067d920ba81.94108199_15b513c49743c49.16917110&f=png&q=90&wctx=mgr&source=1

可以看到几个参数描述了图片的一些基本属性,这些属性在core/model/phpthumb/phpthumb.class.php中定义

从定义中也能看到,phpthumb提供了两种类型的参数:publicprivate

public就是普通属性,包括图片长宽高等,private则是一些私有属性,包括缓存目录,文件类型等,此次漏洞形成的关键就是程序并没有对两种类型的参数区分处理,以至于我们可以直接传入私有参数控制其中的变量值,从而改变程序执行逻辑。

当我们请求这个接口的时候,会访问modSystemPhpThumbProcessor()类,其中的process()方法:

 

可以看到里面的几个主要操作,包括检查文件是否被缓存,以及读取缓存,设置缓存等,我们利用的就是phpthumb设置缓存的方法phpThumb->cache()

这里面关键的方法是RenderToFile(),可以看到它接收参数$this->cache_filename,那么我们可以直接传入cache_filename这个变量值。

RenderToFile()方法里有file_put_contents()函数,文件名是我们传入的cache_filename,文件内容是$this->outputImageData。如果对内容没有校验的话意味着我们可以写入任意内容,前提是满足$this->RenderOutput()为真,进去看一下RenderOutput()

在这里我们需要满足$this->useRawIMoutput为真,而这个变量默认值为false。实际上useRawIMoutput即为我们提到的私有变量,程序虽然默认定义了私有变量的值,但我们还是可以通过post把值直接传进去,同时这里也没有检验文件的内容,直接把$this->IMresizedData赋值为$this->outputImageData,也就是file_put_contents()所需要的第二个参数,所以到这里就能构成一个任意文件写入的漏洞。

构造PoC:

cache_filename=../../../payload.php&src=.&ctx=web&useRawIMoutput=1&config_prefer_imagemagick=0&outputImageData=<?php phpinfo();?>

需要特别注意的是,此处的cache_filename与网站相对路径密切相关,往上目录穿越少了反而不能写入文件,而在Windows下测试可以写入Web根目录以外的目录,因为程序内部虽然检查了目录写权限,却并没有限制一个根目录,所以严格来说这里还存在一个目录穿越漏洞。

这个利用在MODX 2.5.1版本及之前可以无需登录直接利用,而在2.6.4版本进行了更严格的权限检查,在处理请求之前增加了这样一段判断代码:

core/model/modx/modconnectorresponse.class.php outputContent()方法

所以在2.6.4版本利用需要登录权限。

2.6.4版本

那么有没有方法在2.6.4版本也能不需要权限直接写入任意文件呢?答案还是有的,只不过网站需要安装一个插件Gallery

Gallery is a dynamic Gallery Extra for MODx Revolution. It allows you to quickly and easily put up galleries of images, sort them, tag them, and display them in a myriad of ways in the front-end of your site.

简而言之Gallery 是一个图库,可以更方便地管理网站图片。

在这个库中也有phpThumb的相关方法,而且同样有缓存机制,不出意外同样存在任意文件写入漏洞,但是这个方法稍微复杂一些,它把文件写入cache目录,而文件名经过了一个array的反序列化再MD5,这样即使我们能写入文件,却猜不到文件名,因此a2u给出的PoC也没能直接写入文件,而是通过返回包来判断是否存在漏洞。但是经过分析,实际上我们是可以往缓存目录写入一个shell的,而且能够知道保存的文件名,下面来分析一下如何绕过这个看似复杂的流程。

1532596628836

当利用插件上传图片的时候,如果图库中已经有图片,我们就可以看到一张缩略图,请求类似这样

http://127.0.0.1/modx-2.6.4-pl/assets/components/gallery/connector.php?action=web/phpthumb&w=100&h=100&zc=1&src=/modx-2.6.4-pl/assets/gallery/1/cover.png&time=1532596253635

同样的,galleryconnector.php也接收图片属性等public参数,但是此处我们并不关心,直接定位到处理写入缓存的文件core/components/gallery/processors/web/phpthumb.php。漏洞形成点同样也是file_put_contents参数没有经过过滤。

请求在进入phpthumb.php之后,首先会把参数设置成一个array,放在$scriptProperties中,类似这样

在调用系统phpthumb.class.php模块的RenderToFile之前对文件进行了一系列处理,主要关注其中几个

首先对src文件后缀有一个判断

如果没有指定f参数的话,就根据文件后缀将f赋值。也就是说,如果我们传递了f参数,也就可以指定任意文件后缀,此处没有任何过滤。

然后判断src参数是否是以http开头,如果不是,则把src拼接成完整的物理路径:D:/phpStudy/PHPTutorial/WWW/modx-2.6.4-pl/assets/gallery/1/cover.png

接着把src路径中的:/替换成_,也就是D__phpStudy_PHPTutorial_WWW_modx-2.6.4-pl_assets_gallery_1_cover.png,这个字符串将成为最后缓存文件的文件名的前半部分。

而文件名后半部分则是md5(serialize($scriptProperties))的值,把上面的array进行反序列化再MD5,最后拼接上面设置的f后缀,所以最后的文件名类似D__phpStudy_PHPTutorial_WWW_modx-2.6.4-pl_assets_gallery_1_cover.png.0f0d6092657266f9718061fb8a20730d.png,由于在实际利用中我们不知道网站物理路径,因此几乎无法猜出这个文件名。

绕过方式就是利用src参数,上面代码对src进行了一个http判断,假如我们指定srchttp开头,就不会拼接物理路径,而反序列化时的各个参数均是我们可以控制的,这样我们最终就能得到一个文件名类似http.md5_string.php的缓存文件。

构造PoC:

action=web/phpthumb&src=http&f=php&useRawIMoutput=1&config_prefer_imagemagick=0&IMresizedData=<?php phpinfo();?>

然后写一段代码来生成反序列化数据,此处要注意参数顺序,不同顺序生成的反序列化数据不一样,最终的MD5值也就会变

最终会在缓存目录assets/components/gallery/cache写入文件http.f23566b3b11f5fd29a8189b74ef53daf.php

1532601619133

0x04 补丁分析

https://github.com/modxcms/revolution/pull/13979/

1532602450085

补丁主要是对可传入的参数进行了限制,只允许公共参数(public parameters),这样就避免了直接传入私有参数改变程序逻辑。

0x05 总结

该漏洞的利用条件虽然有一定版本和插件限制,但是在互联网上Gallery插件的使用量并不小,相关站点需要多加防范。

此次漏洞应该归结于phpthumb模块,一是接口直接对外暴露,二是对文件操作缺少过滤。在MODx中的两个版本均受到影响,分别是 1.7.14-2016041513031.7.14-201608101311 ,在Github上搜索了几个使用该库的CMS,发现代码结构几乎一致,不排除也能直接利用的情况,有兴趣的可以研究一下。

发表评论