Skip to content

Commit f8dfaae

Browse files
committed
Guard FQDN lookup logic a bit more
Use DNS first, then fail back to LDAP
1 parent 61a0981 commit f8dfaae

File tree

2 files changed

+64
-42
lines changed

2 files changed

+64
-42
lines changed

lib/rex/proto/ms_dnsp.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def get
5959
end
6060

6161
def set(v)
62-
raise TypeError, 'must be an IPv4 address' unless Rex::Socket.is_ipv4?(v)
62+
raise TypeError, 'must be an IPv4 address' unless Rex::Socket.is_ipv4?(v)
6363

6464
self.data = Rex::Socket.addr_aton(v)
6565
end

modules/auxiliary/gather/ldap_esc_vulnerable_cert_finder.rb

Lines changed: 63 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -539,28 +539,30 @@ def find_enrollable_vuln_certificate_templates
539539
next if enroll_sids.empty?
540540

541541
ca_server_fqdn = ca_server[:dnshostname][0].to_s.downcase
542-
ca_server_ip_address = get_ip_addresses_by_fqdn(ca_server_fqdn)&.first
543-
544-
if ca_server_ip_address
545-
service = report_service({
546-
host: ca_server_ip_address,
547-
port: 445,
548-
proto: 'tcp',
549-
name: 'AD CS',
550-
info: "AD CS CA name: #{ca_server[:name][0]}"
551-
})
552-
553-
report_note({
554-
data: ca_server[:dn][0].to_s,
555-
service: service,
556-
host: ca_server_ip_address,
557-
ntype: 'windows.ad.cs.ca.dn'
558-
})
559-
560-
report_host({
561-
host: ca_server_ip_address,
562-
name: ca_server_fqdn
563-
})
542+
unless ca_server_fqdn.blank?
543+
ca_server_ip_address = get_ip_addresses_by_fqdn(ca_server_fqdn)&.first
544+
545+
if ca_server_ip_address
546+
service = report_service({
547+
host: ca_server_ip_address,
548+
port: 445,
549+
proto: 'tcp',
550+
name: 'AD CS',
551+
info: "AD CS CA name: #{ca_server[:name][0]}"
552+
})
553+
554+
report_note({
555+
data: ca_server[:dn][0].to_s,
556+
service: service,
557+
host: ca_server_ip_address,
558+
ntype: 'windows.ad.cs.ca.dn'
559+
})
560+
561+
report_host({
562+
host: ca_server_ip_address,
563+
name: ca_server_fqdn
564+
})
565+
end
564566
end
565567

566568
ca_server_key = ca_server_fqdn.to_sym
@@ -606,7 +608,7 @@ def print_vulnerable_cert_info
606608
vuln_certificate_details.each do |key, hash|
607609
techniques = hash[:techniques].dup
608610
techniques.delete('ESC3_TEMPLATE_2') unless any_esc3t1 # don't report ESC3_TEMPLATE_2 if there are no instances of ESC3
609-
next if techniques.empty?
611+
next if techniques.empty? || !db
610612

611613
techniques.each do |vuln|
612614
next if vuln == 'ESC3_TEMPLATE_2'
@@ -624,23 +626,27 @@ def print_vulnerable_cert_info
624626
info: "AD CS CA name: #{ca_server[:name]}"
625627
})
626628

627-
vuln = report_vuln(
628-
host: ca_server[:ip_address],
629-
port: 445,
630-
proto: 'tcp',
631-
sname: 'AD CS',
632-
name: "#{vuln} - #{key}",
633-
info: info,
634-
refs: REFERENCES[vuln],
635-
service: service
636-
)
629+
if ca_server[:ip_address].present?
630+
vuln = report_vuln(
631+
host: ca_server[:ip_address],
632+
port: 445,
633+
proto: 'tcp',
634+
sname: 'AD CS',
635+
name: "#{vuln} - #{key}",
636+
info: info,
637+
refs: REFERENCES[vuln],
638+
service: service
639+
)
640+
else
641+
vuln = nil
642+
end
637643

638644
report_note({
639645
data: hash[:dn],
640646
service: service,
641647
host: ca_fqdn.to_s,
642648
ntype: 'windows.ad.cs.ca.template.dn',
643-
vuln_id: vuln.id
649+
vuln_id: vuln&.id
644650
})
645651
end
646652
end
@@ -660,9 +666,9 @@ def print_vulnerable_cert_info
660666
end
661667
end
662668

663-
if hash[:write_enabled_sids]
669+
if hash[:write_sids]
664670
print_status(' Certificate Template Write-Enabled SIDs:')
665-
hash[:write_enabled_sids].each do |sid|
671+
hash[:write_sids].each do |sid|
666672
print_status(" * #{highlight_sid(sid)}")
667673
end
668674
end
@@ -744,13 +750,29 @@ def get_object_by_sid(object_sid)
744750
def get_ip_addresses_by_fqdn(host_fqdn)
745751
return @fqdns[host_fqdn] if @fqdns.key?(host_fqdn)
746752

753+
vprint_status("Resolving addresses for #{host_fqdn} via DNS.")
754+
begin
755+
ip_addresses = Rex::Socket.getaddresses(host_fqdn)
756+
rescue ::SocketError
757+
print_warning("No IP addresses were found for #{host_fqdn} via DNS.")
758+
else
759+
@fqdns[host_fqdn] = ip_addresses
760+
vprint_status("Found #{ip_addresses.length} IP address#{ip_addresses.length > 1 ? 'es' : ''} via DNS.")
761+
return ip_addresses
762+
end
763+
747764
vprint_status("Looking up DNS records for #{host_fqdn} in LDAP.")
748765
hostname, _, domain = host_fqdn.partition('.')
749-
results = query_ldap_server(
750-
"(&(objectClass=dnsNode)(DC=#{ldap_escape_filter(hostname)}))",
751-
%w[dnsRecord],
752-
base_prefix: "DC=#{ldap_escape_filter(domain)},CN=MicrosoftDNS,DC=DomainDnsZones"
753-
)
766+
begin
767+
results = query_ldap_server(
768+
"(&(objectClass=dnsNode)(DC=#{ldap_escape_filter(hostname)}))",
769+
%w[dnsRecord],
770+
base_prefix: "DC=#{ldap_escape_filter(domain)},CN=MicrosoftDNS,DC=DomainDnsZones"
771+
)
772+
rescue Msf::Auxiliary::Failed
773+
print_error('Encountered an error while querying LDAP for DNS records.')
774+
@fqdns[host_fqdn] = nil
775+
end
754776
return nil if results.blank?
755777

756778
ip_addresses = []

0 commit comments

Comments
 (0)