diff --git a/bloodhound/ad/computer.py b/bloodhound/ad/computer.py index af8f6b9..ffbece4 100644 --- a/bloodhound/ad/computer.py +++ b/bloodhound/ad/computer.py @@ -146,7 +146,7 @@ def get_bloodhound_data(self, entry, collect, skip_acl=False): props['samaccountname'] = ADUtils.get_entry_property(entry, 'sAMAccountName') if 'objectprops' in collect or 'acl' in collect: - props['haslaps'] = ADUtils.get_entry_property(entry, 'ms-mcs-admpwdexpirationtime', 0) != 0 + props['haslaps'] = bool(ADUtils.get_entry_property(entry, 'ms-mcs-admpwdexpirationtime', 0) or ADUtils.get_entry_property(entry, 'mslaps-passwordexpirationtime', 0)) if 'objectprops' in collect: props['lastlogon'] = ADUtils.win_timestamp_to_unix( diff --git a/bloodhound/ad/domain.py b/bloodhound/ad/domain.py index 9b1c7e9..048254f 100644 --- a/bloodhound/ad/domain.py +++ b/bloodhound/ad/domain.py @@ -271,6 +271,9 @@ def get_objecttype(self): if 'ms-mcs-admpwdexpirationtime' in self.objecttype_guid_map: logging.debug('Found LAPS attributes in schema') self.ad.has_laps = True + elif 'ms-laps-passwordexpirationtime' in self.objecttype_guid_map: + logging.debug('Found LAPSv2 attributes in schema') + self.ad.has_lapsv2 = True else: logging.debug('No LAPS attributes found in schema') @@ -484,12 +487,15 @@ def get_computers(self, include_properties=False, acl=False): properties.append('msDS-AllowedToActOnBehalfOfOtherIdentity') if self.ad.has_laps: properties.append('ms-mcs-admpwdexpirationtime') + if self.ad.has_lapsv2: + properties.append('mslaps-passwordexpirationtime') if acl: # Also collect LAPS expiration time since this matters for reporting (no LAPS = no ACL reported) if self.ad.has_laps: - properties += ['nTSecurityDescriptor', 'ms-mcs-admpwdexpirationtime'] - else: - properties.append('nTSecurityDescriptor') + properties.append('ms-mcs-admpwdexpirationtime') + if self.ad.has_lapsv2: + properties.append('mslaps-passwordexpirationtime') + properties.append('nTSecurityDescriptor') # Exclude MSA only if server supports it if 'msDS-GroupManagedServiceAccount' in self.ldap.server.schema.object_classes: @@ -635,6 +641,8 @@ def __init__(self, domain=None, auth=None, nameserver=None, dns_tcp=False, dns_t self.num_domains = 1 # Does the schema have laps properties self.has_laps = False + # Does the schema have lapsv2 properties + self.has_lapsv2 = False # Does the schema have msDS-KeyCredentialLink self.has_keycredlink = False if domain is not None: diff --git a/bloodhound/enumeration/acls.py b/bloodhound/enumeration/acls.py index f5a3667..c84b1b0 100644 --- a/bloodhound/enumeration/acls.py +++ b/bloodhound/enumeration/acls.py @@ -164,7 +164,7 @@ def parse_binary_acl(entry, entrytype, acl, objecttype_guid_map): if entrytype == 'computer' and \ ace_object.acedata.has_flag(ACCESS_ALLOWED_OBJECT_ACE.ACE_OBJECT_TYPE_PRESENT) and \ entry['Properties']['haslaps']: - if ace_object.acedata.get_object_type().lower() == objecttype_guid_map['ms-mcs-admpwd']: + if ace_object.acedata.get_object_type().lower() in (objecttype_guid_map.get('ms-mcs-admpwd'), objecttype_guid_map.get('mslaps-password')): relations.append(build_relation(sid, 'ReadLAPSPassword', inherited=is_inherited)) # Extended rights