Merge remote-tracking branch 'upstream/master' into service_principle_name
commit
0a15e07473
|
@ -5631,19 +5631,19 @@ class DBManager
|
|||
|
||||
# Pull out vulnerabilities that have at least one matching
|
||||
# ref -- many "vulns" are not vulns, just audit information.
|
||||
def find_qualys_asset_vulns(host,wspace,hobj,vuln_refs,&block)
|
||||
def find_qualys_asset_vulns(host,wspace,hobj,vuln_refs,task_id,&block)
|
||||
host.elements.each("VULN_INFO_LIST/VULN_INFO") do |vi|
|
||||
next unless vi.elements["QID"]
|
||||
vi.elements.each("QID") do |qid|
|
||||
next if vuln_refs[qid.text].nil? || vuln_refs[qid.text].empty?
|
||||
handle_qualys(wspace, hobj, nil, nil, qid.text, nil, vuln_refs[qid.text], nil,nil, args[:task])
|
||||
handle_qualys(wspace, hobj, nil, nil, qid.text, nil, vuln_refs[qid.text], nil, nil, task_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Takes QID numbers and finds the discovered services in
|
||||
# a qualys_asset_xml.
|
||||
def find_qualys_asset_ports(i,host,wspace,hobj)
|
||||
def find_qualys_asset_ports(i,host,wspace,hobj,task_id)
|
||||
return unless (i == 82023 || i == 82004)
|
||||
proto = i == 82023 ? 'tcp' : 'udp'
|
||||
qid = host.elements["VULN_INFO_LIST/VULN_INFO/QID[@id='qid_#{i}']"]
|
||||
|
@ -5656,7 +5656,7 @@ class DBManager
|
|||
else
|
||||
name = match[2].strip
|
||||
end
|
||||
handle_qualys(wspace, hobj, match[0].to_s, proto, 0, nil, nil, name, nil, args[:task])
|
||||
handle_qualys(wspace, hobj, match[0].to_s, proto, 0, nil, nil, name, nil, task_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -5700,11 +5700,11 @@ class DBManager
|
|||
end
|
||||
|
||||
# Report open ports.
|
||||
find_qualys_asset_ports(82023,host,wspace,hobj) # TCP
|
||||
find_qualys_asset_ports(82004,host,wspace,hobj) # UDP
|
||||
find_qualys_asset_ports(82023,host,wspace,hobj, args[:task]) # TCP
|
||||
find_qualys_asset_ports(82004,host,wspace,hobj, args[:task]) # UDP
|
||||
|
||||
# Report vulns
|
||||
find_qualys_asset_vulns(host,wspace,hobj,vuln_refs,&block)
|
||||
find_qualys_asset_vulns(host,wspace,hobj,vuln_refs, args[:task],&block)
|
||||
|
||||
end # host
|
||||
|
||||
|
|
|
@ -65,33 +65,41 @@ class Exploit < Msf::Module
|
|||
##
|
||||
#
|
||||
# The various check codes that can be returned from the ``check'' routine.
|
||||
# Please read the following wiki to learn how these codes are used:
|
||||
# https://github.com/rapid7/metasploit-framework/wiki/How-to-write-a-check()-method
|
||||
#
|
||||
##
|
||||
module CheckCode
|
||||
|
||||
#
|
||||
# Can't tell if the target is exploitable or not.
|
||||
# Can't tell if the target is exploitable or not. This is recommended if the module fails to
|
||||
# retrieve enough information from the target machine, such as due to a timeout.
|
||||
#
|
||||
Unknown = [ 'unknown', "Cannot reliably check exploitability."]
|
||||
|
||||
#
|
||||
# The target is safe and is therefore not exploitable.
|
||||
# The target is safe and is therefore not exploitable. This is recommended after the check
|
||||
# fails to trigger the vulnerability, or even detect the service.
|
||||
#
|
||||
Safe = [ 'safe', "The target is not exploitable." ]
|
||||
|
||||
#
|
||||
# The target is running the service in question but may not be
|
||||
# exploitable.
|
||||
# The target is running the service in question, but the check fails to determine whether
|
||||
# the target is vulnerable or not.
|
||||
#
|
||||
Detected = [ 'detected', "The target service is running, but could not be validated." ]
|
||||
|
||||
#
|
||||
# The target appears to be vulnerable.
|
||||
# The target appears to be vulnerable. This is recommended if the vulnerability is determined
|
||||
# based on passive reconnaissance. For example: version, banner grabbing, or having the resource
|
||||
# that's known to be vulnerable.
|
||||
#
|
||||
Appears = [ 'appears', "The target appears to be vulnerable." ]
|
||||
|
||||
#
|
||||
# The target is vulnerable.
|
||||
# The target is vulnerable. Only used if the check is able to actually take advantage of the
|
||||
# bug, and obtain hard evidence. For example: executing a command on the target machine, and
|
||||
# retrieve the output.
|
||||
#
|
||||
Vulnerable = [ 'vulnerable', "The target is vulnerable." ]
|
||||
|
||||
|
|
|
@ -15,20 +15,106 @@ module LDAP
|
|||
|
||||
DEFAULT_PAGE_SIZE = 500
|
||||
|
||||
ERROR_CODE_TO_CONSTANT =
|
||||
{
|
||||
0x0b => 'LDAP_ADMIN_LIMIT_EXCEEDED',
|
||||
0x47 => 'LDAP_AFFECTS_MULTIPLE_DSAS',
|
||||
0x24 => 'LDAP_ALIAS_DEREF_PROBLEM',
|
||||
0x21 => 'LDAP_ALIAS_PROBLEM',
|
||||
0x44 => 'LDAP_ALREADY_EXISTS',
|
||||
0x14 => 'LDAP_ATTRIBUTE_OR_VALUE_EXISTS',
|
||||
0x07 => 'LDAP_AUTH_METHOD_NOT_SUPPORTED',
|
||||
0x56 => 'LDAP_AUTH_UNKNOWN',
|
||||
0x33 => 'LDAP_BUSY',
|
||||
0x60 => 'LDAP_CLIENT_LOOP',
|
||||
0x05 => 'LDAP_COMPARE_FALSE',
|
||||
0x06 => 'LDAP_COMPARE_TRUE',
|
||||
0x0d => 'LDAP_CONFIDENTIALITY_REQUIRED',
|
||||
0x5b => 'LDAP_CONNECT_ERROR',
|
||||
0x13 => 'LDAP_CONSTRAINT_VIOLATION',
|
||||
0x5d => 'LDAP_CONTROL_NOT_FOUND',
|
||||
0x54 => 'LDAP_DECODING_ERROR',
|
||||
0x53 => 'LDAP_ENCODING_ERROR',
|
||||
0x57 => 'LDAP_FILTER_ERROR',
|
||||
0x30 => 'LDAP_INAPPROPRIATE_AUTH',
|
||||
0x12 => 'LDAP_INAPPROPRIATE_MATCHING',
|
||||
0x32 => 'LDAP_INSUFFICIENT_RIGHTS',
|
||||
0x31 => 'LDAP_INVALID_CREDENTIALS',
|
||||
0x22 => 'LDAP_INVALID_DN_SYNTAX',
|
||||
0x15 => 'LDAP_INVALID_SYNTAX',
|
||||
0x23 => 'LDAP_IS_LEAF',
|
||||
0x52 => 'LDAP_LOCAL_ERROR',
|
||||
0x36 => 'LDAP_LOOP_DETECT',
|
||||
0x5f => 'LDAP_MORE_RESULTS_TO_RETURN',
|
||||
0x40 => 'LDAP_NAMING_VIOLATION',
|
||||
0x5a => 'LDAP_NO_MEMORY',
|
||||
0x45 => 'LDAP_NO_OBJECT_CLASS_MODS',
|
||||
0x5e => 'LDAP_NO_RESULTS_RETURNED',
|
||||
0x10 => 'LDAP_NO_SUCH_ATTRIBUTE',
|
||||
0x20 => 'LDAP_NO_SUCH_OBJECT',
|
||||
0x42 => 'LDAP_NOT_ALLOWED_ON_NONLEAF',
|
||||
0x43 => 'LDAP_NOT_ALLOWED_ON_RDN',
|
||||
0x5c => 'LDAP_NOT_SUPPORTED',
|
||||
0x41 => 'LDAP_OBJECT_CLASS_VIOLATION',
|
||||
0x01 => 'LDAP_OPERATIONS_ERROR',
|
||||
0x50 => 'LDAP_OTHER',
|
||||
0x59 => 'LDAP_PARAM_ERROR',
|
||||
0x09 => 'LDAP_PARTIAL_RESULTS',
|
||||
0x02 => 'LDAP_PROTOCOL_ERROR',
|
||||
0x0a => 'LDAP_REFERRAL',
|
||||
0x61 => 'LDAP_REFERRAL_LIMIT_EXCEEDED',
|
||||
0x09 => 'LDAP_REFERRAL_V2',
|
||||
0x46 => 'LDAP_RESULTS_TOO_LARGE',
|
||||
0x51 => 'LDAP_SERVER_DOWN',
|
||||
0x04 => 'LDAP_SIZELIMIT_EXCEEDED',
|
||||
0x08 => 'LDAP_STRONG_AUTH_REQUIRED',
|
||||
0x00 => 'LDAP_SUCCESS',
|
||||
0x03 => 'LDAP_TIMELIMIT_EXCEEDED',
|
||||
0x55 => 'LDAP_TIMEOUT',
|
||||
0x34 => 'LDAP_UNAVAILABLE',
|
||||
0x0c => 'LDAP_UNAVAILABLE_CRIT_EXTENSION',
|
||||
0x11 => 'LDAP_UNDEFINED_TYPE',
|
||||
0x35 => 'LDAP_UNWILLING_TO_PERFORM',
|
||||
0x58 => 'LDAP_USER_CANCELLED',
|
||||
0x4c => 'LDAP_VIRTUAL_LIST_VIEW_ERROR'
|
||||
}
|
||||
|
||||
def initialize(info = {})
|
||||
super
|
||||
register_options(
|
||||
[
|
||||
OptString.new('DOMAIN', [false, 'The domain to query.', nil]),
|
||||
OptInt.new('MAX_SEARCH', [true, 'Maximum values to retrieve, 0 for all.', 50]),
|
||||
OptString.new('FIELDS', [true, 'FIELDS to retrieve.', nil]),
|
||||
OptString.new('FILTER', [true, 'Search filter.', nil])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
# Performs an ldap query
|
||||
#
|
||||
# @param [String] LDAP search filter
|
||||
# @param [Integer] Maximum results
|
||||
# @param [Array] String array containing attributes to retrieve
|
||||
# @return [Hash] Entries found
|
||||
def query(filter, max_results, fields)
|
||||
default_naming_context = get_default_naming_context
|
||||
default_naming_context = datastore['DOMAIN']
|
||||
default_naming_context ||= get_default_naming_context
|
||||
vprint_status("Default Naming Context #{default_naming_context}")
|
||||
if load_extapi
|
||||
domain_name = default_naming_context.gsub("DC=","").gsub(",",".")
|
||||
vprint_status(domain_name)
|
||||
return session.extapi.adsi.domain_query(domain_name, filter, max_results, DEFAULT_PAGE_SIZE, fields)
|
||||
return session.extapi.adsi.domain_query(default_naming_context, filter, max_results, DEFAULT_PAGE_SIZE, fields)
|
||||
else
|
||||
unless default_naming_context.include? "DC="
|
||||
raise RuntimeError.new("DOMAIN must be specified as distinguished name e.g. DC=test,DC=com")
|
||||
end
|
||||
|
||||
bind_default_ldap_server(max_results) do |session_handle|
|
||||
return query_ldap(session_handle, default_naming_context, 2, filter, fields)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Performs a query to retrieve the default naming context
|
||||
#
|
||||
def get_default_naming_context
|
||||
bind_default_ldap_server(1) do |session_handle|
|
||||
print_status("Querying default naming context")
|
||||
|
@ -114,7 +200,7 @@ module LDAP
|
|||
values = get_values_from_ber(ber, field)
|
||||
|
||||
values_result = ""
|
||||
values_result = values.join(',') unless values.nil?
|
||||
values_result = values.join(',') if values
|
||||
vprint_status("Values #{values}")
|
||||
|
||||
field_results << values_result
|
||||
|
@ -165,7 +251,7 @@ module LDAP
|
|||
def get_values_from_ber(ber_data, field)
|
||||
field_offset = ber_data.index(field)
|
||||
|
||||
if field_offset.nil?
|
||||
unless field_offset
|
||||
vprint_status("Field not found in BER: #{field}")
|
||||
return nil
|
||||
end
|
||||
|
@ -221,7 +307,6 @@ module LDAP
|
|||
vprint_status ("Initializing LDAP connection.")
|
||||
init_result = wldap32.ldap_sslinitA("\x00\x00\x00\x00", 389, 0)
|
||||
session_handle = init_result['return']
|
||||
|
||||
if session_handle == 0
|
||||
raise RuntimeError.new("Unable to initialize ldap server: #{init_result["ErrorMessage"]}")
|
||||
end
|
||||
|
@ -235,11 +320,10 @@ module LDAP
|
|||
bind_result = wldap32.ldap_bind_sA(session_handle, nil, nil, LDAP_AUTH_NEGOTIATE)
|
||||
|
||||
bind = bind_result['return']
|
||||
|
||||
unless bind == Error::SUCCESS
|
||||
unless bind == 0
|
||||
vprint_status("Unbinding from LDAP service")
|
||||
wldap32.ldap_unbind(session_handle)
|
||||
raise RuntimeError.new("Unable to bind to ldap server: #{bind}")
|
||||
raise RuntimeError.new("Unable to bind to ldap server: #{ERROR_CODE_TO_CONSTANT[bind]}")
|
||||
end
|
||||
|
||||
if (block_given?)
|
||||
|
|
|
@ -154,11 +154,15 @@ module Rex::Socket::SslTcpServer
|
|||
ctx.cert = cert
|
||||
ctx.options = 0
|
||||
|
||||
# enable/disable the SSL/TLS-level compression
|
||||
if params.ssl_compression
|
||||
ctx.options &= ~OpenSSL::SSL::OP_NO_COMPRESSION
|
||||
else
|
||||
ctx.options |= OpenSSL::SSL::OP_NO_COMPRESSION
|
||||
|
||||
# Older versions of OpenSSL do not export the OP_NO_COMPRESSION symbol
|
||||
if defined?(OpenSSL::SSL::OP_NO_COMPRESSION)
|
||||
# enable/disable the SSL/TLS-level compression
|
||||
if params.ssl_compression
|
||||
ctx.options &= ~OpenSSL::SSL::OP_NO_COMPRESSION
|
||||
else
|
||||
ctx.options |= OpenSSL::SSL::OP_NO_COMPRESSION
|
||||
end
|
||||
end
|
||||
|
||||
ctx.session_id_context = Rex::Text.rand_text(16)
|
||||
|
|
|
@ -49,7 +49,6 @@ class Metasploit3 < Msf::Post
|
|||
))
|
||||
|
||||
register_options([
|
||||
OptInt.new('MAX_SEARCH', [true, 'Maximum values to retrieve, 0 for all.', 50]),
|
||||
OptBool.new('STORE_LOOT', [true, 'Store file in loot.', false]),
|
||||
OptBool.new('STORE_DB', [true, 'Store file in DB (performance hit resolving IPs).', false]),
|
||||
OptString.new('FIELDS', [true, 'FIELDS to retrieve.', 'dNSHostName,distinguishedName,description,operatingSystem,operatingSystemServicePack']),
|
||||
|
@ -63,9 +62,7 @@ class Metasploit3 < Msf::Post
|
|||
max_search = datastore['MAX_SEARCH']
|
||||
q = query(search_filter, max_search, fields)
|
||||
|
||||
if q.nil? or q[:results].empty?
|
||||
return
|
||||
end
|
||||
return if q.nil? or q[:results].empty?
|
||||
|
||||
# Results table holds raw string data
|
||||
results_table = Rex::Ui::Text::Table.new(
|
||||
|
|
Loading…
Reference in New Issue