Skip to content

Commit 209fa3d

Browse files
committed
Some adjustments for ESC4 compatibility with MSP
1 parent b72290d commit 209fa3d

File tree

1 file changed

+17
-16
lines changed

1 file changed

+17
-16
lines changed

modules/auxiliary/gather/ldap_esc_vulnerable_cert_finder.rb

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ def initialize(info = {})
5050
allows enrollment in and which SIDs are authorized to use that certificate server to
5151
perform this enrollment operation.
5252
53-
Currently the module is capable of checking for certificates that are vulnerable to ESC1, ESC2, ESC3, ESC13,
54-
and ESC15. The module is limited to checking for these techniques due to them being identifiable remotely from
55-
a normal user account by analyzing the objects in LDAP.
53+
Currently the module is capable of checking for certificates that are vulnerable to ESC1, ESC2, ESC3, ESC4,
54+
ESC13, and ESC15. The module is limited to checking for these techniques due to them being identifiable
55+
remotely from a normal user account by analyzing the objects in LDAP.
5656
},
5757
'Author' => [
5858
'Grant Willcox', # Original module author
@@ -247,7 +247,7 @@ def query_ldap_server_certificates(esc_raw_filter, esc_id, notes: [])
247247

248248
def convert_sids_to_human_readable_name(sids_array)
249249
output = []
250-
for sid in sids_array
250+
sids_array.each do |sid|
251251
sid_entry = get_object_by_sid(sid)
252252
if sid_entry.nil?
253253
print_warning("Could not find any details on the LDAP server for SID #{sid}!")
@@ -392,8 +392,9 @@ def find_esc4_vuln_cert_templates
392392
# https://learn.microsoft.com/en-us/windows/win32/adsi/search-filter-syntax?redirectedfrom=MSDN
393393
filter_with_user = "(|(member:1.2.840.113556.1.4.1941:=#{our_account[:dn].first})"
394394
user_groups.each do |sid|
395-
obj = query_ldap_server("(objectSid=#{sid})", ['dn'])&.first
395+
obj = get_object_by_sid(sid)
396396
print_error('Failed to lookup SID.') unless obj
397+
397398
filter_with_user << "(member:1.2.840.113556.1.4.1941:=#{obj[:dn].first})" if obj
398399
end
399400
filter_with_user << ')'
@@ -442,28 +443,28 @@ def find_esc4_vuln_cert_templates
442443

443444
# SIDs that can edit the template that the user we've authenticated with are also a part of
444445
user_write_priv_sids = []
445-
note = []
446+
notes = []
446447

447448
# Main reason for splitting user_can_edit and group_can_edit is so "note" can be more descriptive
448449
if user_can_edit
449450
user_write_priv_sids << user_can_edit
450-
note << "ESC4: The account: #{sam_account_name} has edit permissions over the template #{certificate_symbol} making it vulnerable to ESC4"
451+
notes << "ESC4: The account: #{sam_account_name} has edit permissions over the template #{certificate_symbol} making it vulnerable to ESC4"
451452
end
452453

453454
if group_can_edit.any?
454455
user_write_priv_sids.concat(group_can_edit.map(&:to_s))
455-
note << "ESC4: The account: #{sam_account_name} is a part of the following groups: (#{convert_sids_to_human_readable_name(group_can_edit).map(&:name).join(', ')}) which have edit permissions over the template #{certificate_symbol} making it vulnerable to ESC4"
456+
notes << "ESC4: The account: #{sam_account_name} is a part of the following groups: (#{convert_sids_to_human_readable_name(group_can_edit).map(&:name).join(', ')}) which have edit permissions over the template object"
456457
end
457458

458459
next unless user_write_priv_sids.any?
459460

460-
if @vuln_certificate_details.key?(certificate_symbol)
461-
@vuln_certificate_details[certificate_symbol][:vulns] << 'ESC4'
462-
@vuln_certificate_details[certificate_symbol][:notes].concat(note)
463-
@vuln_certificate_details[certificate_symbol][:certificate_write_priv_sids] ||= convert_sids_to_human_readable_name(user_write_priv_sids)
461+
if @certificate_details.key?(certificate_symbol)
462+
@certificate_details[certificate_symbol][:techniques] << 'ESC4'
463+
@certificate_details[certificate_symbol][:notes].concat(notes)
464464
else
465-
@vuln_certificate_details[certificate_symbol] = { vulns: ['ESC4'], dn: entry[:dn][0], certificate_enrollment_sids: convert_sids_to_human_readable_name(allowed_sids), ca_servers_n_enrollment_sids: {}, certificate_write_priv_sids: convert_sids_to_human_readable_name(user_write_priv_sids), notes: note }
465+
@certificate_details[certificate_symbol] = build_certificate_details(entry, allowed_sids, techniques: %w[ESC4], notes: notes)
466466
end
467+
@certificate_details[certificate_symbol][:write_enabled_sids] ||= convert_sids_to_human_readable_name(user_write_priv_sids)
467468
end
468469
end
469470

@@ -616,7 +617,7 @@ def find_enrollable_vuln_certificate_templates
616617
end
617618

618619
def print_vulnerable_cert_info
619-
vuln_certificate_details = @certificate_details.select do |_key, hash|
620+
vuln_certificate_details = @certificate_details.sort.to_h.select do |_key, hash|
620621
select = true
621622
select = false unless datastore['REPORT_PRIVENROLLABLE'] || hash[:enrollment_sids].any? do |sid|
622623
# compare based on RIDs to avoid issues language specific issues
@@ -698,9 +699,9 @@ def print_vulnerable_cert_info
698699
end
699700
end
700701

701-
if hash[:certificate_write_priv_sids]
702+
if hash[:write_enabled_sids]
702703
print_status(' Certificate Template Write-Enabled SIDs:')
703-
hash[:certificate_write_priv_sids].each do |sid|
704+
hash[:write_enabled_sids].each do |sid|
704705
print_status(" * #{highlight_sid(sid)}")
705706
end
706707
end

0 commit comments

Comments
 (0)