rex-bin_tools 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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