Use unless

bug/bundler_fix
Meatballs 2014-05-19 10:41:01 +01:00
parent bf52c0b888
commit e59f104195
No known key found for this signature in database
GPG Key ID: 5380EAF01F2F8B38
1 changed files with 80 additions and 64 deletions

View File

@ -3,7 +3,6 @@
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'rex/proto/http'
require 'msf/core'
class Metasploit3 < Msf::Auxiliary
@ -30,143 +29,160 @@ class Metasploit3 < Msf::Auxiliary
register_options(
[
OptString.new('VERB', [true, "Verb for auth bypass testing", "HEAD"]),
OptString.new('URLFILE', [true, "SAP ICM Paths File", "sap_icm_paths.txt"])
OptPath.new('URLFILE', [true, "SAP ICM Paths File",
File.join(Msf::Config.data_directory, 'wordlists', 'sap_icm_paths.txt')])
], self.class)
end
# Base Structure of module borrowed from jboss_vulnscan
def run_host(ip)
# If URLFILE is set empty, obviously the user made a silly mistake
if datastore['URLFILE'].empty?
print_error("Please specify a URLFILE")
return
end
# Initialize the actual URLFILE path
if datastore['URLFILE'] == "sap_icm_paths.txt"
url_file = "#{Msf::Config.data_directory}/wordlists/#{datastore['URLFILE']}"
else
# Not the default sap_icm_paths file
url_file = datastore['URLFILE']
end
# If URLFILE path doesn't exist, no point to continue the rest of the script
if not File.exists?(url_file)
print_error("Required URL list #{url_file} was not found")
return
end
res = send_request_cgi(
res = send_request_cgi(
{
'uri' => "/" + Rex::Text.rand_text_alpha(12),
'method' => 'GET',
'ctype' => 'text/plain',
}, 20)
})
if res
print_status("Note: Please note these URLs may or may not be of interest based on server configuration")
@info = []
if not res.headers['Server'].nil?
if res.headers['Server']
@info << res.headers['Server']
print_status("#{rhost}:#{rport} Server responded with the following Server Header: #{@info[0]}")
else
print_status("#{rhost}:#{rport} Server responded with a blank or missing Server Header")
end
if (res.body and /class="note">(.*)code:(.*)</i.match(res.body) )
if (res.body && /class="note">(.*)code:(.*)</i.match(res.body) )
print_error("#{rhost}:#{rport} SAP ICM error message: #{$2}")
end
# Load URLs
urls_to_check = []
File.open(url_file) do |f|
urls_to_check = check_urlprefixes
File.open(datastore['URLFILE']) do |f|
f.each_line do |line|
urls_to_check.push line
end
end
print_status("#{rhost}:#{rport} Beginning URL check")
@valid_urls = ''
urls_to_check.each do |url|
check_url(url.strip)
end
# check custom URLs
check_urlprefixes
else
print_error("#{rhost}:#{rport} No response received")
end
if @valid_urls.length > 0
l = store_loot(
'sap.icm.urls',
"text/plain",
datastore['RHOST'],
@valid_urls,
"icm_urls.txt", "SAP ICM Urls"
)
print_line
print_good("Stored urls as loot: #{l}") if l
end
end
def check_url(url)
full_url = write_url(url)
res = send_request_cgi({
'uri' => url,
'uri' => normalize_uri(url),
'method' => 'GET',
'ctype' => 'text/plain',
}, 20)
})
if (res)
if not @info.include?(res.headers['Server']) and not res.headers['Server'].nil?
print_good("New server header seen [#{res.headers['Server']}]")
@info << res.headers['Server'] #Add To seen server headers
if res.headers['Server']
unless @info.include?(res.headers['Server'])
print_good("New server header seen [#{res.headers['Server']}]")
@info << res.headers['Server'] #Add To seen server headers
end
end
case
when res.code == 200
print_good("#{rhost}:#{rport} #{url} - does not require authentication (200) (length: #{res.headers['Content-Length']})")
when res.code == 403
print_good("#{rhost}:#{rport} #{url} - restricted (403)")
when res.code == 401
print_good("#{rhost}:#{rport} #{url} - requires authentication (401): #{res.headers['WWW-Authenticate']}")
case res.code
when 200
print_good("#{full_url} - does not require authentication (#{res.code})")
@valid_urls << full_url << "\n"
when 403
print_status("#{full_url} - restricted (#{res.code})")
when 401
print_status("#{full_url} - requires authentication (#{res.code}): #{res.headers['WWW-Authenticate']}")
# Attempt verb tampering bypass
bypass_auth(url)
when res.code == 404
when 404
# Do not return by default, only display in verbose mode
vprint_status("#{rhost}:#{rport} #{url.strip} - not found (404)")
when res.code == 500
print_good("#{rhost}:#{rport} #{url} - produced a server error (500)")
when res.code == 301, res.code == 302
print_good("#{rhost}:#{rport} #{url} - redirected (#{res.code}) to #{res.headers['Location']} (not following)")
vprint_status("#{full_url} - not found (#{res.code})")
when 400,500
print_status("#{full_url} - produced a server error (#{res.code})")
when 301, 302
print_good("#{full_url} - redirected (#{res.code}) to #{res.redirection} (not following)")
@valid_urls << full_url << "\n"
when 307
vprint_status("#{full_url} - redirected (#{res.code}) to #{res.redirection} (not following)")
else
vprint_status("#{rhost}:#{rport} - unhandle response code #{res.code}")
print_error("#{full_url} - unhandled response code #{res.code}")
@valid_urls << full_url << "\n"
end
else
print_status("#{rhost}:#{rport} #{url} - not found (No Response code Received)")
vprint_status("#{full_url} - not found (No Repsonse code Received)")
end
end
def write_url(path)
if datastore['SSL']
protocol = 'https://'
else
protocol = 'http://'
end
"#{protocol}#{rhost}:#{rport}#{path}"
end
def bypass_auth(url)
print_status("#{rhost}:#{rport} Check for verb tampering (#{datastore['VERB']})")
full_url = write_url(url)
vprint_status("#{full_url} Check for verb tampering (#{datastore['VERB']})")
res = send_request_raw({
'uri' => url,
'uri' => normalize_uri(url),
'method' => datastore['VERB'],
'version' => '1.0' # 1.1 makes the head request wait on timeout for some reason
}, 20)
})
if (res and res.code == 200)
print_good("#{rhost}:#{rport} Got authentication bypass via HTTP verb tampering (length: #{res.headers['Content-Length']})")
if (res && res.code == 200)
print_good("#{full_url} Got authentication bypass via HTTP verb tampering")
@valid_urls << full_url << "\n"
else
print_status("#{rhost}:#{rport} Could not get authentication bypass via HTTP verb tampering")
vprint_status("#{rhost}:#{rport} Could not get authentication bypass via HTTP verb tampering")
end
end
# "/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) -> this disclose custom URLs that are also checked for authentication
def check_urlprefixes
# "/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)
# -> this disclose custom URLs that are also checked for authentication
urls = []
res = send_request_cgi({
'uri' => "/sap/public/icf_info/urlprefix",
'method' => 'GET',
'ctype' => 'text/plain',
}, 20)
if (res and res.code == 200)
})
if (res && res.code == 200)
res.body.each_line do |line|
if line =~ /PREFIX=/
url_enc = line.sub(/^PREFIX=/, '')
# Remove CASE and VHOST
url_enc = url_enc.sub(/&CASE=.*/, '')
url_dec = URI.unescape(url_enc).sub(/;/, '')
check_url(url_dec.strip)
urls << url_dec.strip
end
end
else
print_error("#{rhost}:#{rport} Could not retrieve urlprefixes")
end
urls
end
end