Skip to content

Commit 25c72d4

Browse files
committed
Handle some edge cases in report filtering
1 parent f3719b8 commit 25c72d4

File tree

1 file changed

+38
-18
lines changed

1 file changed

+38
-18
lines changed

modules/auxiliary/gather/ldap_esc_vulnerable_cert_finder.rb

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -707,17 +707,41 @@ def find_enrollable_vuln_certificate_templates
707707
end
708708
end
709709

710+
def reporting_split_techniques(template)
711+
# these techniques are special in the sense that the exploit steps involve a different user performing the request
712+
# meaning that whether or not we can issue them is irrelevant
713+
enroll_by_proxy = %w[ESC9 ESC10 ESC16]
714+
# technically ESC15 might be patched and we can't fingerprint that status but we live it in the "vulnerable" category
715+
716+
# when we have the registry values, we can tell the vulnerabilities for certain
717+
if @registry_values.present?
718+
potentially_vulnerable = []
719+
vulnerable = template[:techniques].dup
720+
else
721+
potentially_vulnerable = template[:techniques] & enroll_by_proxy
722+
vulnerable = template[:techniques] - potentially_vulnerable
723+
end
724+
725+
if datastore['REPORT'] == 'vulnerable-and-enrollable'
726+
vulnerable.keep_if do |technique|
727+
enroll_by_proxy.include?(technique) || (template[:permissions].include?('FULL CONTROL') || template[:permissions].include?('ENROLL')) && template[:ca_servers].values.any? { _1[:permissions].include?('REQUEST CERTIFICATES') }
728+
end
729+
end
730+
731+
[vulnerable, potentially_vulnerable]
732+
end
733+
710734
def print_vulnerable_cert_info
711-
filtered_certificate_details = @certificate_details.sort.to_h.select do |_key, details|
735+
filtered_certificate_details = @certificate_details.sort.to_h.select do |_key, template|
712736
case datastore['REPORT']
713737
when 'all'
714738
true
715739
when 'vulnerable'
716-
details[:techniques].present?
740+
template[:techniques].present?
717741
when 'vulnerable-and-published'
718-
details[:techniques].present? && details[:ca_servers].present?
742+
template[:techniques].present? && template[:ca_servers].present?
719743
when 'vulnerable-and-enrollable'
720-
(details[:permissions].include?('FULL CONTROL') || details[:permissions].include?('ENROLL')) && details[:ca_servers].values.any? { _1[:permissions].include?('REQUEST CERTIFICATES') }
744+
!reporting_split_techniques(template).flatten.empty?
721745
end
722746
end
723747

@@ -726,12 +750,13 @@ def print_vulnerable_cert_info
726750
end
727751

728752
filtered_certificate_details.each do |key, hash|
729-
techniques = hash[:techniques].dup
730-
techniques.delete('ESC3_TEMPLATE_2') unless any_esc3t1 # don't report ESC3_TEMPLATE_2 if there are no instances of ESC3
731-
next unless techniques.present? || datastore['REPORT'] == 'all'
753+
vulnerable_techniques, potentially_vulnerable_techniques = reporting_split_techniques(hash)
754+
all_techniques = vulnerable_techniques + potentially_vulnerable_techniques
755+
all_techniques.delete('ESC3_TEMPLATE_2') unless any_esc3t1 # don't report ESC3_TEMPLATE_2 if there are no instances of ESC3
756+
next unless all_techniques.present? || datastore['REPORT'] == 'all'
732757

733758
if db
734-
techniques.each do |vuln|
759+
all_techniques.each do |vuln|
735760
next if vuln == 'ESC3_TEMPLATE_2'
736761

737762
prefix = "#{vuln}:"
@@ -772,24 +797,19 @@ def print_vulnerable_cert_info
772797
print_status(" Manager Approval: #{hash[:manager_approval] ? '%redRequired' : '%grnDisabled'}%clr")
773798
print_status(" Required Signatures: #{hash[:required_signatures] == 0 ? '%grn0' : '%red' + hash[:required_signatures].to_s}%clr")
774799

775-
potential_techniques = []
776-
if @registry_values.blank?
777-
potential_techniques << techniques.delete('ESC9') if techniques.include?('ESC9')
778-
potential_techniques << techniques.delete('ESC10') if techniques.include?('ESC10')
779-
end
780-
781-
if techniques.present?
782-
print_good(" Vulnerable to: #{techniques.join(', ')}")
800+
if vulnerable_techniques.present?
801+
print_good(" Vulnerable to: #{vulnerable_techniques.join(', ')}")
783802
else
784803
print_status(' Vulnerable to: (none)')
785804
end
786805

787-
if potential_techniques.include?('ESC9')
806+
if potentially_vulnerable_techniques.include?('ESC9')
788807
print_warning(' Potentially vulnerable to: ESC9 (the template is in a vulnerable configuration but in order to exploit registry key StrongCertificateBindingEnforcement must not be set to 2)')
789808
end
790-
if potential_techniques.include?('ESC10')
809+
if potentially_vulnerable_techniques.include?('ESC10')
791810
print_warning(' Potentially vulnerable to: ESC10 (the template is in a vulnerable configuration but in order to exploit registry key StrongCertificateBindingEnforcement must be set to 0 or CertificateMappingMethods must be set to 4)')
792811
end
812+
# TODO: need a warning here when ESC16 is potentially vulnerable
793813

794814
print_status(" Permissions: #{hash[:permissions].join(', ')}")
795815

0 commit comments

Comments
 (0)