Skip to content

Commit c39d6e1

Browse files
committed
Land rapid7#4819, Normalize HTTP LoginScanner modules
2 parents 885469c + c60e258 commit c39d6e1

26 files changed

+313
-176
lines changed

lib/metasploit/framework/login_scanner/axis2.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def attempt_login(credential)
2020
host, port, {'Msf' => framework, 'MsfExploit' => framework_module}, ssl, ssl_version, proxies
2121
)
2222

23-
http_client = config_client(http_client)
23+
configure_http_client(http_client)
2424

2525
result_opts = {
2626
credential: credential,

lib/metasploit/framework/login_scanner/buffalo.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ def attempt_login(credential)
3535
end
3636
begin
3737
cli = Rex::Proto::Http::Client.new(host, port, {'Msf' => framework, 'MsfExploit' => framework_module}, ssl, ssl_version)
38+
configure_http_client(cli)
3839
cli.connect
3940
req = cli.request_cgi({
4041
'method'=>'POST',

lib/metasploit/framework/login_scanner/chef_webui.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ def check_setup
6363
# @return [Rex::Proto::Http::Response] The HTTP response
6464
def send_request(opts)
6565
cli = Rex::Proto::Http::Client.new(host, port, {'Msf' => framework, 'MsfExploit' => self}, ssl, ssl_version, proxies)
66+
configure_http_client(cli)
6667
cli.connect
6768
req = cli.request_raw(opts)
6869
res = cli.send_recv(req)

lib/metasploit/framework/login_scanner/glassfish.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ def check_setup
6262
# @return [Rex::Proto::Http::Response] The HTTP response
6363
def send_request(opts)
6464
cli = Rex::Proto::Http::Client.new(host, port, {'Msf' => framework, 'MsfExploit' => framework_module}, ssl, ssl_version, proxies)
65+
configure_http_client(cli)
6566
cli.connect
6667
req = cli.request_raw(opts)
6768
res = cli.send_recv(req)

lib/metasploit/framework/login_scanner/http.rb

Lines changed: 163 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,122 @@ class HTTP
3737
# @return [String] the Virtual Host name for the target Web Server
3838
attr_accessor :vhost
3939

40+
# @!attribute evade_uri_encode_mode
41+
# @return [String] The type of URI encoding to use
42+
attr_accessor :evade_uri_encode_mode
43+
44+
# @!attribute evade_uri_full_url
45+
# @return [Boolean] Whether to use the full URL for all HTTP requests
46+
attr_accessor :evade_uri_full_url
47+
48+
# @!attribute evade_pad_method_uri_count
49+
# @return [Fixnum] How many whitespace characters to use between the method and uri
50+
attr_accessor :evade_pad_method_uri_count
51+
52+
# @!attribute evade_pad_uri_version_count
53+
# @return [Fixnum] How many whitespace characters to use between the uri and version
54+
attr_accessor :evade_pad_uri_version_count
55+
56+
# @!attribute evade_pad_method_uri_type
57+
# @return [String] What type of whitespace to use between the method and uri
58+
attr_accessor :evade_pad_method_uri_type
59+
60+
# @!attribute evade_pad_uri_version_type
61+
# @return [String] What type of whitespace to use between the uri and version
62+
attr_accessor :evade_pad_uri_version_type
63+
64+
# @!attribute evade_method_random_valid
65+
# @return [Boolean] Whether to use a random, but valid, HTTP method for request
66+
attr_accessor :evade_method_random_valid
67+
68+
# @!attribute evade_method_random_invalid
69+
# @return [Boolean] Whether to use a random invalid, HTTP method for request
70+
attr_accessor :evade_method_random_invalid
71+
72+
# @!attribute evade_method_random_case
73+
# @return [Boolean] Whether to use random casing for the HTTP method
74+
attr_accessor :evade_method_random_case
75+
76+
# @!attribute evade_uri_dir_self_reference
77+
# @return [Boolean] Whether to insert self-referential directories into the uri
78+
attr_accessor :evade_uri_dir_self_reference
79+
80+
# @!attribute evade_uri_dir_fake_relative
81+
# @return [Boolean] Whether to insert fake relative directories into the uri
82+
attr_accessor :evade_uri_dir_fake_relative
83+
84+
# @!attribute evade_uri_use_backslashes
85+
# @return [Boolean] Whether to use back slashes instead of forward slashes in the uri
86+
attr_accessor :evade_uri_use_backslashes
87+
88+
# @!attribute evade_pad_fake_headers
89+
# @return [Boolean] Whether to insert random, fake headers into the HTTP request
90+
attr_accessor :evade_pad_fake_headers
91+
92+
# @!attribute evade_pad_fake_headers_count
93+
# @return [Fixnum] How many fake headers to insert into the HTTP request
94+
attr_accessor :evade_pad_fake_headers_count
95+
96+
# @!attribute evade_pad_get_params
97+
# @return [Boolean] Whether to insert random, fake query string variables into the request
98+
attr_accessor :evade_pad_get_params
99+
100+
# @!attribute evade_pad_get_params_count
101+
# @return [Fixnum] How many fake query string variables to insert into the request
102+
attr_accessor :evade_pad_get_params_count
103+
104+
# @!attribute evade_pad_post_params
105+
# @return [Boolean] Whether to insert random, fake post variables into the request
106+
attr_accessor :evade_pad_post_params
107+
108+
# @!attribute evade_pad_post_params_count
109+
# @return [Fixnum] How many fake post variables to insert into the request
110+
attr_accessor :evade_pad_post_params_count
111+
112+
# @!attribute evade_uri_fake_end
113+
# @return [Boolean] Whether to add a fake end of URI (eg: /%20HTTP/1.0/../../)
114+
attr_accessor :evade_uri_fake_end
115+
116+
# @!attribute evade_uri_fake_params_start
117+
# @return [Boolean] Whether to add a fake start of params to the URI (eg: /%3fa=b/../)
118+
attr_accessor :evade_uri_fake_params_start
119+
120+
# @!attribute evade_header_folding
121+
# @return [Boolean] Whether to enable folding of HTTP headers
122+
attr_accessor :evade_header_folding
123+
124+
# @!attribute ntlm_use_ntlmv2_session
125+
# @return [Boolean] Whether to activate the 'Negotiate NTLM2 key' flag, forcing the use of a NTLMv2_session
126+
attr_accessor :ntlm_use_ntlmv2_session
127+
128+
# @!attribute ntlm_use_ntlmv2
129+
# @return [Boolean] Whether to use NTLMv2 instead of NTLM2_session when 'Negotiate NTLM2' is enabled
130+
attr_accessor :ntlm_use_ntlmv2
131+
132+
# @!attribute ntlm_send_lm
133+
# @return [Boolean] Whether to always send the LANMAN response (except when NTLMv2_session is specified)
134+
attr_accessor :ntlm_send_lm
135+
136+
# @!attribute ntlm_send_ntlm
137+
# @return [Boolean] Whether to activate the 'Negotiate NTLM key' flag, indicating the use of NTLM responses
138+
attr_accessor :ntlm_send_ntlm
139+
140+
# @!attribute ntlm_send_spn
141+
# @return [Boolean] Whether to send an avp of type SPN in the NTLMv2 client blob.
142+
attr_accessor :ntlm_send_spn
143+
144+
# @!attribute ntlm_use_lm_key
145+
# @return [Boolean] Activate the 'Negotiate Lan Manager Key' flag, using the LM key when the LM response is sent
146+
attr_accessor :ntlm_use_lm_key
147+
148+
# @!attribute ntlm_domain
149+
# @return [String] The NTLM domain to use during authentication
150+
attr_accessor :ntlm_domain
151+
152+
# @!attribute digest_auth_iis
153+
# @return [Boolean] Whether to conform to IIS digest authentication mode.
154+
attr_accessor :digest_auth_iis
155+
40156

41157
validates :uri, presence: true, length: { minimum: 1 }
42158

@@ -99,7 +215,7 @@ def attempt_login(credential)
99215
proxies, credential.public, credential.private
100216
)
101217

102-
http_client = config_client(http_client)
218+
configure_http_client(http_client)
103219

104220
if credential.realm
105221
http_client.set_config('domain' => credential.realm)
@@ -127,12 +243,53 @@ def attempt_login(credential)
127243

128244
private
129245

130-
def config_client(client)
131-
client.set_config(
132-
'vhost' => vhost || host,
133-
'agent' => user_agent
246+
# This method is responsible for mapping the caller's datastore options to the
247+
# Rex::Proto::Http::Client configuration parameters.
248+
def configure_http_client(http_client)
249+
http_client.set_config(
250+
'vhost' => vhost || host,
251+
'agent' => user_agent
134252
)
135-
client
253+
254+
possible_params = {
255+
'uri_encode_mode' => evade_uri_encode_mode,
256+
'uri_full_url' => evade_uri_full_url,
257+
'pad_method_uri_count' => evade_pad_method_uri_count,
258+
'pad_uri_version_count' => evade_pad_uri_version_count,
259+
'pad_method_uri_type' => evade_pad_method_uri_type,
260+
'pad_uri_version_type' => evade_pad_uri_version_type,
261+
'method_random_valid' => evade_method_random_valid,
262+
'method_random_invalid' => evade_method_random_invalid,
263+
'method_random_case' => evade_method_random_case,
264+
'uri_dir_self_reference' => evade_uri_dir_self_reference,
265+
'uri_dir_fake_relative' => evade_uri_dir_fake_relative,
266+
'uri_use_backslashes' => evade_uri_use_backslashes,
267+
'pad_fake_headers' => evade_pad_fake_headers,
268+
'pad_fake_headers_count' => evade_pad_fake_headers_count,
269+
'pad_get_params' => evade_pad_get_params,
270+
'pad_get_params_count' => evade_pad_get_params_count,
271+
'pad_post_params' => evade_pad_post_params,
272+
'pad_post_params_count' => evade_pad_post_params_count,
273+
'uri_fake_end' => evade_uri_fake_end,
274+
'uri_fake_params_start' => evade_uri_fake_params_start,
275+
'header_folding' => evade_header_folding,
276+
'usentlm2_session' => ntlm_use_ntlmv2_session,
277+
'use_ntlmv2' => ntlm_use_ntlmv2,
278+
'send_lm' => ntlm_send_lm,
279+
'send_ntlm' => ntlm_send_ntlm,
280+
'SendSPN' => ntlm_send_spn,
281+
'UseLMKey' => ntlm_use_lm_key,
282+
'domain' => ntlm_domain,
283+
'DigestAuthIIS' => digest_auth_iis
284+
}
285+
286+
# Set the parameter only if it is not nil
287+
possible_params.each_pair do |k,v|
288+
next if v.nil?
289+
http_client.set_config(k => v)
290+
end
291+
292+
http_client
136293
end
137294

138295
# This method sets the sane defaults for things

lib/metasploit/framework/login_scanner/ipboard.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ def attempt_login(credential)
1212
http_client = Rex::Proto::Http::Client.new(
1313
host, port, {'Msf' => framework, 'MsfExploit' => framework_module}, ssl, ssl_version, proxies
1414
)
15-
16-
http_client = config_client(http_client)
15+
configure_http_client(http_client)
1716

1817
result_opts = {
1918
credential: credential,

lib/metasploit/framework/login_scanner/jenkins.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ def attempt_login(credential)
3434
end
3535
begin
3636
cli = Rex::Proto::Http::Client.new(host, port, {'Msf' => framework, 'MsfExploit' => framework_module}, ssl, ssl_version, proxies)
37+
configure_http_client(cli)
3738
cli.connect
3839
req = cli.request_cgi({
3940
'method'=>'POST',

lib/metasploit/framework/login_scanner/mybook_live.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ def attempt_login(credential)
3636
cred = Rex::Text.uri_encode(credential.private)
3737
body = "data%5BLogin%5D%5Bowner_name%5D=admin&data%5BLogin%5D%5Bowner_passwd%5D=#{cred}"
3838
cli = Rex::Proto::Http::Client.new(host, port, {'Msf' => framework, 'MsfExploit' => framework_module}, ssl, ssl_version)
39+
configure_http_client(cli)
3940
cli.connect
4041
req = cli.request_cgi(
4142
'method' => method,

lib/metasploit/framework/login_scanner/smh.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ def attempt_login(credential)
3434

3535
begin
3636
cli = Rex::Proto::Http::Client.new(host, port, {'Msf' => framework, 'MsfExploit' => framework_module}, ssl, ssl_version, proxies)
37+
configure_http_client(cli)
3738
cli.connect
3839
req = cli.request_cgi(req_opts)
3940
res = cli.send_recv(req)

lib/metasploit/framework/login_scanner/wordpress_rpc.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ def attempt_login(credential)
1212
http_client = Rex::Proto::Http::Client.new(
1313
host, port, {'Msf' => framework, 'MsfExploit' => framework_module}, ssl, ssl_version, proxies
1414
)
15+
configure_http_client(http_client)
1516

1617
result_opts = {
1718
credential: credential,

0 commit comments

Comments
 (0)