rex-zip 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a95759c12cde8b1cf3896b04ed2ff165bed20426
4
+ data.tar.gz: a0a2731839cbecedf333df2f3d4fac6a21872cb8
5
+ SHA512:
6
+ metadata.gz: 5f7bd388a005d6a785845c24207378652ab6429c95be8d08c78f11fd38e8881d1c271060bd0a73e444cc370802f649870e58870d359f940f37fd59f7fc5ec7f7
7
+ data.tar.gz: f446e3502dbf5a11c75f3bc64de0c8c0962e20cd45d107a9f863005efd1616844e0cc4a85cc5a98e3235b422674c71b1d98813de69310ca5db60ed1a1c7c7da4
Binary file
@@ -0,0 +1,2 @@
1
+ 5�<Γ�� �g�cOƹWT��q���,5�;�d��?!�I)����>�ㆹ�h�e�(���{d=�P�����ax�t3��t0�# Ր۞�s��98o�U6d��jR��ىϔ
2
+ *�͆~�VA���̖�a�Ґ�k�^ ��,��i �|�T�(,��K�_y�����g�Eo�n�
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.12.5
@@ -0,0 +1,52 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This Code of Conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting the project maintainers at msfdev@metasploit.com. If
39
+ the incident involves a committer, you may report directly to
40
+ egypt@metasploit.com or todb@metasploit.com.
41
+
42
+ All complaints will be reviewed and investigated and will result in a
43
+ response that is deemed necessary and appropriate to the circumstances.
44
+ Maintainers are obligated to maintain confidentiality with regard to the
45
+ reporter of an incident.
46
+
47
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
48
+ version 1.3.0, available at
49
+ [http://contributor-covenant.org/version/1/3/0/][version]
50
+
51
+ [homepage]: http://contributor-covenant.org
52
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rex-zip.gemspec
4
+ gemspec
5
+
data/LICENSE ADDED
@@ -0,0 +1,27 @@
1
+ Copyright (C) 2012-2013, Rapid7, Inc.
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+
10
+ * Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ * Neither the name of Rapid7 LLC nor the names of its contributors
15
+ may be used to endorse or promote products derived from this software
16
+ without specific prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
22
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,52 @@
1
+ # Rex::Zip
2
+
3
+ Ruby Exploitation(Rex) Library for creating Zip based archives such as *.zip, *.war, and *.jar files. Ported from the original
4
+ Metasploit Framework code written by jduck.
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'rex-zip'
12
+ ```
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install rex-zip
21
+
22
+ ## Usage
23
+
24
+ Creating a .zip example:
25
+
26
+ ```ruby
27
+ msfbase = __FILE__
28
+ while File.symlink?(msfbase)
29
+ msfbase = File.expand_path(File.readlink(msfbase), File.dirname(msfbase))
30
+ end
31
+ inc = File.dirname(msfbase) + '/../../..'
32
+ $:.unshift(inc)
33
+
34
+ require 'rex/zip'
35
+
36
+ # example usage
37
+ zip = Rex::Zip::Archive.new
38
+ zip.add_file("elite.txt", "A" * 1024)
39
+ zip.save_to("lolz.zip")
40
+ ```
41
+
42
+
43
+ ## Development
44
+
45
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
46
+
47
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
48
+
49
+ ## Contributing
50
+
51
+ Bug reports and pull requests are welcome on GitHub at https://github.com/rapid7/rex-zip. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
52
+
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "rex/zip"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,97 @@
1
+ # -*- coding: binary -*-
2
+ #
3
+ # Zip library
4
+ #
5
+ # Written by Joshua J. Drake <jduck [at] metasploit.com>
6
+ #
7
+ # Based on code contributed by bannedit, and the following SPEC:
8
+ # Reference: http://www.pkware.com/documents/casestudies/APPNOTE.TXT
9
+ #
10
+ require 'rex/zip/version'
11
+ require 'zlib'
12
+ require 'rex/text'
13
+
14
+ module Rex
15
+ module Zip
16
+
17
+ # various parts of the structure
18
+ require 'rex/zip/blocks'
19
+
20
+ # an entry in a zip file
21
+ require 'rex/zip/entry'
22
+
23
+ # the archive class
24
+ require 'rex/zip/archive'
25
+
26
+ # a child of Archive, implements Java ARchives for creating java applications
27
+ require 'rex/zip/jar'
28
+
29
+ ZIP_VERSION = 0x14
30
+
31
+ # general purpose bit flag values
32
+ #
33
+ # bit 0
34
+ GPBF_ENCRYPTED = 0x0001
35
+ # bits 1 & 2
36
+ # implode only
37
+ GPBF_IMP_8KDICT = 0x0002
38
+ GPBF_IMP_3SFT = 0x0004
39
+ # deflate only
40
+ GPBF_DEF_MAX = 0x0002
41
+ GPBF_DEF_FAST = 0x0004
42
+ GPBF_DEF_SUPERFAST = 0x0006
43
+ # lzma only
44
+ GPBF_LZMA_EOSUSED = 0x0002
45
+ # bit 3
46
+ GPBF_USE_DATADESC = 0x0008
47
+ # bit 4
48
+ GPBF_DEF_ENHANCED = 0x0010
49
+ # bit 5
50
+ GPBF_COMP_PATHCED = 0x0020
51
+ # bit 6
52
+ GPBF_STRONG_ENC = 0x0040
53
+ # bit 7-10 unused
54
+ # bit 11
55
+ GPBF_STRS_UTF8 = 0x0800
56
+ # bit 12 (reserved)
57
+ # bit 13
58
+ GPBF_DIR_ENCRYPTED = 0x2000
59
+ # bit 14,15 (reserved)
60
+
61
+
62
+ # compression methods
63
+ CM_STORE = 0
64
+ CM_SHRINK = 1
65
+ CM_REDUCE1 = 2
66
+ CM_REDUCE2 = 3
67
+ CM_REDUCE3 = 4
68
+ CM_REDUCE4 = 5
69
+ CM_IMPLODE = 6
70
+ CM_TOKENIZE = 7
71
+ CM_DEFLATE = 8
72
+ CM_DEFLATE64 = 9
73
+ CM_PKWARE_IMPLODE = 10
74
+ # 11 - reserved
75
+ CM_BZIP2 = 12
76
+ # 13 - reserved
77
+ CM_LZMA_EFS = 14
78
+ # 15-17 reserved
79
+ CM_IBM_TERSE = 18
80
+ CM_IBM_LZ77 = 19
81
+ # 20-96 reserved
82
+ CM_WAVPACK = 97
83
+ CM_PPMD_V1R1 = 98
84
+
85
+
86
+ # internal file attributes
87
+ IFA_ASCII = 0x0001
88
+ # bits 2 & 3 are reserved
89
+ IFA_MAINFRAME_MODE = 0x0002 # ??
90
+
91
+
92
+ # external file attributes
93
+ EFA_ISDIR = 0x0001
94
+
95
+ end
96
+ end
97
+
@@ -0,0 +1,130 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Zip
5
+
6
+ #
7
+ # This represents an entire archive.
8
+ #
9
+ class Archive
10
+
11
+ # An array of the Entry objects stored in this Archive.
12
+ attr_reader :entries
13
+
14
+
15
+ def initialize(compmeth=CM_DEFLATE)
16
+ @compmeth = compmeth
17
+ @entries = []
18
+ end
19
+
20
+ #
21
+ # Recursively adds a directory of files into the archive.
22
+ #
23
+ def add_r(dir)
24
+ path = File.dirname(dir)
25
+ Dir[File.join(dir, "**", "**")].each do |file|
26
+ relative = file.sub(/^#{path.chomp('/')}\//, '')
27
+ if File.directory?(file)
28
+ @entries << Entry.new(relative.chomp('/') + '/', '', @compmeth, nil, EFA_ISDIR, nil, nil)
29
+ else
30
+ contents = File.read(file, :mode => 'rb')
31
+ @entries << Entry.new(relative, contents, @compmeth, nil, nil, nil, nil)
32
+ end
33
+ end
34
+ end
35
+
36
+ #
37
+ # Create a new Entry and add it to the archive.
38
+ #
39
+ # If fdata is set, the file is populated with that data
40
+ # from the calling method. If fdata is nil, then the
41
+ # fs is checked for the file. If central_dir_name is set
42
+ # it will be used to spoof the name at the Central Directory
43
+ # at packing time.
44
+ #
45
+ def add_file(fname, fdata=nil, xtra=nil, comment=nil, central_dir_name=nil)
46
+ if (not fdata)
47
+ begin
48
+ st = File.stat(fname)
49
+ rescue
50
+ return nil
51
+ end
52
+
53
+ ts = st.mtime
54
+ if (st.directory?)
55
+ attrs = EFA_ISDIR
56
+ fdata = ''
57
+ unless fname[-1,1] == '/'
58
+ fname += '/'
59
+ end
60
+ else
61
+ f = File.open(fname, 'rb')
62
+ fdata = f.read(f.stat.size)
63
+ f.close
64
+ end
65
+ end
66
+
67
+ @entries << Entry.new(fname, fdata, @compmeth, ts, attrs, xtra, comment, central_dir_name)
68
+ end
69
+
70
+
71
+ def set_comment(comment)
72
+ @comment = comment
73
+ end
74
+
75
+
76
+ #
77
+ # Write the compressed file to +fname+.
78
+ #
79
+ def save_to(fname)
80
+ f = File.open(fname, 'wb')
81
+ f.write(pack)
82
+ f.close
83
+ end
84
+
85
+
86
+ #
87
+ # Compress this archive and return the resulting zip file as a String.
88
+ #
89
+ def pack
90
+ ret = ''
91
+
92
+ # save the offests
93
+ offsets = []
94
+
95
+ # file 1 .. file n
96
+ @entries.each { |ent|
97
+ offsets << ret.length
98
+ ret << ent.pack
99
+ }
100
+
101
+ # archive decryption header (unsupported)
102
+ # archive extra data record (unsupported)
103
+
104
+ # central directory
105
+ cfd_offset = ret.length
106
+ idx = 0
107
+ @entries.each { |ent|
108
+ cfd = CentralDir.new(ent, offsets[idx])
109
+ ret << cfd.pack
110
+ idx += 1
111
+ }
112
+
113
+ # zip64 end of central dir record (unsupported)
114
+ # zip64 end of central dir locator (unsupported)
115
+
116
+ # end of central directory record
117
+ cur_offset = ret.length - cfd_offset
118
+ ret << CentralDirEnd.new(@entries.length, cur_offset, cfd_offset, @comment).pack
119
+
120
+ ret
121
+ end
122
+
123
+ def inspect
124
+ "#<#{self.class} entries = [#{@entries.map{|e| e.name}.join(",")}]>"
125
+ end
126
+
127
+ end
128
+
129
+ end
130
+ end
@@ -0,0 +1,184 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Zip
5
+
6
+
7
+ #
8
+ # This structure holds the following data pertaining to a Zip entry's data.
9
+ #
10
+ # data crc
11
+ # compressed size
12
+ # uncompressed size
13
+ #
14
+ class CompInfo
15
+
16
+ def initialize(crc, compsz, uncompsz)
17
+ @crc, @compsz, @uncompsz = crc, compsz, uncompsz
18
+ end
19
+
20
+ def pack
21
+ [ @crc, @compsz, @uncompsz ].pack('VVV')
22
+ end
23
+
24
+ end
25
+
26
+
27
+ #
28
+ # This structure holds the following data pertaining to a Zip entry.
29
+ #
30
+ # general purpose bit flag
31
+ # compression method
32
+ # modification time
33
+ # modification date
34
+ #
35
+ class CompFlags
36
+
37
+ attr_accessor :compmeth
38
+
39
+ def initialize(gpbf, compmeth, timestamp)
40
+ @gpbf = gpbf
41
+ @compmeth = compmeth
42
+ @mod_time = ((timestamp.hour << 11) | (timestamp.min << 5) | (timestamp.sec))
43
+ @mod_date = (((timestamp.year - 1980) << 9) | (timestamp.mon << 5) | (timestamp.day))
44
+ end
45
+
46
+ def pack
47
+ [ @gpbf, @compmeth, @mod_time, @mod_date ].pack('vvvv')
48
+ end
49
+
50
+ end
51
+
52
+
53
+
54
+ #
55
+ # This structure is sometimes stored after the file data and used
56
+ # instead of the fields within the Local File Header.
57
+ #
58
+ class DataDesc
59
+
60
+ SIGNATURE = 0x8074b50
61
+
62
+ def initialize(compinfo)
63
+ @compinfo = compinfo
64
+ end
65
+
66
+ def pack
67
+ ret = [ SIGNATURE ].pack('V')
68
+ ret << @compinfo.pack
69
+ ret
70
+ end
71
+
72
+ end
73
+
74
+
75
+ #
76
+ # This structure records the compression data and flags about
77
+ # a Zip entry to a file.
78
+ #
79
+ class LocalFileHdr
80
+
81
+ SIGNATURE = 0x4034b50
82
+
83
+ def initialize(entry)
84
+ @entry = entry
85
+ end
86
+
87
+ def pack
88
+ path = @entry.relative_path
89
+
90
+ ret = [ SIGNATURE, ZIP_VERSION ].pack('Vv')
91
+ ret << @entry.flags.pack
92
+ ret << @entry.info.pack
93
+ ret << [ path.length, @entry.xtra.length ].pack('vv')
94
+ ret << path
95
+ ret << @entry.xtra
96
+ ret
97
+ end
98
+
99
+ end
100
+
101
+
102
+ #
103
+ # This structure holds all of the information about a particular Zip Entry
104
+ # as it is contained within the central directory.
105
+ #
106
+ class CentralDir
107
+
108
+ SIGNATURE = 0x2014b50
109
+
110
+ def initialize(entry, offset)
111
+ @entry = entry
112
+ @disknum_start = 0
113
+ @attr_int = 0
114
+ @attr_ext = 0x20
115
+ @hdr_offset = offset
116
+ end
117
+
118
+ def pack
119
+ if @entry.central_dir_name.to_s.strip.empty?
120
+ path = @entry.relative_path
121
+ else
122
+ path = @entry.central_dir_path
123
+ end
124
+
125
+ ret = [ SIGNATURE, ZIP_VERSION ].pack('Vv')
126
+ ret << [ ZIP_VERSION ].pack('v')
127
+ ret << @entry.flags.pack
128
+ ret << @entry.info.pack
129
+ arr = []
130
+ arr << path.length
131
+ arr << @entry.xtra.length
132
+ arr << @entry.comment.length
133
+ arr << @disknum_start
134
+ arr << @attr_int
135
+ arr << @entry.attrs
136
+ arr << @hdr_offset
137
+ ret << arr.pack('vvvvvVV')
138
+ ret << path
139
+ ret << @entry.xtra
140
+ ret << @entry.comment
141
+ # digital signature not supported
142
+ ret
143
+ end
144
+
145
+ end
146
+
147
+
148
+ #
149
+ # This structure is written after the per-entry central directory records to
150
+ # provide information about the archive as a whole.
151
+ #
152
+ class CentralDirEnd
153
+
154
+ SIGNATURE = 0x6054b50
155
+
156
+ def initialize(ncfd, cfdsz, offset, comment=nil)
157
+ @disk_no = 0
158
+ @disk_dir_start = 0
159
+ @ncfd_this_disk = ncfd
160
+ @ncfd_total = ncfd
161
+ @cfd_size = cfdsz
162
+ @start_offset = offset
163
+ @comment = comment
164
+ @comment ||= ''
165
+ end
166
+
167
+
168
+ def pack
169
+ arr = []
170
+ arr << SIGNATURE
171
+ arr << @disk_no
172
+ arr << @disk_dir_start
173
+ arr << @ncfd_this_disk
174
+ arr << @ncfd_total
175
+ arr << @cfd_size
176
+ arr << @start_offset
177
+ arr << @comment.length
178
+ (arr.pack('VvvvvVVv') + @comment)
179
+ end
180
+
181
+ end
182
+
183
+ end
184
+ end