CVE-2019-6116 : Detail

CVE-2019-6116

7.8
/
High
8.93%V3
Local
2019-03-19
17h27 +00:00
2020-04-01
19h06 +00:00
Notifications for a CVE
Stay informed of any changes for a specific CVE.
Notifications manage

CVE Descriptions

In Artifex Ghostscript through 9.26, ephemeral or transient procedures can allow access to system operators, leading to remote code execution.

CVE Informations

Related Weaknesses

CWE-ID Weakness Name Source
CWE Other No informations.

Metrics

Metrics Score Severity CVSS Vector Source
V3.1 7.8 HIGH CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

Base: Exploitabilty Metrics

The Exploitability metrics reflect the characteristics of the thing that is vulnerable, which we refer to formally as the vulnerable component.

Attack Vector

This metric reflects the context by which vulnerability exploitation is possible.

Local

The vulnerable component is not bound to the network stack and the attacker’s path is via read/write/execute capabilities.

Attack Complexity

This metric describes the conditions beyond the attacker’s control that must exist in order to exploit the vulnerability.

Low

Specialized access conditions or extenuating circumstances do not exist. An attacker can expect repeatable success when attacking the vulnerable component.

Privileges Required

This metric describes the level of privileges an attacker must possess before successfully exploiting the vulnerability.

None

The attacker is unauthorized prior to attack, and therefore does not require any access to settings or files of the vulnerable system to carry out an attack.

User Interaction

This metric captures the requirement for a human user, other than the attacker, to participate in the successful compromise of the vulnerable component.

Required

Successful exploitation of this vulnerability requires a user to take some action before the vulnerability can be exploited. For example, a successful exploit may only be possible during the installation of an application by a system administrator.

Base: Scope Metrics

The Scope metric captures whether a vulnerability in one vulnerable component impacts resources in components beyond its security scope.

Scope

Formally, a security authority is a mechanism (e.g., an application, an operating system, firmware, a sandbox environment) that defines and enforces access control in terms of how certain subjects/actors (e.g., human users, processes) can access certain restricted objects/resources (e.g., files, CPU, memory) in a controlled manner. All the subjects and objects under the jurisdiction of a single security authority are considered to be under one security scope. If a vulnerability in a vulnerable component can affect a component which is in a different security scope than the vulnerable component, a Scope change occurs. Intuitively, whenever the impact of a vulnerability breaches a security/trust boundary and impacts components outside the security scope in which vulnerable component resides, a Scope change occurs.

Unchanged

An exploited vulnerability can only affect resources managed by the same security authority. In this case, the vulnerable component and the impacted component are either the same, or both are managed by the same security authority.

Base: Impact Metrics

The Impact metrics capture the effects of a successfully exploited vulnerability on the component that suffers the worst outcome that is most directly and predictably associated with the attack. Analysts should constrain impacts to a reasonable, final outcome which they are confident an attacker is able to achieve.

Confidentiality Impact

This metric measures the impact to the confidentiality of the information resources managed by a software component due to a successfully exploited vulnerability.

High

There is a total loss of confidentiality, resulting in all resources within the impacted component being divulged to the attacker. Alternatively, access to only some restricted information is obtained, but the disclosed information presents a direct, serious impact. For example, an attacker steals the administrator's password, or private encryption keys of a web server.

Integrity Impact

This metric measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of information.

High

There is a total loss of integrity, or a complete loss of protection. For example, the attacker is able to modify any/all files protected by the impacted component. Alternatively, only some files can be modified, but malicious modification would present a direct, serious consequence to the impacted component.

Availability Impact

This metric measures the impact to the availability of the impacted component resulting from a successfully exploited vulnerability.

High

There is a total loss of availability, resulting in the attacker being able to fully deny access to resources in the impacted component; this loss is either sustained (while the attacker continues to deliver the attack) or persistent (the condition persists even after the attack has completed). Alternatively, the attacker has the ability to deny some availability, but the loss of availability presents a direct, serious consequence to the impacted component (e.g., the attacker cannot disrupt existing connections, but can prevent new connections; the attacker can repeatedly exploit a vulnerability that, in each instance of a successful attack, leaks a only small amount of memory, but after repeated exploitation causes a service to become completely unavailable).

Temporal Metrics

The Temporal metrics measure the current state of exploit techniques or code availability, the existence of any patches or workarounds, or the confidence in the description of a vulnerability.

Environmental Metrics

These metrics enable the analyst to customize the CVSS score depending on the importance of the affected IT asset to a user’s organization, measured in terms of Confidentiality, Integrity, and Availability.

[email protected]
V2 6.8 AV:N/AC:M/Au:N/C:P/I:P/A:P [email protected]

EPSS

EPSS is a scoring model that predicts the likelihood of a vulnerability being exploited.

EPSS Score

The EPSS model produces a probability score between 0 and 1 (0 and 100%). The higher the score, the greater the probability that a vulnerability will be exploited.

EPSS Percentile

The percentile is used to rank CVE according to their EPSS score. For example, a CVE in the 95th percentile according to its EPSS score is more likely to be exploited than 95% of other CVE. Thus, the percentile is used to compare the EPSS score of a CVE with that of other CVE.

Exploit information

Exploit Database EDB-ID : 46242

Publication date : 2019-01-23 23h00 +00:00
Author : Google Security Research
EDB Verified : Yes

I noticed ghostscript 9.26 was released, so had a quick look and spotted some errors. For background, this is how you define a subroutine in postscript: /hello { (hello\n) print } def That's simple enough, but because a subroutine is just an executable array of commands, you need to mark it as executeonly if you're using system operators. That way, users can't peek inside and get references to operators they shouldn't be allowed to use. /hello { (hello\n) print } executeonly def That's still not enough though, because the routine might expose the contents to error handlers, so you also need to make it a pseudo-operator with odef. PostScript error handlers don't examine any deeper than the current operator (or pseudo-operator), so won't expose any of the contents if they stop. /hello { (hello\n) print } executeonly odef Looks good, but it gets weirder. If you don't bind the contents, then name resolution happens on execution, not when you define it. That means that someone can change the dictstack (which kind of works like variable scope in other languages) so that commands and operators do something different than when you defined the subroutine. Like this: GS>/hello { (hello\n) print } executeonly odef GS><< /print { (goodbye) == pop } >> begin GS>hello (goodbye) This means you also need to bind the routine, and also be very aware when you're writing it of what cannot be resolved at define-time (nobody ever said writing postscript was easy, lol). So now we have this: /hello { (hello\n) print } bind executeonly odef I think that's good enough for simple routines, but what if it's more complicated? The way you branch in PostScript is to create an ephemeral subroutine and pass it to the `if` or `ifelse` operators, like this: /hello { time 1200 lt { (good morning\n) print } { (good afternoon\n) print } ifelse } bind executeonly odef Do those ephemeral routines also need to be protected? The answer is yes, they're pushed on the operand stack just like everything else, so can cause /stackoverflow or /execstackoverflow errors, and will then be exposed to error handlers. Ghostscript didn't protect a whole bunch of these ephemeral routines, here is one example: 1123 { 1124 currentglobal pdfdict gcheck .setglobal 1125 pdfdict /.Qqwarning_issued //true .forceput 1126 .setglobal 1127 pdfformaterror 1128 } ifelse You can see the routine itself is bound, executeonly and odef, but the ephemeral routines inside it used for conditions and loops are not protected. These bugs are starting to get trickier to exploit, you have to make an operator fail very precisely, but I made a demo that works in 9.26. This uses the trick I described above of taking over names that couldn't be resolved at define time by pushing a new dict on the dictstack. This gives me a high degree of control over the routine. $ gs -dSAFER -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: /stackoverflow) ( Last 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--} ( Extracting .forceput...) ( Result:)--.forceput-- (Stage 11: Exploitation...) ( Should now have complete control over ghostscript, attempting to read /etc/passwd...) (root:x:0:0:root:/root:/bin/bash) (All Done) $ tail -1 ~/.bashrc echo pwned by postscript This exploit should work via evince, ImageMagick, nautilus, less, gimp, gv, etc, etc. It might require some adjustment to work on older versions, because it requires precise alignment of the operand stack, but 9.26 and earlier are all affected. p.s. I'm not regularly looking at ghostscript, this was just a random look at the new release. #DeprecateUntrustedPostscript ################################################################################ Project Member Comment 2 by [email protected], Dec 4 I noticed someone point out on twitter that the default $LESSOPEN can invoke ImageMagick: https://twitter.com/jensvoid/status/1065948452872511488 Naturally, that works with this too (just name the exploit foo.pcd) ################################################################################ Project Member Comment 3 by [email protected], Dec 4 This is ghostscript bug 700317 ################################################################################ Project Member Comment 5 by [email protected], Dec 12 Artifex sent me a proposed patch to review, but their patch only fixed the vulnerability for /stackoverflow. I did use /stackoverflow in the testcase, but as I mentioned in the report, any error will do. I updated the exploit to use /typecheck instead, and sent it to them with an explanation of why the patch was insufficient. Artifex also informed me that they plan to sit on their patch for the full 90 days, and will not commit it to git or release it. I consider this a bad faith gaming of our disclosure policy, which is astonishing for an open source company. Ghostscript vulnerabilities have been discovered exploited in the wild in the past (e.g. http://ghostbutt.com/), sitting on exploits with patches available for months is really unacceptable. I know that Artifex commercial customers are already cc'd on the ghostscript bug tracker, which makes this even harder to stomach. $ ./gs -dSAFER -sDEVICE=ppmraw -sOutputFile=/dev/null -f ghostscript-926-forceput-typecheck-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 11: Exploitation...) ( Should now have complete control over ghostscript, attempting to read /etc/passwd...) (root:x:0:0:root:/root:/bin/bash) ################################################################################ Project Member Comment 6 by [email protected], Dec 14 Artifex sent me a new proposed patch to review, this one changes all branches in system routines to look like this: /blah { { foo } executeonly { bar } executeonly ifelse } def That solution doesn't work, because it doesn't stop you extracting the routine, waiting for the stack to unwind then executing it outside pseudo-op context. That allows the error handler to access internals, so you just cause random errors and extract any contents you like. (I'm aware this is really getting into the postscript weeds, but basically "just" being executeonly is useless). 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) I sent this to Artifex and explained why their solution wont work. I *think* the branches need to be named and pseudo-ops, but that will be really ugly and I doubt Artifex will implement that, more likely they will make an interpreter change. ################################################################################ Project Member Comment 7 by [email protected], Dec 17 Artifex sent me a new patch that changes how the $error dict works, instead of getting a reference to the failing operator, you get a name object (i.e. /--foo-- instead of --foo--). I *think* this works, but if any ephemeral routine can be run in an unexpected context, it might be a security issue. Artifex says they're going to manually check for any that look dangerous, but in my opinion it will take a while to iron out all possible attack vectors. I think this is a major change and requires some thought, even if I can't immediately think of a way to break it (other than the unexpected context thing). Project Member Comment 8 by [email protected], Jan 7 Artifex sent me a patch with more checking for abusable procedures (i.e. routines that are useful in an unexpected context), hiding some that are hard to reason about. I spent a morning double checking for any more that they had missed and found one in gs_fonts.ps: 1105 dup 3 index .fontknownget 1106 { dup /PathLoad 4 index //.putgstringcopy 1107 4 1 roll pop pop pop //true exit 1108 } if 1109 .putgstringcopy is a dangerous operator, basically just a wrapper around .forceput. I wrote a quick demo that is able to extract a reference, and mailed it to Artifex. $ ./gs -dSAFER -sDEVICE=ppmraw -f 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. {--dup-- /PathLoad 4 --index-- --.putgstringcopy-- 4 1 --roll-- --pop-- --pop-- --pop-- true --exit--} --.putgstringcopy-- I checked pretty thoroughly, and this is the only one I could find that they had missed - but a lot of the code is quite hard to reason about, so I'm not sure there are no more. ################################################################################ Project Member Comment 9 by [email protected], Jan 8 Artifex sent me a patch that makes that executeonly, but not the containing procedures as well, so I could still make them fail. e.g. this one in gs_fonts.ps: 1137 } executeonly 1138 if pop % Stack: origfontname fontdirectory path 1139 } 1140 if pop pop % Stack: origfontname It doesn't matter that the inner one is executeonly, because if the outer one fails that one never gets called. $ ./gs -dSAFER -sDEVICE=ppmraw -sOutputFile=/dev/null -f font.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. .loadfont (.fontknownget, force /typecheck) --.forceundef-- operatortype GS> I sent an explanation to Artifex on why containing procedures also need to be fixed. I'm spending way too much time reviewing patches for this one bug, untrusted postscript needs to be deprecated asap. Project Member Comment 10 by [email protected], Jan 9 I got a new patchset from Artifex, this one has a set of five patches which should fix this bug. I've attached them for reference. ################################################################################ Project Member Comment 11 by [email protected], Jan 9 I think this patchset seems comprehensive, in summary: - Replaces references to operators with name objects in saved stacks for error handlers. - Makes all ephemeral procedures that contain dangerous operators executeonly, and any outer procedures. This isn't automated, they are manually changing the postscript. - Changes how error handlers behave in executeonly procedures so that faulting operators don't leak. - Rewrite a lot of code so less pseudo-operators are exposed to users, especially some that are complicated and hard to reason about. I think this will work, although it's hard to be confident they found all the transient routines - postscript is really hard to read. Assuming they found them all, this still requires that developers don't accidentally add new branches in any of the postscript and forget to make them executeonly, which seems like a very easy mistake to make. I asked if they would consider making dangerous operators search the estack for any non-executeonly routines, perhaps only for test runs - just to make sure future changes don't re-introduce this. Let's see what they say, it seems like a pretty simple change to me. Project Member Comment 12 by [email protected], Jan 10 Filed https://bugs.ghostscript.com/show_bug.cgi?id=700472 to cover regression tests: ----- When bug 700317 is fixed, it will be important that any future changes to postscript resources don't introduce any new conditions or other control structures that aren't executeonly. This seems like a really easy mistake to make, just changing an if into an ifelse, or adding another test could introduce a vulnerability. I wonder if some of the dangerous routines, like .forceput and so on, could search the e_stack every time they're called to verify there are no non-executeonly routines on the call stack. I suppose this is only necessary for test-cluster runs, just to make sure nobody accidentally breaks the security guarantees. Just looking at count_exec_stack() in zcontrol.c, it seems like the code would be really simple. Just filing this enhancement request to think about this (or some other solution). ----- Proof of Concept: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/46242.zip

Products Mentioned

Configuraton 0

Artifex>>Ghostscript >> Version To (including) 9.26

Configuraton 0

Fedoraproject>>Fedora >> Version 28

Fedoraproject>>Fedora >> Version 29

Fedoraproject>>Fedora >> Version 30

Configuraton 0

Canonical>>Ubuntu_linux >> Version 14.04

Canonical>>Ubuntu_linux >> Version 16.04

Canonical>>Ubuntu_linux >> Version 18.04

Canonical>>Ubuntu_linux >> Version 18.10

Configuraton 0

Debian>>Debian_linux >> Version 8.0

Debian>>Debian_linux >> Version 9.0

Configuraton 0

Opensuse>>Leap >> Version 15.0

Opensuse>>Leap >> Version 42.3

Configuraton 0

Redhat>>Enterprise_linux_desktop >> Version 7.0

Redhat>>Enterprise_linux_server >> Version 7.0

Redhat>>Enterprise_linux_server_aus >> Version 7.6

Redhat>>Enterprise_linux_server_eus >> Version 7.6

Redhat>>Enterprise_linux_server_tus >> Version 7.6

Redhat>>Enterprise_linux_workstation >> Version 7.0

References

https://access.redhat.com/errata/RHSA-2019:0229
Tags : vendor-advisory, x_refsource_REDHAT
http://www.securityfocus.com/bid/106700
Tags : vdb-entry, x_refsource_BID
https://usn.ubuntu.com/3866-1/
Tags : vendor-advisory, x_refsource_UBUNTU
https://www.exploit-db.com/exploits/46242/
Tags : exploit, x_refsource_EXPLOIT-DB
https://www.debian.org/security/2019/dsa-4372
Tags : vendor-advisory, x_refsource_DEBIAN
http://www.openwall.com/lists/oss-security/2019/01/23/5
Tags : mailing-list, x_refsource_MLIST
http://www.openwall.com/lists/oss-security/2019/03/21/1
Tags : mailing-list, x_refsource_MLIST
https://seclists.org/bugtraq/2019/Apr/4
Tags : mailing-list, x_refsource_BUGTRAQ
https://access.redhat.com/errata/RHBA-2019:0327
Tags : vendor-advisory, x_refsource_REDHAT
https://security.gentoo.org/glsa/202004-03
Tags : vendor-advisory, x_refsource_GENTOO