CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/tools/exploit/egghunter.rb
Views: 1904
1
#!/usr/bin/env ruby
2
3
##
4
# This module requires Metasploit: https://metasploit.com/download
5
# Current source: https://github.com/rapid7/metasploit-framework
6
##
7
begin
8
msfbase = __FILE__
9
while File.symlink?(msfbase)
10
msfbase = File.expand_path(File.readlink(msfbase), File.dirname(msfbase))
11
end
12
$:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', '..', 'lib')))
13
require 'msfenv'
14
require 'rex'
15
require 'optparse'
16
require 'rex/exploitation/egghunter'
17
18
module Egghunter
19
class OptsConsole
20
def self.parse(args)
21
options = {}
22
parser = OptionParser.new do |opt|
23
opt.banner = "Usage: #{__FILE__} [options]\nExample: #{__FILE__} -f python -e W00T"
24
opt.separator ''
25
opt.separator 'Specific options:'
26
27
opt.on('-f', '--format <String>', "See --list-formats for a list of supported output formats") do |v|
28
options[:format] = v
29
end
30
31
opt.on('-b', '--badchars <String>', "(Optional) Bad characters to avoid for the egg") do |v|
32
options[:badchars] = v
33
end
34
35
opt.on('-e', '--egg <String>', "The egg (Please give 4 bytes)") do |v|
36
options[:eggtag] = v
37
end
38
39
opt.on('-p', '--platform <String>', "(Optional) Platform") do |v|
40
options[:platform] = v
41
end
42
43
opt.on('--startreg <String>', "(Optional) The starting register") do |v|
44
# Do not change this key. This should matching the one in Rex::Exploitation::Egghunter
45
options[:startreg] = v
46
end
47
48
opt.on('--forward', "(Optional) To search forward") do |v|
49
# Do not change this key. This should matching the one in Rex::Exploitation::Egghunter
50
options[:searchforward] = true
51
end
52
53
opt.on('--depreg <String>', "(Optional) The DEP register") do |v|
54
# Do not change this key. This should matching the one in Rex::Exploitation::Egghunter
55
options[:depreg] = v
56
end
57
58
opt.on('--depdest <String>', "(Optional) The DEP destination") do |v|
59
# Do not change this key. This should matching the one in Rex::Exploitation::Egghunter
60
options[:depdest] = v
61
end
62
63
opt.on('--depsize <Integer>', "(Optional) The DEP size") do |v|
64
# Do not change this key. This should matching the one in Rex::Exploitation::Egghunter
65
options[:depsize] = v
66
end
67
68
opt.on('--depmethod <String>', "(Optional) The DEP method to use (virtualprotect/virtualalloc/copy/copy_size)") do |v|
69
# Do not change this key. This should matching the one in Rex::Exploitation::Egghunter
70
options[:depmethod] = v
71
end
72
73
opt.on('-a', '--arch <String>', "(Optional) Architecture") do |v|
74
# Although this is an option, this is currently useless because we don't have x64 egghunters
75
options[:arch] = v
76
end
77
78
opt.on('--list-formats', "List all supported output formats") do
79
options[:list_formats] = true
80
end
81
82
opt.on('-v', '--var-name <name>', String, '(Optional) Specify a custom variable name to use for certain output formats') do |v|
83
options[:var_name] = v
84
end
85
86
opt.on_tail('-h', '--help', 'Show this message') do
87
$stdout.puts opt
88
exit
89
end
90
end
91
92
parser.parse!(args)
93
94
if options.empty?
95
raise OptionParser::MissingArgument, 'No options set, try -h for usage'
96
elsif options[:format].blank? && !options[:list_formats]
97
raise OptionParser::MissingArgument, '-f is required'
98
elsif options[:eggtag].blank? && !options[:list_formats]
99
raise OptionParser::MissingArgument, '-e is required'
100
elsif options[:format] && !::Msf::Simple::Buffer.transform_formats.include?(options[:format])
101
raise OptionParser::InvalidOption, "#{options[:format]} is not a valid format"
102
elsif options[:depsize] && options[:depsize] !~ /^\d+$/
103
raise OptionParser::InvalidOption, "--depsize must be a Integer"
104
end
105
106
options[:badchars] = '' unless options[:badchars]
107
options[:platform] = 'windows' unless options[:platform]
108
options[:arch] = ARCH_X86 unless options[:arch]
109
options[:var_name] = 'buf' unless options[:var_name]
110
111
options
112
end
113
end
114
115
class Driver
116
def initialize
117
begin
118
@opts = OptsConsole.parse(ARGV)
119
rescue OptionParser::ParseError => e
120
$stderr.puts "[x] #{e.message}"
121
exit
122
end
123
end
124
125
def run
126
# list_formats should check first
127
if @opts[:list_formats]
128
list_formats
129
return
130
end
131
132
egghunter = Rex::Exploitation::Egghunter.new(@opts[:platform], @opts[:arch])
133
raw_code = egghunter.hunter_stub('', @opts[:badchars], @opts)
134
output_stream = $stdout
135
output_stream.binmode
136
output_stream.write ::Msf::Simple::Buffer.transform(raw_code, @opts[:format], @opts[:var_name])
137
$stderr.puts
138
end
139
140
private
141
142
def list_formats
143
$stderr.puts "[*] Supported output formats:"
144
$stderr.puts ::Msf::Simple::Buffer.transform_formats.join(", ")
145
end
146
147
end
148
end
149
150
151
if __FILE__ == $PROGRAM_NAME
152
driver = Egghunter::Driver.new
153
begin
154
driver.run
155
rescue ::Exception => e
156
elog(e)
157
$stderr.puts "[x] #{e.class}: #{e.message}"
158
$stderr.puts "[*] If necessary, please refer to framework.log for more details."
159
end
160
end
161
rescue SignalException => e
162
puts("Aborted! #{e}")
163
end
164
165