文|腾讯蓝军 路飞
0x00 前言
Ghostscript是一款Adobe PostScript语言和PDF的解释器软件,被诸多著名应用(如ImageMagick)所使用。
9月5日,海外安全研究员在Twitter公开Ghostscript的安全模式绕过0day,并给出ImagMgick的利用代码,该漏洞可以造成任意命令执行,影响诸多下游应用,当天TSRC紧急对该漏洞进行复现与分析。
9月9日,Ghostscript官方发布补丁代码,但是并没有发布编译程序。
9月27日,Ghostscript官方发布修复后的新版本编译程序。
可以说这个0day是影响了相当一段时间,这个漏洞的利用也比较曲折,值得深入研究思考。这篇文章将完整分析从ImageMagick到Ghostscript的攻击利用链。
0x01 环境搭建及复现
1. 影响范围
https://github.com/ImageMagick/ImageMagick
ImageMagick <= 7.0.11-10
https://github.com/ArtifexSoftware/ghostpdl-downloads/releases
Ghostscript <= 9.54.0
2. 漏洞环境搭建
可以在ubuntu 20的环境下快速复现
apt-get install imagemagick
git clone https://github.com/duc-nt/RCE-0-day-for-GhostScript-9.50.git
python IM-RCE-via-GhostScript-9.5.py "sleep 1000" 1.jpg
convert 1.jpg 1.pdf
通过pstree查看进程树,可以看到是GhostScript执行了sleep命令,由此可以确认分析路径。
ImageMagick是如何生成参数文件,并且传递给GhostScript解析?
GhostScript的沙箱是如何被绕过的?
0x02 ImageMagick
1. 分析ImageMagick
这里打算进行源码debug,所以我们从github上下载ImageMagick源码,编译debug版本,进行调试。后面附了整个栈信息,想快速分析的可以直接看栈信息就好了。
一开始看给的poc是生成jpg,以为是jpg文件处理出问题了,其实不然。ImageMagick会自动识别文件类型,通过GetImageDecoder函数获取相对应的文件decoder,这里获取到的decoder是ReadSVGImage,所以虽然将文件名命名为1.jpg,但是ImageMagick还是将文件为svg文件进行处理。
/tmp/ImageMagick-7.0.11-6/MagickCore/constitute.c
decoder=GetImageDecoder(magick_info)
ReadSVGImage函数是如何处理payload中重要的desc、image两个标签?
在ImageMagick/coders/svg.c中搜索到关键词"desc",来到如下图的位置。
在处理desc标签的时候,会里面内容加一个#,并且写入到/proc/self/fd/3中(当然这里的fd不一定是3,会根据进程里面打开的文件数量而变化)。
<desc>copies (%pipe%/tmp/;{}) (r) file showpage 0 quit desc>
将上面解析为如下内容,并且添加到/proc/self/fd/3
#copies (%pipe%/tmp/;sleep 1000) (r) file showpage 0 quit
同样搜索"image"关键词,来到如下图的位置。
/tmp/im/ImageMagick-7.0.11-6/coders/svg.c
<image href="epi:/proc/self/fd/3" />
将上面解析为如下内容&