Class: Rex::Proto::DNS::UpstreamRule

Inherits:
Object
  • Object
show all
Defined in:
lib/rex/proto/dns/upstream_rule.rb

Overview

This represents a configuration rule for how names should be resolved. It matches a single wildcard which acts as a matching condition and maps it to 0 or more resolvers to use for lookups.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(wildcard: '*', resolvers: [], comm: nil) ⇒ UpstreamRule

Returns a new instance of UpstreamRule.

Parameters:

  • wildcard (String) (defaults to: '*')

    The wildcard pattern to use for conditionally matching hostnames.

  • resolvers (Array) (defaults to: [])

    The resolvers to use when this rule is applied.

  • comm (Msf::Session::Comm) (defaults to: nil)

    The communication channel to use when creating network connections.



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/rex/proto/dns/upstream_rule.rb', line 19

def initialize(wildcard: '*', resolvers: [], comm: nil)
  ::ArgumentError.new("Invalid wildcard text: #{wildcard}") unless self.class.valid_wildcard?(wildcard)
  @wildcard = wildcard
  socket_options = {}
  socket_options['Comm'] = comm unless comm.nil?
  @resolvers = resolvers.map do |resolver|
    if resolver.is_a?(String) && !Rex::Socket.is_ip_addr?(resolver)
      resolver = resolver.downcase.to_sym
    end

    case resolver
    when UpstreamResolver
      resolver
    when UpstreamResolver::Type::BLACK_HOLE
      UpstreamResolver.create_black_hole
    when UpstreamResolver::Type::STATIC
      UpstreamResolver.create_static
    when UpstreamResolver::Type::SYSTEM
      UpstreamResolver.create_system
    else
      if Rex::Socket.is_ip_addr?(resolver)
        UpstreamResolver.create_dns_server(resolver, socket_options: socket_options)
      else
        raise ::ArgumentError.new("Invalid upstream DNS resolver: #{resolver}")
      end
    end
  end
  @comm = comm
end

Instance Attribute Details

#commObject (readonly)

Returns the value of attribute comm.



15
16
17
# File 'lib/rex/proto/dns/upstream_rule.rb', line 15

def comm
  @comm
end

#resolversObject (readonly)

Returns the value of attribute resolvers.



15
16
17
# File 'lib/rex/proto/dns/upstream_rule.rb', line 15

def resolvers
  @resolvers
end

#wildcardObject (readonly)

Returns the value of attribute wildcard.



15
16
17
# File 'lib/rex/proto/dns/upstream_rule.rb', line 15

def wildcard
  @wildcard
end

Class Method Details

.spell_check_resolver(resolver) ⇒ Object

Perform a spell check on resolver to suggest corrections.

Parameters:

  • resolver (String)

    The resolver string to check.



68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/rex/proto/dns/upstream_rule.rb', line 68

def self.spell_check_resolver(resolver)
  return nil if Rex::Socket.is_ip_addr?(resolver)

  suggestions = DidYouMean::SpellChecker.new(dictionary: [
    UpstreamResolver::Type::BLACK_HOLE,
    UpstreamResolver::Type::STATIC,
    UpstreamResolver::Type::SYSTEM
  ]).correct(resolver).map(&:to_s)
  return nil if suggestions.empty?

  suggestions
end

.valid_resolver?(resolver) ⇒ Boolean

Check whether or not the defined resolver is valid.

Parameters:

  • resolver (String)

    The resolver string to check.

Returns:

  • (Boolean)


53
54
55
56
57
58
59
60
61
62
# File 'lib/rex/proto/dns/upstream_rule.rb', line 53

def self.valid_resolver?(resolver)
  return true if Rex::Socket.is_ip_addr?(resolver)

  resolver = resolver.downcase.to_sym
  [
    UpstreamResolver::Type::BLACK_HOLE,
    UpstreamResolver::Type::STATIC,
    UpstreamResolver::Type::SYSTEM
  ].include?(resolver)
end

.valid_wildcard?(wildcard) ⇒ Boolean

Check whether or not the defined wildcard is a valid pattern.

Parameters:

  • wildcard (String)

    The wildcard text to check.

Returns:

  • (Boolean)


85
86
87
# File 'lib/rex/proto/dns/upstream_rule.rb', line 85

def self.valid_wildcard?(wildcard)
  wildcard == '*' || wildcard =~ /^(\*\.)?([a-z\d][a-z\d-]*[a-z\d]\.)+[a-z]+$/
end

Instance Method Details

#eql?(other) ⇒ Boolean Also known as: ==

Returns:

  • (Boolean)


109
110
111
112
113
114
115
# File 'lib/rex/proto/dns/upstream_rule.rb', line 109

def eql?(other)
  return false unless other.is_a?(self.class)
  return false unless other.wildcard == wildcard
  return false unless other.resolvers == resolvers
  return false unless other.comm == comm
  true
end

#matches_all?Boolean

Check whether or not the currently configured wildcard pattern will match all names.

Returns:

  • (Boolean)


92
93
94
# File 'lib/rex/proto/dns/upstream_rule.rb', line 92

def matches_all?
  wildcard == '*'
end

#matches_name?(name) ⇒ Boolean

Check whether or not the specified name matches the currently configured wildcard pattern.

Returns:

  • (Boolean)


99
100
101
102
103
104
105
106
107
# File 'lib/rex/proto/dns/upstream_rule.rb', line 99

def matches_name?(name)
  if matches_all?
    true
  elsif wildcard.start_with?('*.')
    name.downcase.end_with?(wildcard[1..-1].downcase)
  else
    name.casecmp?(wildcard)
  end
end