Module: Msf::Exploit::Remote::HTTP::WebEnrollment
- Includes:
- CertRequest, LDAP::ActiveDirectory::AdCsOpts
- Defined in:
- lib/msf/core/exploit/remote/http/web_enrollment.rb
Overview
This module provides a way of interacting with the Microsoft AD/CS web enrollment portal
Instance Method Summary collapse
- #add_cert_entry(connection_identity, cert_template) ⇒ Object
- #cert_issued?(connection_identity, cert_template) ⇒ Boolean
- #do_request_cert(http_client, opts, csr, attributes) ⇒ Object
- #get_cert_templates(http_client) ⇒ Object
- #report_web_enrollment_service ⇒ Object
- #retrieve_cert(http_client, connection_identity, cert_template) ⇒ Object
- #retrieve_certs(http_client, connection_identity, cert_templates) ⇒ Object
Methods included from LDAP::ActiveDirectory::AdCsOpts
Methods included from CertRequest
#create_csr, #get_cert_msext_sid, #get_cert_msext_upn, #get_cert_policy_oids, #get_cert_san, #get_cert_san_dns, #get_cert_san_email, #get_cert_san_uri, #with_adcs_certificate_request
Instance Method Details
#add_cert_entry(connection_identity, cert_template) ⇒ Object
30 31 32 33 34 35 36 |
# File 'lib/msf/core/exploit/remote/http/web_enrollment.rb', line 30 def add_cert_entry(connection_identity, cert_template) if @issued_certs.key?(connection_identity) @issued_certs[connection_identity] << cert_template else @issued_certs[connection_identity] = [ cert_template ] end end |
#cert_issued?(connection_identity, cert_template) ⇒ Boolean
49 50 51 |
# File 'lib/msf/core/exploit/remote/http/web_enrollment.rb', line 49 def cert_issued?(connection_identity, cert_template) !!@issued_certs[connection_identity]&.include?(cert_template) end |
#do_request_cert(http_client, opts, csr, attributes) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/msf/core/exploit/remote/http/web_enrollment.rb', line 71 def do_request_cert(http_client, opts, csr, attributes) res = send_request_raw( { 'client' => http_client, 'method' => 'POST', 'uri' => normalize_uri(datastore['TARGETURI'], 'certfnsh.asp'), 'ctype' => 'application/x-www-form-urlencoded', 'vars_post' => { 'Mode' => 'newreq', 'CertRequest' => Rex::Text.encode_base64(csr.to_der.to_s), 'CertAttrib' => attributes.map { |k, v| "#{k}:#{v}" }.join("\n"), 'TargetStoreFlags' => 0, 'SaveCert' => 'yes', 'ThumbPrint' => '' }, 'cgi' => true } ) cert_template = opts[:cert_template] connection_identity = "#{opts[:domain]}\\#{opts[:username]}" if res.nil? print_bad('Certificate request failed, no response was received from the server') return nil end if res.code == 200 && res.body.include?('request was denied') print_bad("Certificate request denied using template #{cert_template} for #{connection_identity}") return nil end if res.code == 200 && res.body.include?('request failed') print_bad("Certificate request failed using template #{cert_template} for #{connection_identity}") return nil end if res.code == 401 && res.body.include?('invalid credentials') print_bad("Invalid Credential Error returned when using template #{cert_template} for #{connection_identity}") return nil end print_good("Certificate generated using template #{cert_template} for #{connection_identity}") add_cert_entry(connection_identity, cert_template) begin location_tag = res.body.match(/^.*location="(.*)"/)[1] rescue NoMethodError print_bad('Unable to locate location tag') return nil end location_uri = normalize_uri(target_uri, location_tag) vprint_status("Attempting to download the certificate from #{location_uri}") res = send_request_raw( { 'client' => http_client, 'method' => 'GET', 'uri' => location_uri } ) OpenSSL::X509::Certificate.new(res.body) end |
#get_cert_templates(http_client) ⇒ Object
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/msf/core/exploit/remote/http/web_enrollment.rb', line 14 def get_cert_templates(http_client) print_status('Retrieving available template list, this may take a few minutes') res = send_request_raw( { 'client' => http_client, 'method' => 'GET', 'uri' => normalize_uri(target_uri, 'certrqxt.asp') } ) return nil unless res&.code == 200 cert_templates = res.body.scan(/^.*Option Value="[E|O];(.*?);/).map(&:first) print_bad('Found no available certificate templates') if cert_templates.empty? cert_templates end |
#report_web_enrollment_service ⇒ Object
133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/msf/core/exploit/remote/http/web_enrollment.rb', line 133 def report_web_enrollment_service common = { host: rhost, port: rport, proto: 'tcp' } report_service({ name: 'AD CS Web Enrollment', parents: { name: ssl ? 'https' : 'http', parents: { name: 'tcp' }.merge(common) }.merge(common) }.merge(common)) end |
#retrieve_cert(http_client, connection_identity, cert_template) ⇒ Object
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/msf/core/exploit/remote/http/web_enrollment.rb', line 53 def retrieve_cert(http_client, connection_identity, cert_template) opts = { username: connection_identity.split('\\').last, domain: connection_identity.split('\\').first, # this is slightly inconsistent since it's the NETBIOS domain name not FQDN cert_template: cert_template, } with_adcs_certificate_request(opts) do |csr, attributes| if (certificate = do_request_cert(http_client, opts, csr, attributes)) # Unlike with MS-ICPR we're not confident the target is the AD CS service we think it is until a # certificate is issued so wait and only report the service if it worked opts[:service] = report_web_enrollment_service end certificate end end |
#retrieve_certs(http_client, connection_identity, cert_templates) ⇒ Object
38 39 40 41 42 43 44 45 46 47 |
# File 'lib/msf/core/exploit/remote/http/web_enrollment.rb', line 38 def retrieve_certs(http_client, connection_identity, cert_templates) cert_templates.each do |cert_template| if cert_issued?(connection_identity, cert_template) print_status("Certificate already created for #{connection_identity} using #{cert_template}, skipping...") next end retrieve_cert(http_client, connection_identity, cert_template) end end |