rex-bin_tools 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +1 -0
  3. data.tar.gz.sig +0 -0
  4. data/.gitignore +9 -0
  5. data/.rspec +2 -0
  6. data/.travis.yml +5 -0
  7. data/CODE_OF_CONDUCT.md +52 -0
  8. data/Gemfile +4 -0
  9. data/LICENSE +27 -0
  10. data/README.md +22 -0
  11. data/Rakefile +6 -0
  12. data/bin/console +14 -0
  13. data/bin/msfbinscan +284 -0
  14. data/bin/msfelfscan +120 -0
  15. data/bin/msfmachscan +100 -0
  16. data/bin/msfpescan +184 -0
  17. data/bin/setup +8 -0
  18. data/data/identify.txt +3043 -0
  19. data/lib/rex/assembly/nasm.rb +104 -0
  20. data/lib/rex/bin_tools.rb +13 -0
  21. data/lib/rex/bin_tools/version.rb +5 -0
  22. data/lib/rex/elfparsey.rb +9 -0
  23. data/lib/rex/elfparsey/elf.rb +121 -0
  24. data/lib/rex/elfparsey/elfbase.rb +265 -0
  25. data/lib/rex/elfparsey/exceptions.rb +25 -0
  26. data/lib/rex/elfscan.rb +10 -0
  27. data/lib/rex/elfscan/scanner.rb +226 -0
  28. data/lib/rex/elfscan/search.rb +44 -0
  29. data/lib/rex/image_source.rb +10 -0
  30. data/lib/rex/image_source/disk.rb +58 -0
  31. data/lib/rex/image_source/image_source.rb +48 -0
  32. data/lib/rex/image_source/memory.rb +35 -0
  33. data/lib/rex/machparsey.rb +9 -0
  34. data/lib/rex/machparsey/exceptions.rb +31 -0
  35. data/lib/rex/machparsey/mach.rb +209 -0
  36. data/lib/rex/machparsey/machbase.rb +408 -0
  37. data/lib/rex/machscan.rb +9 -0
  38. data/lib/rex/machscan/scanner.rb +217 -0
  39. data/lib/rex/peparsey.rb +10 -0
  40. data/lib/rex/peparsey/exceptions.rb +30 -0
  41. data/lib/rex/peparsey/pe.rb +210 -0
  42. data/lib/rex/peparsey/pe_memdump.rb +61 -0
  43. data/lib/rex/peparsey/pebase.rb +1662 -0
  44. data/lib/rex/peparsey/section.rb +128 -0
  45. data/lib/rex/pescan.rb +11 -0
  46. data/lib/rex/pescan/analyze.rb +366 -0
  47. data/lib/rex/pescan/scanner.rb +230 -0
  48. data/lib/rex/pescan/search.rb +68 -0
  49. data/rex-bin_tools.gemspec +32 -0
  50. metadata +284 -0
  51. metadata.gz.sig +0 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 787c1726c02358862ab0feaf1fb1f86df29bc2af
4
+ data.tar.gz: 66626707fa1ec982becf43c69959099a6744c9d8
5
+ SHA512:
6
+ metadata.gz: 3910da97774e960cd3d1b89a19b90387dcdb2b69c795c08eafbb998325561cb324213eb48a8af773c5e406a7218633eea8576e92542d2acd2d66b982b981eb81
7
+ data.tar.gz: f021df69244b0ae8334212d564e8a84ad80c134d24289af4d7c2553554e1d2e49b05b2519ab04cd6a0c51e75d818369d61a7c95609f537febffd6cdd8e843f40
@@ -0,0 +1 @@
1
+ ^�,�hj���m�`j��
Binary file
@@ -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,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rex-bin_tools.gemspec
4
+ gemspec
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,22 @@
1
+ # Rex::BinTools
2
+
3
+ Ruby Exploitation(Rex) Library for Binary Manipulation. This suite of tools contains ElfScan,MachScan, PEScan, and BinScan.
4
+ These tools are designed to help you analyze an executable binary and search for particular instruction sets. This is aprticularly
5
+ useful for things like building ROP chains or SEH exploits.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'rex-bin_tools'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install rex-bin_tools
22
+
@@ -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/bin_tools"
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,284 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: binary -*-
3
+
4
+ require 'metasm'
5
+ require 'rex/elfparsey'
6
+ require 'rex/elfscan'
7
+ require 'rex/machparsey'
8
+ require 'rex/machscan'
9
+ require 'rex/peparsey'
10
+ require 'rex/pescan'
11
+ require 'rex/arch/x86'
12
+ require 'optparse'
13
+
14
+ def opt2i(o)
15
+ o.index("0x")==0 ? o.hex : o.to_i
16
+ end
17
+
18
+ opt = OptionParser.new
19
+
20
+ opt.banner = "Usage: #{$PROGRAM_NAME} [mode] <options> [targets]"
21
+ opt.separator('')
22
+ opt.separator('Modes:')
23
+
24
+ worker = nil
25
+ param = {}
26
+ files = []
27
+ mode = ""
28
+
29
+ opt.on('-j', '--jump [regA,regB,regC]', 'Search for jump equivalent instructions [PE|ELF|MACHO]') do |t|
30
+ # take csv of register names (like eax,ebx) and convert
31
+ # them to an array of register numbers
32
+ mode = "jump"
33
+ regnums = t.split(',').collect { |o|
34
+ begin
35
+ Rex::Arch::X86.reg_number(o)
36
+ rescue
37
+ puts "Invalid register \"#{o}\""
38
+ exit(1)
39
+ end
40
+ }
41
+ param['args'] = regnums
42
+ end
43
+
44
+ opt.on('-p', '--poppopret', 'Search for pop+pop+ret combinations [PE|ELF|MACHO]') do |t|
45
+ mode = "pop"
46
+ param['args'] = t
47
+ end
48
+
49
+ opt.on('-r', '--regex [regex]', 'Search for regex match [PE|ELF|MACHO]') do |t|
50
+ mode = "regex"
51
+ param['args'] = t
52
+ end
53
+
54
+ opt.on('-a', '--analyze-address [address]', 'Display the code at the specified address [PE|ELF]') do |t|
55
+ mode = "analyze-address"
56
+ param['args'] = opt2i(t)
57
+ end
58
+
59
+ opt.on('-b', '--analyze-offset [offset]', 'Display the code at the specified offset [PE|ELF]') do |t|
60
+ mode = "analyze-offset"
61
+ param['args'] = opt2i(t)
62
+ end
63
+
64
+ opt.on('-f', '--fingerprint', 'Attempt to identify the packer/compiler [PE]') do |t|
65
+ mode = "fingerprint"
66
+ param['database'] = File.join(File.dirname(msfbase), 'data', 'msfpescan', 'identify.txt')
67
+ end
68
+
69
+ opt.on('-i', '--info', 'Display detailed information about the image [PE]') do |t|
70
+ mode = "info"
71
+ end
72
+
73
+ opt.on('-R', '--ripper [directory]', 'Rip all module resources to disk [PE]') do |t|
74
+ mode = "ripper"
75
+ param['dir'] = t
76
+ end
77
+
78
+ opt.on('--context-map [directory]', 'Generate context-map files [PE]') do |t|
79
+ mode = "context"
80
+ param['dir'] = t
81
+ end
82
+
83
+ opt.separator('')
84
+ opt.separator('Options:')
85
+
86
+ opt.on('-A', '--after [bytes]', 'Number of bytes to show after match (-a/-b) [PE|ELF|MACHO]') do |t|
87
+ param['after'] = opt2i(t)
88
+ end
89
+
90
+ opt.on('-B', '--before [bytes]', 'Number of bytes to show before match (-a/-b) [PE|ELF|MACHO]') do |t|
91
+ param['before'] = opt2i(t)
92
+ end
93
+
94
+ opt.on('-I', '--image-base [address]', 'Specify an alternate ImageBase [PE|ELF|MACHO]') do |t|
95
+ param['imagebase'] = opt2i(t)
96
+ end
97
+
98
+ opt.on('-D', '--disasm', 'Disassemble the bytes at this address [PE|ELF]') do |t|
99
+ param['disasm'] = true
100
+ end
101
+
102
+ opt.on('-F', '--filter-addresses [regex]', 'Filter addresses based on a regular expression [PE]') do |t|
103
+ param['filteraddr'] = t
104
+ end
105
+
106
+ opt.on_tail("-h", "--help", "Show this message") do
107
+ $stderr.puts opt
108
+ exit
109
+ end
110
+
111
+ begin
112
+ opt.parse!
113
+ rescue OptionParser::InvalidOption, OptionParser::MissingArgument
114
+ $stderr.puts "Invalid option, try -h for usage"
115
+ exit(1)
116
+ end
117
+
118
+
119
+ if mode.empty?
120
+ $stderr.puts "A mode must be selected"
121
+ $stderr.puts opt
122
+ exit(1)
123
+ end
124
+
125
+ # check if the file is a directory if it is collect all the entries
126
+ ARGV.each do |file|
127
+
128
+ if(File.directory?(file))
129
+ dir = Dir.open(file)
130
+ dir.entries.each do |ent|
131
+ path = File.join(file, ent)
132
+ next if not File.file?(path)
133
+ files << File.join(path)
134
+ end
135
+ else
136
+ files << file
137
+ end
138
+ end
139
+
140
+ # we need to do some work to figure out the file format
141
+ files.each do |file|
142
+ param['file'] = file
143
+
144
+ bin = Metasm::AutoExe.decode_file(file) if not file.empty?
145
+
146
+ if bin.kind_of?(Metasm::PE)
147
+ case mode
148
+ when "jump"
149
+ worker = Rex::PeScan::Scanner::JmpRegScanner
150
+ when "pop"
151
+ worker = Rex::PeScan::Scanner::PopPopRetScanner
152
+ when "regex"
153
+ worker = Rex::PeScan::Scanner::RegexScanner
154
+ when "analyze-address"
155
+ worker = Rex::PeScan::Search::DumpRVA
156
+ when "analyze-offset"
157
+ worker = Rex::PeScan::Search::DumpOffset
158
+ when "fingerprint"
159
+ worker = Rex::PeScan::Analyze::Fingerprint
160
+ when "info"
161
+ worker = Rex::PeScan::Analyze::Information
162
+ when "ripper"
163
+ worker = Rex::PeScan::Analyze::Ripper
164
+ when "context"
165
+ worker = Rex::PeScan::Analyze::ContextMapDumper
166
+ else
167
+ $stderr.puts("Mode unsupported by file format")
168
+ end
169
+
170
+ pe_klass = Rex::PeParsey::Pe
171
+ begin
172
+ pe = pe_klass.new_from_file(file, true)
173
+ rescue ::Interrupt
174
+ raise $!
175
+ rescue Rex::PeParsey::FileHeaderError
176
+ next if $!.message == "Couldn't find the PE magic!"
177
+ raise $!
178
+ rescue Errno::ENOENT
179
+ $stdout.puts("File does not exist: #{file}")
180
+ next
181
+ rescue ::Rex::PeParsey::SkipError
182
+ next
183
+ rescue ::Exception => e
184
+ $stdout.puts "[#{file}] #{e.class}: #{e}"
185
+ next
186
+ end
187
+
188
+ if (param['imagebase'])
189
+ pe.image_base = param['imagebase'];
190
+ end
191
+
192
+ if not worker
193
+ $stderr.puts("A mode could not be set for this file.")
194
+ next
195
+ end
196
+
197
+ o = worker.new(pe)
198
+ o.scan(param)
199
+
200
+ pe.close
201
+
202
+ elsif bin.kind_of?(Metasm::ELF)
203
+ case mode
204
+ when "jump"
205
+ worker = Rex::ElfScan::Scanner::JmpRegScanner
206
+ when "pop"
207
+ worker = Rex::ElfScan::Scanner::PopPopRetScanner
208
+ when "regex"
209
+ worker = Rex::ElfScan::Scanner::RegexScanner
210
+ when "analyze-address"
211
+ worker = Rex::ElfScan::Search::DumpRVA
212
+ when "analyze-offset"
213
+ worker = Rex::ElfScan::Search::DumpOffset
214
+ else
215
+ $stderr.puts("Mode unsupported by file format")
216
+ end
217
+
218
+ begin
219
+ elf = Rex::ElfParsey::Elf.new_from_file(file, true)
220
+ rescue Rex::ElfParsey::ElfHeaderError
221
+ if $!.message == 'Invalid magic number'
222
+ $stderr.puts("Skipping #{file}: #{$!}")
223
+ next
224
+ end
225
+ raise $!
226
+ rescue Errno::ENOENT
227
+ $stderr.puts("File does not exist: #{file}")
228
+ next
229
+ end
230
+
231
+ if (param['imagebase'])
232
+ elf.base_addr = param['imagebase'];
233
+ end
234
+
235
+ if not worker
236
+ $stderr.puts("A mode could not be set for this file.")
237
+ next
238
+ end
239
+
240
+ o = worker.new(elf)
241
+ o.scan(param)
242
+
243
+ elf.close
244
+
245
+ elsif bin.kind_of?(Metasm::MachO)
246
+ case mode
247
+ when "jump"
248
+ worker = Rex::MachScan::Scanner::JmpRegScanner
249
+ when "pop"
250
+ worker = Rex::MachScan::Scanner::PopPopRetScanner
251
+ when "regex"
252
+ worker = Rex::MachScan::Scanner::RegexScanner
253
+ else
254
+ $stderr.puts("Mode unsupported by file format")
255
+ end
256
+
257
+ begin
258
+ mach = Rex::MachParsey::Mach.new_from_file(file, true)
259
+ o = worker.new(mach)
260
+ o.scan(param)
261
+ mach.close
262
+ rescue Rex::MachParsey::MachHeaderError
263
+ $stderr.puts("File is not a Mach-O binary, trying Fat..\n")
264
+ begin
265
+ fat = Rex::MachParsey::Fat.new_from_file(file, true)
266
+ o = worker.new(fat)
267
+ o.scan(param)
268
+ fat.close
269
+ rescue
270
+ $stderr.puts("Error: " + $!.to_s)
271
+ $stderr.puts("Skipping #{file}")
272
+ end
273
+ rescue Errno::ENOENT
274
+ $stderr.puts("File does not exist: #{file}")
275
+ next
276
+ end
277
+ end
278
+
279
+ if not worker
280
+ $stderr.puts("Unsupported file format")
281
+ $stderr.puts("Skipping #{file}")
282
+ next
283
+ end
284
+ end