Class: Ronin::Listener::DNS::Server

Inherits:
Async::DNS::Server
  • Object
show all
Defined in:
lib/ronin/listener/dns/server.rb

Overview

A simple DNS server for receiving exfiltrated DNS queries.

Constant Summary collapse

RECORD_TYPES =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Mapping of Resolv resource classes to Symbols.

{
  Resolv::DNS::Resource::IN::A     => :A,
  Resolv::DNS::Resource::IN::AAAA  => :AAAA,
  Resolv::DNS::Resource::IN::ANY   => :ANY,
  Resolv::DNS::Resource::IN::CNAME => :CNAME,
  Resolv::DNS::Resource::IN::HINFO => :HINFO,
  Resolv::DNS::Resource::IN::LOC   => :LOC,
  Resolv::DNS::Resource::IN::MINFO => :MINFO,
  Resolv::DNS::Resource::IN::MX    => :MX,
  Resolv::DNS::Resource::IN::NS    => :NS,
  Resolv::DNS::Resource::IN::PTR   => :PTR,
  Resolv::DNS::Resource::IN::SOA   => :SOA,
  Resolv::DNS::Resource::IN::SRV   => :SRV,
  Resolv::DNS::Resource::IN::TXT   => :TXT,
  Resolv::DNS::Resource::IN::WKS   => :WKS
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(domain, host: '0.0.0.0', port: 53) {|query| ... } ⇒ Server

Initializes the DNS listener server.

Parameters:

  • domain (String, Regexp)

    The domain to accept queries for (ex: example.com).

  • host (String) (defaults to: '0.0.0.0')

    The interface to listen on.

  • port (Integer) (defaults to: 53)

    The local port to listen on.

Yields:

  • (query)

    The given block will be passed each received query.

Yield Parameters:

  • query (Query)

    The received DNS query object.

Raises:

  • (ArgumentError)

    No callback block was given.



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/ronin/listener/dns/server.rb', line 76

def initialize(domain, host: '0.0.0.0',
                       port: 53,
                       &callback)
  unless callback
    raise(ArgumentError,"#{self.class}#initialize requires a callback block")
  end

  @domain = domain
  @suffix = ".#{domain}"

  @host = host
  @port = port

  super([[:udp, host, port]])

  @callback = callback
end

Instance Attribute Details

#callbackProc (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

The callback which will be passed all received queries.

Returns:

  • (Proc)


53
54
55
# File 'lib/ronin/listener/dns/server.rb', line 53

def callback
  @callback
end

#domainString (readonly)

The domain to accept queries for.

Returns:

  • (String)


36
37
38
# File 'lib/ronin/listener/dns/server.rb', line 36

def domain
  @domain
end

#hostString (readonly)

The host the server will listen on.

Returns:

  • (String)


41
42
43
# File 'lib/ronin/listener/dns/server.rb', line 41

def host
  @host
end

#portInteger (readonly)

The port the server will listen on.

Returns:

  • (Integer)


46
47
48
# File 'lib/ronin/listener/dns/server.rb', line 46

def port
  @port
end

Instance Method Details

#process(label, resource_class, transaction) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Processes an incoming query.

Parameters:

  • label (String)

    The queried domain label (ex: www.example.com).

  • resource_class (Class<Resolv::DNS::Resource>)

    The resource class (ex: Resolv::DNS::Resource::IN::A).

  • transaction (Async::DNS::Transaction)

    The DNS transaction object.



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/ronin/listener/dns/server.rb', line 128

def process(label,resource_class,transaction)
  # filter out queries for all other domains
  if label.end_with?(@suffix)
    # map the `Resolv::DNS::Resource::IN` class to a Symbol
    query_type = RECORD_TYPES.fetch(resource_class)

    # extract the remote address
    source_addr = transaction.options[:remote_address]

    @callback.call(Query.new(query_type,label,source_addr))
  end

  # always respond with an error to prevent DNS caching
  transaction.fail!(:NXDomain)
end