From 553a596f1a0335a5f0d0f4c7df6ca44a1a7c7bba Mon Sep 17 00:00:00 2001 From: spyr0 <78267628+spyr0-sec@users.noreply.github.com> Date: Wed, 2 Oct 2024 13:25:18 +0100 Subject: [PATCH 1/5] Update LDAPProperties.cs Updated LAPS password attributes --- src/CommonLib/Enums/LDAPProperties.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/CommonLib/Enums/LDAPProperties.cs b/src/CommonLib/Enums/LDAPProperties.cs index 0b202e46..25bd4a8b 100644 --- a/src/CommonLib/Enums/LDAPProperties.cs +++ b/src/CommonLib/Enums/LDAPProperties.cs @@ -36,7 +36,8 @@ public static class LDAPProperties public const string ServicePack = "operatingsystemservicepack"; public const string DNSHostName = "dnshostname"; public const string LAPSExpirationTime = "mslaps-passwordexpirationtime"; - public const string LAPSPassword = "mslaps-password"; + public const string LAPSPlaintextPassword = "ms-laps-password"; + public const string LAPSEncryptedPassword = "ms-laps-encryptedpassword"; public const string LegacyLAPSExpirationTime = "ms-mcs-admpwdexpirationtime"; public const string LegacyLAPSPassword = "ms-mcs-admpwd"; public const string Members = "member"; From 7d16833b3b42d8ff1baba4190eed982ddd3e2d30 Mon Sep 17 00:00:00 2001 From: spyr0 <78267628+spyr0-sec@users.noreply.github.com> Date: Wed, 2 Oct 2024 13:27:16 +0100 Subject: [PATCH 2/5] Update ACLProcessor.cs Updated logic to create ReadLAPSPassword edges based on updated LAPS password attributes --- src/CommonLib/Processors/ACLProcessor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CommonLib/Processors/ACLProcessor.cs b/src/CommonLib/Processors/ACLProcessor.cs index af69068a..546eb630 100644 --- a/src/CommonLib/Processors/ACLProcessor.cs +++ b/src/CommonLib/Processors/ACLProcessor.cs @@ -402,7 +402,7 @@ public async IAsyncEnumerable ProcessACL(byte[] ntSecurityDescriptor, strin RightName = EdgeNames.AllExtendedRights, InheritanceHash = aceInheritanceHash }; - else if (mappedGuid is LDAPProperties.LegacyLAPSPassword or LDAPProperties.LAPSPassword) + else if (mappedGuid is LDAPProperties.LegacyLAPSPassword or LDAPProperties.LAPSPlaintextPassword or LDAPProperties.LAPSEncryptedPassword) yield return new ACE { PrincipalType = resolvedPrincipal.ObjectType, PrincipalSID = resolvedPrincipal.ObjectIdentifier, From 86224d82c88c891905bd040fcc26e718b23bd8a4 Mon Sep 17 00:00:00 2001 From: spyr0 <78267628+spyr0-sec@users.noreply.github.com> Date: Wed, 2 Oct 2024 13:28:50 +0100 Subject: [PATCH 3/5] Update ACLProcessor.cs Updated logic to pull GUIDs for new LAPS password attributes --- src/CommonLib/Processors/ACLProcessor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CommonLib/Processors/ACLProcessor.cs b/src/CommonLib/Processors/ACLProcessor.cs index 546eb630..aea8b60c 100644 --- a/src/CommonLib/Processors/ACLProcessor.cs +++ b/src/CommonLib/Processors/ACLProcessor.cs @@ -64,7 +64,7 @@ private async Task BuildGuidCache(string domain) { } name = name.ToLower(); - if (name is LDAPProperties.LAPSPassword or LDAPProperties.LegacyLAPSPassword) { + if (name is LDAPProperties.LAPSPlaintextPassword or LDAPProperties.LAPSEncryptedPassword or LDAPProperties.LegacyLAPSPassword) { _log.LogDebug("Found GUID for ACL Right {Name}: {Guid} in domain {Domain}", name, guid, domain); GuidMap.TryAdd(guid, name); } From 57cedd10d87c0a2ec223bf0c9fe7452bd7fec23d Mon Sep 17 00:00:00 2001 From: spyr0 <78267628+spyr0-sec@users.noreply.github.com> Date: Wed, 2 Oct 2024 13:33:10 +0100 Subject: [PATCH 4/5] Update LDAPProperties.cs Corrected new LAPS password expiry attribute --- src/CommonLib/Enums/LDAPProperties.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CommonLib/Enums/LDAPProperties.cs b/src/CommonLib/Enums/LDAPProperties.cs index 25bd4a8b..18ae2c55 100644 --- a/src/CommonLib/Enums/LDAPProperties.cs +++ b/src/CommonLib/Enums/LDAPProperties.cs @@ -35,7 +35,7 @@ public static class LDAPProperties public const string OperatingSystem = "operatingsystem"; public const string ServicePack = "operatingsystemservicepack"; public const string DNSHostName = "dnshostname"; - public const string LAPSExpirationTime = "mslaps-passwordexpirationtime"; + public const string LAPSExpirationTime = "ms-laps-passwordexpirationtime"; public const string LAPSPlaintextPassword = "ms-laps-password"; public const string LAPSEncryptedPassword = "ms-laps-encryptedpassword"; public const string LegacyLAPSExpirationTime = "ms-mcs-admpwdexpirationtime"; From 33c75a3f1ee274ef9157959da6e9c233ba5fb9ab Mon Sep 17 00:00:00 2001 From: spyr0 Date: Wed, 16 Oct 2024 22:55:15 +0100 Subject: [PATCH 5/5] Fixed ReadLAPSPassword Logic --- src/CommonLib/Enums/LDAPProperties.cs | 2 +- src/CommonLib/Processors/ACLProcessor.cs | 27 +++++++++++++++--------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/CommonLib/Enums/LDAPProperties.cs b/src/CommonLib/Enums/LDAPProperties.cs index 18ae2c55..25bd4a8b 100644 --- a/src/CommonLib/Enums/LDAPProperties.cs +++ b/src/CommonLib/Enums/LDAPProperties.cs @@ -35,7 +35,7 @@ public static class LDAPProperties public const string OperatingSystem = "operatingsystem"; public const string ServicePack = "operatingsystemservicepack"; public const string DNSHostName = "dnshostname"; - public const string LAPSExpirationTime = "ms-laps-passwordexpirationtime"; + public const string LAPSExpirationTime = "mslaps-passwordexpirationtime"; public const string LAPSPlaintextPassword = "ms-laps-password"; public const string LAPSEncryptedPassword = "ms-laps-encryptedpassword"; public const string LegacyLAPSExpirationTime = "ms-mcs-admpwdexpirationtime"; diff --git a/src/CommonLib/Processors/ACLProcessor.cs b/src/CommonLib/Processors/ACLProcessor.cs index e28ea491..00aed1e4 100644 --- a/src/CommonLib/Processors/ACLProcessor.cs +++ b/src/CommonLib/Processors/ACLProcessor.cs @@ -300,8 +300,6 @@ public async IAsyncEnumerable ProcessACL(byte[] ntSecurityDescriptor, strin aceInheritanceHash = CalculateInheritanceHash(ir, aceRights, aceType, ace.InheritedObjectType()); } - _guidMap.TryGetValue(aceType, out var mappedGuid); - _log.LogTrace("Processing ACE with rights {Rights} and guid {GUID} on object {Name}", aceRights, aceType, objectName); @@ -414,14 +412,23 @@ public async IAsyncEnumerable ProcessACL(byte[] ntSecurityDescriptor, strin RightName = EdgeNames.AllExtendedRights, InheritanceHash = aceInheritanceHash }; - else if (mappedGuid is LDAPProperties.LegacyLAPSPassword or LDAPProperties.LAPSPlaintextPassword or LDAPProperties.LAPSEncryptedPassword) - yield return new ACE { - PrincipalType = resolvedPrincipal.ObjectType, - PrincipalSID = resolvedPrincipal.ObjectIdentifier, - IsInherited = inherited, - RightName = EdgeNames.ReadLAPSPassword, - InheritanceHash = aceInheritanceHash - }; + else if (_guidMap.TryGetValue(aceType, out var lapsAttribute)) + { + // Compare the retrieved attribute name against LDAPProperties values + if (lapsAttribute == LDAPProperties.LegacyLAPSPassword || + lapsAttribute == LDAPProperties.LAPSPlaintextPassword || + lapsAttribute == LDAPProperties.LAPSEncryptedPassword) + { + yield return new ACE + { + PrincipalType = resolvedPrincipal.ObjectType, + PrincipalSID = resolvedPrincipal.ObjectIdentifier, + IsInherited = inherited, + RightName = EdgeNames.ReadLAPSPassword, + InheritanceHash = aceInheritanceHash + }; + } + } } } else if (objectType == Label.CertTemplate) { if (aceType is ACEGuids.AllGuid or "")