2023-08-29 13:51:58 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
2023-09-17 20:20:40 +00:00
|
|
|
class NXCModule:
|
2023-08-29 13:51:58 +00:00
|
|
|
'''
|
|
|
|
Extract all Trust Relationships, Trusting Direction, and Trust Transitivity
|
|
|
|
Module by Brandon Fisher @shad0wcntr0ller
|
|
|
|
'''
|
|
|
|
name = 'enum_trusts'
|
|
|
|
description = 'Extract all Trust Relationships, Trusting Direction, and Trust Transitivity'
|
|
|
|
supported_protocols = ['ldap']
|
|
|
|
opsec_safe = True
|
|
|
|
multiple_hosts = True
|
|
|
|
|
|
|
|
def options(self, context, module_options):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def on_login(self, context, connection):
|
|
|
|
domain_dn = ','.join(['DC=' + dc for dc in connection.domain.split('.')])
|
|
|
|
search_filter = '(&(objectClass=trustedDomain))'
|
|
|
|
attributes = ['flatName', 'trustPartner', 'trustDirection', 'trustAttributes']
|
2023-08-29 15:38:07 +00:00
|
|
|
|
|
|
|
context.log.debug(f'Search Filter={search_filter}')
|
|
|
|
resp = connection.ldapConnection.search(searchBase=domain_dn, searchFilter=search_filter, attributes=attributes, sizeLimit=0)
|
2023-08-29 13:51:58 +00:00
|
|
|
|
|
|
|
trusts = []
|
2023-08-29 15:38:07 +00:00
|
|
|
context.log.debug(f'Total of records returned {len(resp)}')
|
2023-08-29 13:51:58 +00:00
|
|
|
for item in resp:
|
|
|
|
if isinstance(item, ldapasn1_impacket.SearchResultEntry) is not True:
|
|
|
|
continue
|
|
|
|
flat_name = ''
|
|
|
|
trust_partner = ''
|
|
|
|
trust_direction = ''
|
|
|
|
trust_transitive = []
|
|
|
|
try:
|
|
|
|
for attribute in item['attributes']:
|
|
|
|
if str(attribute['type']) == 'flatName':
|
|
|
|
flat_name = str(attribute['vals'][0])
|
|
|
|
elif str(attribute['type']) == 'trustPartner':
|
|
|
|
trust_partner = str(attribute['vals'][0])
|
|
|
|
elif str(attribute['type']) == 'trustDirection':
|
|
|
|
if str(attribute['vals'][0]) == '1':
|
|
|
|
trust_direction = 'Inbound'
|
|
|
|
elif str(attribute['vals'][0]) == '2':
|
|
|
|
trust_direction = 'Outbound'
|
|
|
|
elif str(attribute['vals'][0]) == '3':
|
|
|
|
trust_direction = 'Bidirectional'
|
|
|
|
elif str(attribute['type']) == 'trustAttributes':
|
|
|
|
trust_attributes_value = int(attribute['vals'][0])
|
|
|
|
if trust_attributes_value & 0x1:
|
|
|
|
trust_transitive.append('Non-Transitive')
|
|
|
|
if trust_attributes_value & 0x2:
|
|
|
|
trust_transitive.append('Uplevel-Only')
|
|
|
|
if trust_attributes_value & 0x4:
|
|
|
|
trust_transitive.append('Quarantined Domain')
|
|
|
|
if trust_attributes_value & 0x8:
|
|
|
|
trust_transitive.append('Forest Transitive')
|
|
|
|
if trust_attributes_value & 0x10:
|
|
|
|
trust_transitive.append('Cross Organization')
|
|
|
|
if trust_attributes_value & 0x20:
|
|
|
|
trust_transitive.append('Within Forest')
|
|
|
|
if trust_attributes_value & 0x40:
|
|
|
|
trust_transitive.append('Treat as External')
|
|
|
|
if trust_attributes_value & 0x80:
|
|
|
|
trust_transitive.append('Uses RC4 Encryption')
|
|
|
|
if trust_attributes_value & 0x100:
|
|
|
|
trust_transitive.append('Cross Organization No TGT Delegation')
|
|
|
|
if trust_attributes_value & 0x2000:
|
|
|
|
trust_transitive.append('PAM Trust')
|
|
|
|
if not trust_transitive:
|
|
|
|
trust_transitive.append('Other')
|
2023-08-29 15:38:07 +00:00
|
|
|
trust_transitive = ', '.join(trust_transitive)
|
2023-08-29 13:51:58 +00:00
|
|
|
|
2023-08-29 15:38:07 +00:00
|
|
|
if flat_name and trust_partner and trust_direction and trust_transitive:
|
|
|
|
trusts.append((flat_name, trust_partner, trust_direction, trust_transitive))
|
2023-08-29 13:51:58 +00:00
|
|
|
except Exception as e:
|
2023-08-29 15:38:07 +00:00
|
|
|
context.log.debug(f'Cannot process trust relationship due to error {e}')
|
2023-08-29 13:51:58 +00:00
|
|
|
pass
|
|
|
|
|
2023-08-29 15:38:07 +00:00
|
|
|
if trusts:
|
2023-08-29 13:51:58 +00:00
|
|
|
context.log.success('Found the following trust relationships:')
|
|
|
|
for trust in trusts:
|
2023-08-29 15:38:07 +00:00
|
|
|
context.log.highlight(f'{trust[1]} -> {trust[2]} -> {trust[3]}')
|
2023-08-29 13:51:58 +00:00
|
|
|
else:
|
2023-08-29 16:30:59 +00:00
|
|
|
context.log.display('No trust relationships found')
|
2023-08-29 13:51:58 +00:00
|
|
|
|
|
|
|
return True
|
|
|
|
|