@@ -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