Skip to content

Commit cefec81

Browse files
kernelsmithzeroSteiner
authored andcommitted
move plugins/http to plugins/request
1 parent 2e8e350 commit cefec81

File tree

1 file changed

+96
-65
lines changed

1 file changed

+96
-65
lines changed

plugins/httpr.rb renamed to plugins/request.rb

Lines changed: 96 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,68 @@
22

33
module Msf
44

5-
class Plugin::HTTPRequests < Msf::Plugin
5+
class Plugin::Requests < Msf::Plugin
66

77
class ConsoleCommandDispatcher
88
include Msf::Ui::Console::CommandDispatcher
99

1010
def name
11-
'HTTP Requests'
11+
'Request'
1212
end
1313

1414
def commands
1515
{
16-
'httpr' => 'Make an HTTP request'
16+
'request' => 'Make a request of the specified type',
1717
}
1818
end
1919

20-
def parse_args(args)
21-
help_line = 'Usage: httpr [options] uri'
20+
def types
21+
# dynamically figure out what types are supported based on parse_args_*
22+
parse_methods = self.public_methods.select {|m| m.to_s =~ /^parse_args_/}
23+
parse_methods.collect {|m| m.to_s.split('_').slice(2..-1).join('_')}
24+
end
25+
26+
def cmd_request(*args)
27+
# grab and validate the first arg as type, which will affect how the
28+
# remaining args are parsed
29+
type = args.shift
30+
# short circuit the whole deal if they need help
31+
return help if (!type || type =~ /^-?-h(?:elp)?$/)
32+
type.downcase!
33+
opts, opt_parser = parse_args(type, args)
34+
if opts && opt_parser
35+
if opts[:output_file]
36+
begin
37+
opts[:output_file] = File.new(opts[:output_file], 'w')
38+
rescue ::Errno::EACCES, Errno::EISDIR, Errno::ENOTDIR
39+
return help(opt_parser, 'Failed to open the specified file for output')
40+
end
41+
end
42+
handler_method = "handle_request_#{type}".to_sym
43+
if self.respond_to?(handler_method)
44+
# call the appropriate request handler
45+
self.send(handler_method, opts, opt_parser)
46+
else
47+
help(opt_parser, "No request handler found for type (#{type.to_s}).")
48+
end
49+
else
50+
help(opt_parser, "No valid options provided for request #{type}")
51+
end
52+
end
53+
54+
def parse_args(type, args)
55+
type.downcase!
56+
#print_line "type is #{type}"
57+
parse_method = "parse_args_#{type}".to_sym
58+
if self.respond_to?(parse_method)
59+
self.send(parse_method, args, type)
60+
else
61+
print_line('Unrecognized type.')
62+
help
63+
end
64+
end
65+
66+
def parse_args_http(args = [], type = 'http')
2267
opt_parser = Rex::Parser::Arguments.new(
2368
'-0' => [ false, 'Use HTTP 1.0' ],
2469
'-1' => [ false, 'Use TLSv1 (SSL)' ],
@@ -37,15 +82,10 @@ def parse_args(args)
3782
)
3883

3984
options = {
40-
:auth_password => nil,
41-
:auth_username => nil,
42-
:headers => { },
85+
:headers => {},
4386
:print_body => true,
4487
:print_headers => false,
45-
:method => nil,
46-
:output_file => nil,
4788
:ssl_version => 'Auto',
48-
:uri => nil,
4989
:user_agent => Rex::Proto::Http::Client::DefaultUserAgent,
5090
:version => '1.1'
5191
}
@@ -68,11 +108,9 @@ def parse_args(args)
68108
when '-G'
69109
options[:method] = 'GET'
70110
when '-h'
71-
print_line(help_line)
72-
print_line(opt_parser.usage)
73-
return
111+
return help(opt_parser, "Usage: request #{type} [options] uri")
74112
when '-H'
75-
name, _, value = val.partition(':')
113+
name, _, value = val.split(':')
76114
options[:headers][name] = value.strip
77115
when '-i'
78116
options[:print_headers] = true
@@ -83,54 +121,24 @@ def parse_args(args)
83121
when '-o'
84122
options[:output_file] = File.expand_path(val)
85123
when '-u'
86-
val = val.partition(':')
87-
options[:auth_username] = val[0]
88-
options[:auth_password] = val[2]
124+
options[:auth_username] = val
125+
when '-p'
126+
options[:auth_password] = val
89127
when '-X'
90128
options[:method] = val
91129
else
92130
options[:uri] = val
93131
end
94132
end
95-
96-
if options[:uri].nil?
97-
print_line(help_line)
98-
print_line(opt_parser.usage)
99-
return
133+
unless options[:uri]
134+
return help(opt_parser, "Usage: request #{type} [options] uri")
100135
end
101-
102136
options[:method] ||= 'GET'
103137
options[:uri] = URI(options[:uri])
104-
options
105-
end
106-
107-
def output_line(opts, line)
108-
if opts[:output_file].nil?
109-
if line[-2..-1] == "\r\n"
110-
print_line(line[0..-3])
111-
elsif line[-1] == "\n"
112-
print_line(line[0..-2])
113-
else
114-
print_line(line)
115-
end
116-
else
117-
opts[:output_file].write(line)
118-
end
138+
[options, opt_parser]
119139
end
120140

121-
def cmd_httpr(*args)
122-
opts = parse_args(args)
123-
return unless opts
124-
125-
unless opts[:output_file].nil?
126-
begin
127-
opts[:output_file] = File.new(opts[:output_file], 'w')
128-
rescue ::Errno::EACCES, Errno::EISDIR, Errno::ENOTDIR
129-
print_error('Failed to open the specified file for output')
130-
return
131-
end
132-
end
133-
141+
def handle_request_http(opts, opt_parser)
134142
uri = opts[:uri]
135143
http_client = Rex::Proto::Http::Client.new(
136144
uri.host,
@@ -140,8 +148,8 @@ def cmd_httpr(*args)
140148
opts[:ssl_version]
141149
)
142150

143-
unless opts[:auth_username].nil?
144-
auth_str = opts[:auth_username].to_s + ':' + opts[:auth_password].to_s
151+
if opts[:auth_username]
152+
auth_str = opts[:auth_username] + ':' + opts[:auth_password]
145153
auth_str = 'Basic ' + Rex::Text.encode_base64(auth_str)
146154
opts[:headers]['Authorization'] = auth_str
147155
end
@@ -150,7 +158,7 @@ def cmd_httpr(*args)
150158

151159
begin
152160
http_client.connect
153-
request = http_client.request_cgi(
161+
req = http_client.request_cgi(
154162
'agent' => opts[:user_agent],
155163
'data' => opts[:data],
156164
'headers' => opts[:headers],
@@ -162,7 +170,7 @@ def cmd_httpr(*args)
162170
'version' => opts[:version]
163171
)
164172

165-
response = http_client.send_recv(request)
173+
response = http_client.send_recv(req)
166174
rescue ::OpenSSL::SSL::SSLError
167175
print_error('Encountered an SSL error')
168176
rescue ::Errno::ECONNRESET => ex
@@ -176,8 +184,8 @@ def cmd_httpr(*args)
176184
end
177185

178186
unless response
179-
opts[:output_file].close unless opts[:output_file].nil?
180-
return
187+
opts[:output_file].close if opts[:output_file]
188+
return nil
181189
end
182190

183191
if opts[:print_headers]
@@ -186,11 +194,35 @@ def cmd_httpr(*args)
186194
end
187195

188196
output_line(opts, response.body) if opts[:print_body]
189-
unless opts[:output_file].nil?
197+
if opts[:output_file]
190198
print_status("Wrote #{opts[:output_file].tell} bytes to #{opts[:output_file].path}")
191199
opts[:output_file].close
192200
end
193201
end
202+
203+
def output_line(opts, line)
204+
if opts[:output_file].nil?
205+
if line[-2..-1] == "\r\n"
206+
print_line(line[0..-3])
207+
elsif line[-1] == "\n"
208+
print_line(line[0..-2])
209+
else
210+
print_line(line)
211+
end
212+
else
213+
opts[:output_file].write(line)
214+
end
215+
end
216+
217+
def help(opt_parser = nil, msg = 'Usage: request type [options]')
218+
print_line(msg)
219+
if opt_parser
220+
print_line(opt_parser.usage)
221+
else
222+
print_line("Valid types are: #{types.join(', ')}")
223+
end
224+
end
225+
194226
end
195227

196228
def initialize(framework, opts)
@@ -199,18 +231,17 @@ def initialize(framework, opts)
199231
end
200232

201233
def cleanup
202-
remove_console_dispatcher('HTTP Requests')
234+
remove_console_dispatcher('Request')
203235
end
204236

205237
def name
206-
'HTTP Requests'
238+
'Request'
207239
end
208240

209241
def desc
210-
'Make HTTP requests from within Metasploit.'
242+
'Make requests from within Metasploit using various protocols.'
211243
end
212244

213-
protected
214-
end
245+
end # end class
215246

216-
end
247+
end # end module

0 commit comments

Comments
 (0)