From a6fd6defcb9ba212dbe2488f0d9f4d2b2a295539 Mon Sep 17 00:00:00 2001 From: Spencer McIntyre Date: Tue, 18 Jun 2024 17:39:06 -0400 Subject: [PATCH] Escape LDAP query strings --- lib/msf/core/exploit/remote/ldap.rb | 9 +++++++++ .../gather/ldap_esc_vulnerable_cert_finder.rb | 6 +++--- spec/lib/msf/core/exploit/remote/ldap_spec.rb | 10 ++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/lib/msf/core/exploit/remote/ldap.rb b/lib/msf/core/exploit/remote/ldap.rb index 7320e7c48eb7..5346a14d382d 100644 --- a/lib/msf/core/exploit/remote/ldap.rb +++ b/lib/msf/core/exploit/remote/ldap.rb @@ -309,5 +309,14 @@ def validate_query_result!(query_result, filter=nil) end end end + + # Return a string suitable for placement in an LDAP filter + # e.g. (certificateTemplates=#{ldap_escape_string(name)}) + # + # @param string String The string to escape. + # @return The escaped string. + def ldap_escape_filter(string) + Net::LDAP::Filter.escape(string) + end end end diff --git a/modules/auxiliary/gather/ldap_esc_vulnerable_cert_finder.rb b/modules/auxiliary/gather/ldap_esc_vulnerable_cert_finder.rb index 809972513a11..789da03382a6 100644 --- a/modules/auxiliary/gather/ldap_esc_vulnerable_cert_finder.rb +++ b/modules/auxiliary/gather/ldap_esc_vulnerable_cert_finder.rb @@ -178,7 +178,7 @@ def query_ldap_server_certificates(esc_raw_filter, esc_name) def convert_sids_to_human_readable_name(sids_array) output = [] for sid in sids_array - raw_filter = "(objectSID=#{sid})" + raw_filter = "(objectSID=#{ldap_escape_filter(sid.to_s)})" attributes = ['sAMAccountName', 'name'] base_prefix = 'CN=Configuration' sid_entry = query_ldap_server(raw_filter, attributes, base_prefix: base_prefix) # First try with prefix to find entries that may be group specific. @@ -344,7 +344,7 @@ def find_enrollable_vuln_certificate_templates # have permissions to enroll in certificates on each server. @vuln_certificate_details.each_key do |certificate_template| - certificate_enrollment_raw_filter = "(&(objectClass=pKIEnrollmentService)(certificateTemplates=#{certificate_template}))" + certificate_enrollment_raw_filter = "(&(objectClass=pKIEnrollmentService)(certificateTemplates=#{ldap_escape_filter(certificate_template.to_s)}))" attributes = ['cn', 'dnsHostname', 'ntsecuritydescriptor'] base_prefix = 'CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration' enrollment_ca_data = query_ldap_server(certificate_enrollment_raw_filter, attributes, base_prefix: base_prefix) @@ -418,7 +418,7 @@ def get_pki_object_by_oid(oid) if pki_object.nil? pki_object = query_ldap_server( - "(&(objectClass=msPKI-Enterprise-Oid)(msPKI-Cert-Template-OID=#{oid}))", + "(&(objectClass=msPKI-Enterprise-Oid)(msPKI-Cert-Template-OID=#{ldap_escape_filter(oid.to_s)}))", nil, base_prefix: 'CN=OID,CN=Public Key Services,CN=Services,CN=Configuration' )&.first diff --git a/spec/lib/msf/core/exploit/remote/ldap_spec.rb b/spec/lib/msf/core/exploit/remote/ldap_spec.rb index adbddfcfacf1..0a556621979f 100644 --- a/spec/lib/msf/core/exploit/remote/ldap_spec.rb +++ b/spec/lib/msf/core/exploit/remote/ldap_spec.rb @@ -90,6 +90,16 @@ end end + describe '#ldap_escape_filter' do + let(:string) do + 'John Doe (Developer) *' + end + + it do + expect(subject.ldap_escape_filter(string)).to eq("John Doe \\28Developer\\29 \\2A") + end + end + describe '#resolve_connect_opts' do let(:cred) do 'I am a cred'