Skip to content

Commit

Permalink
Merge pull request #19849 from zeroSteiner/feat/mod/ldap/esc-finder-u…
Browse files Browse the repository at this point in the history
…pdates

AD CS Workflow Related Changes
  • Loading branch information
jheysel-r7 authored Jan 31, 2025
2 parents ec9edc5 + 0013db1 commit f3eefc0
Show file tree
Hide file tree
Showing 5 changed files with 424 additions and 202 deletions.
102 changes: 102 additions & 0 deletions lib/rex/proto/ms_dnsp.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# -*- coding: binary -*-
# frozen_string_literal: true

require 'bindata'

module Rex::Proto
module MsDnsp
# see: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dnsp/39b03b89-2264-4063-8198-d62f62a6441a
class DnsRecordType
DNS_TYPE_ZERO = 0x0000
DNS_TYPE_A = 0x0001
DNS_TYPE_NS = 0x0002
DNS_TYPE_MD = 0x0003
DNS_TYPE_MF = 0x0004
DNS_TYPE_CNAME = 0x0005
DNS_TYPE_SOA = 0x0006
DNS_TYPE_MB = 0x0007
DNS_TYPE_MG = 0x0008
DNS_TYPE_MR = 0x0009
DNS_TYPE_NULL = 0x000A
DNS_TYPE_WKS = 0x000B
DNS_TYPE_PTR = 0x000C
DNS_TYPE_HINFO = 0x000D
DNS_TYPE_MINFO = 0x000E
DNS_TYPE_MX = 0x000F
DNS_TYPE_TXT = 0x0010
DNS_TYPE_RP = 0x0011
DNS_TYPE_AFSDB = 0x0012
DNS_TYPE_X25 = 0x0013
DNS_TYPE_ISDN = 0x0014
DNS_TYPE_RT = 0x0015
DNS_TYPE_SIG = 0x0018
DNS_TYPE_KEY = 0x0019
DNS_TYPE_AAAA = 0x001C
DNS_TYPE_LOC = 0x001D
DNS_TYPE_NXT = 0x001E
DNS_TYPE_SRV = 0x0021
DNS_TYPE_ATMA = 0x0022
DNS_TYPE_NAPTR = 0x0023
DNS_TYPE_DNAME = 0x0027
DNS_TYPE_DS = 0x002B
DNS_TYPE_RRSIG = 0x002E
DNS_TYPE_NSEC = 0x002F
DNS_TYPE_DNSKEY = 0x0030
DNS_TYPE_DHCID = 0x0031
DNS_TYPE_NSEC3 = 0x0032
DNS_TYPE_NSEC3PARAM = 0x0033
DNS_TYPE_TLSA = 0x0034
DNS_TYPE_ALL = 0x00FF
DNS_TYPE_WINS = 0xFF01
DNS_TYPE_WINSR = 0xFF02
end

class MsDnspAddr4 < BinData::Primitive
string :data, length: 4

def get
Rex::Socket.addr_ntoa(self.data)
end

def set(v)
raise TypeError, 'must be an IPv4 address' unless Rex::Socket.is_ipv4?(v)

self.data = Rex::Socket.addr_aton(v)
end
end

class MsDnspAddr6 < BinData::Primitive
string :data, length: 16

def get
Rex::Socket.addr_ntoa(self.data)
end

def set(v)
raise TypeError, 'must be an IPv6 address' unless Rex::Socket.is_ipv6?(v)

self.data = Rex::Socket.addr_aton(v)
end
end

# see: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dnsp/6912b338-5472-4f59-b912-0edb536b6ed8
class MsDnspDnsRecord < BinData::Record
endian :little

uint16 :data_length, initial_value: -> { data.length }
uint16 :record_type
uint8 :version
uint8 :rank
uint16 :flags
uint32 :serial
uint32be :ttl_seconds
uint32 :reserved
uint32 :timestamp
choice :data, selection: :record_type do
ms_dnsp_addr4 DnsRecordType::DNS_TYPE_A
ms_dnsp_addr6 DnsRecordType::DNS_TYPE_AAAA
string :default, read_length: :data_length
end
end
end
end
5 changes: 4 additions & 1 deletion modules/auxiliary/admin/kerberos/get_ticket.rb
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ def validate_options
def run
validate_options

send("action_#{action.name.downcase}")
result = send("action_#{action.name.downcase}")

report_service(
host: rhost,
Expand All @@ -151,6 +151,8 @@ def run
name: 'kerberos',
info: "Module: #{fullname}, KDC for domain #{@realm}"
)

result
rescue ::Rex::ConnectionError => e
elog('Connection error', error: e)
fail_with(Failure::Unreachable, e.message)
Expand Down Expand Up @@ -276,6 +278,7 @@ def action_get_hash
print_good("Found NTLM hash for #{@username}: #{ntlm_hash}")

report_ntlm(ntlm_hash)
ntlm_hash
end

def report_ntlm(hash)
Expand Down
20 changes: 14 additions & 6 deletions modules/auxiliary/admin/ldap/ad_cs_cert_template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,9 @@ def run
end
@ldap = ldap

send("action_#{action.name.downcase}")
result = send("action_#{action.name.downcase}")
print_good('The operation completed successfully!')
result
end
rescue Errno::ECONNRESET
fail_with(Failure::Disconnected, 'The connection was reset.')
Expand Down Expand Up @@ -147,7 +148,7 @@ def get_certificate_template
"#{datastore['CERT_TEMPLATE']} Certificate Template"
)
print_status("Certificate template data written to: #{stored}")
obj
[obj, stored]
end

def get_domain_sid
Expand Down Expand Up @@ -323,17 +324,19 @@ def action_create
print_status("Creating: #{dn}")
@ldap.add(dn: dn, attributes: attributes)
validate_query_result!(@ldap.get_operation_result.table)
dn
end

def action_delete
obj = get_certificate_template
obj, = get_certificate_template

@ldap.delete(dn: obj['dn'].first)
validate_query_result!(@ldap.get_operation_result.table)
true
end

def action_read
obj = get_certificate_template
obj, stored = get_certificate_template

print_status('Certificate Template:')
print_status(" distinguishedName: #{obj['distinguishedname'].first}")
Expand Down Expand Up @@ -477,10 +480,12 @@ def action_read
if obj['pkimaxissuingdepth'].present?
print_status(" pKIMaxIssuingDepth: #{obj['pkimaxissuingdepth'].first.to_i}")
end

{ object: obj, file: stored }
end

def action_update
obj = get_certificate_template
obj, = get_certificate_template
new_configuration = load_local_template

operations = []
Expand All @@ -492,6 +497,8 @@ def action_update
unless value.tally == new_value.tally
operations << [:replace, attribute, new_value]
end
elsif attribute == 'ntsecuritydescriptor'
# the security descriptor can't be deleted so leave it alone unless specified
else
operations << [:delete, attribute, nil]
end
Expand All @@ -506,10 +513,11 @@ def action_update

if operations.empty?
print_good('There are no changes to be made.')
return
return true
end

@ldap.modify(dn: obj['dn'].first, operations: operations, controls: [ms_security_descriptor_control(DACL_SECURITY_INFORMATION)])
validate_query_result!(@ldap.get_operation_result.table)
true
end
end
Loading

0 comments on commit f3eefc0

Please sign in to comment.