Module: Msf::Exploit::Remote::DNS::Server

Includes:
Common, SocketServer
Defined in:
lib/msf/core/exploit/remote/dns/server.rb

Constant Summary

Constants included from Common

Common::MATCH_HOSTNAME, Common::Packet

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from SocketServer

#_determine_server_comm, #cleanup, #exploit, #on_client_data, #primer, #regenerate_payload, #srvhost, #srvport, #via_string_for_ip

Instance Attribute Details

#serviceObject

:nodoc:


38
39
40
# File 'lib/msf/core/exploit/remote/dns/server.rb', line 38

def service
  @service
end

Instance Method Details

#add_static_hosts(entries = datastore['STATIC_ENTRIES'], type = 'A') ⇒ Array

Process static entries

Parameters:

  • entries (String) (defaults to: datastore['STATIC_ENTRIES'])

    Filename or String containing static entries

  • type (String) (defaults to: 'A')

    Type of record for which to add static entries

Returns:

  • (Array)

    List of static entries in the cache


47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/msf/core/exploit/remote/dns/server.rb', line 47

def add_static_hosts(entries = datastore['STATIC_ENTRIES'], type = 'A')
  return if entries.nil? or entries.empty?
  if File.file?(File.expand_path(entries))
    data = File.read(File.expand_path(entries)).split("\n")
  else
    data = entries.split(';')
  end
  data.each do |entry|
    next if entry.gsub(/\s/,'').empty?
    addr, names = entry.split(' ', 2)
    names.split.each do |name|
      name << '.' unless name[-1] == '.' or name == '*'
      service.cache.add_static(name, addr, type)
    end
  end
  service.cache.records.select {|r,e| e == 0}
end

#flush_cache(static = false) ⇒ Object

Flush cache entries

Parameters:

  • static (TrueClass, FalseClass) (defaults to: false)

    flush static hosts


77
78
79
80
81
# File 'lib/msf/core/exploit/remote/dns/server.rb', line 77

def flush_cache(static = false)
  self.service.cache.stop(true)
  flush_static_hosts if static
  self.service.cache.start
end

#flush_static_hostsObject

Flush all static entries


68
69
70
71
72
# File 'lib/msf/core/exploit/remote/dns/server.rb', line 68

def flush_static_hosts
  data.cache.records.select {|r,e| e == 0}.each do |flush|
    data.cache.delete(flush)
  end
end

#initialize(info = {}) ⇒ Object

Initializes an exploit module that serves DNS requests


18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/msf/core/exploit/remote/dns/server.rb', line 18

def initialize(info = {})
  super

  register_options(
    [
      OptPort.new('SRVPORT', [true, 'The local port to listen on.', 53]),
      OptString.new('STATIC_ENTRIES', [ false, "DNS domain search list (hosts file or space/semicolon separate entries)"]),
      OptBool.new('DISABLE_RESOLVER', [ false, "Disable DNS request forwarding", false]),
      OptBool.new('DISABLE_NS_CACHE', [ false, "Disable DNS response caching", false])
    ], Exploit::Remote::DNS::Server
  )

  register_advanced_options(
    [
      OptBool.new('DnsServerUdp', [true, "Serve UDP DNS requests", true]),
      OptBool.new('DnsServerTcp', [true, "Serve TCP DNS requests", false])
    ], Exploit::Remote::DNS::Server
  )
end

#on_dispatch_request(cli, data) ⇒ Object

Handle incoming requests Override this method in modules to take flow control


87
88
89
# File 'lib/msf/core/exploit/remote/dns/server.rb', line 87

def on_dispatch_request(cli, data)
  service.default_dispatch_request(cli,data)
end

#on_send_response(cli, data) ⇒ Object

Handle incoming requests Override this method in modules to take flow control


95
96
97
# File 'lib/msf/core/exploit/remote/dns/server.rb', line 95

def on_send_response(cli, data)
  cli.write(data)
end

#reset_serviceObject

Resets the DNS server


146
147
148
149
# File 'lib/msf/core/exploit/remote/dns/server.rb', line 146

def reset_service
  stop_service(true)
  start_service
end

#start_serviceObject

Starts the server


102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/msf/core/exploit/remote/dns/server.rb', line 102

def start_service
  begin

    comm = _determine_server_comm
    self.service = Rex::ServiceManager.start(
      Rex::Proto::DNS::Server,
      datastore['SRVHOST'],
      datastore['SRVPORT'],
      datastore['DnsServerUdp'],
      datastore['DnsServerTcp'],
      (use_resolver? ? setup_resolver : false),
      comm,
      {'Msf' => framework, 'MsfExploit' => self}
    )

    self.service.dispatch_request_proc = Proc.new do |cli, data|
      on_dispatch_request(cli,data)
    end
    self.service.send_response_proc = Proc.new do |cli, data|
      on_send_response(cli,data)
    end

    add_static_hosts
    self.service.start(!datastore['DISABLE_NS_CACHE'])

  rescue ::Errno::EACCES => e
    raise Rex::BindFailed.new(e.message)
  end
end

#stop_service(destroy = false) ⇒ Object

Stops the server

Parameters:

  • destroy (TrueClass, FalseClass) (defaults to: false)

    Dereference the server object


135
136
137
138
139
140
141
# File 'lib/msf/core/exploit/remote/dns/server.rb', line 135

def stop_service(destroy = false)
  Rex::ServiceManager.stop_service(self.service) if self.service
  if destroy
    @dns_resolver = nil if @dns_resolver
    self.service = nil if self.service
  end
end

#use_resolver?Boolean

Determines if resolver is available and configured for use

Returns:

  • (Boolean)

154
155
156
# File 'lib/msf/core/exploit/remote/dns/server.rb', line 154

def use_resolver?
  !datastore['DISABLE_RESOLVER'] and self.respond_to?(:setup_resolver)
end