From f280442b9be78d2449fc0cc6f062d38d798997f5 Mon Sep 17 00:00:00 2001 From: anemeth Date: Fri, 13 Sep 2024 11:10:31 -0700 Subject: [PATCH 1/2] Min-valued nano durations would throw Overflow exceptions, should instead resolve to 'Forever' value --- src/CommonLib/Processors/LdapPropertyProcessor.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/CommonLib/Processors/LdapPropertyProcessor.cs b/src/CommonLib/Processors/LdapPropertyProcessor.cs index b2abc562..4c9f3579 100644 --- a/src/CommonLib/Processors/LdapPropertyProcessor.cs +++ b/src/CommonLib/Processors/LdapPropertyProcessor.cs @@ -724,6 +724,11 @@ private static List ConvertEncryptionTypes(string encryptionTypes) private static string ConvertNanoDuration(long duration) { + // In case duration is long.MinValue, Math.Abs will overflow. Value represents Forever or Never + if (duration == long.MinValue) { + return "Forever"; + } + // duration is in 100-nanosecond intervals // Convert it to TimeSpan (which uses 1 tick = 100 nanoseconds) TimeSpan durationSpan = TimeSpan.FromTicks(Math.Abs(duration)); From ad9538bf1942e39290bcf4c863e81622bf7582c7 Mon Sep 17 00:00:00 2001 From: anemeth Date: Fri, 13 Sep 2024 11:40:35 -0700 Subject: [PATCH 2/2] Going a step further on duration property resolution of error code values --- .../Processors/LdapPropertyProcessor.cs | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/CommonLib/Processors/LdapPropertyProcessor.cs b/src/CommonLib/Processors/LdapPropertyProcessor.cs index 4c9f3579..145a1bca 100644 --- a/src/CommonLib/Processors/LdapPropertyProcessor.cs +++ b/src/CommonLib/Processors/LdapPropertyProcessor.cs @@ -8,6 +8,7 @@ using System.Security.Cryptography.X509Certificates; using System.Security.Principal; using System.Threading.Tasks; +using Microsoft.Extensions.Logging.Abstractions; using SharpHoundCommonLib.Enums; using SharpHoundCommonLib.LDAPQueries; using SharpHoundCommonLib.OutputTypes; @@ -70,16 +71,28 @@ public async Task> ReadDomainProperties(IDirectoryObj props.Add("lockoutthreshold", entry.GetProperty(LDAPProperties.LockoutThreshold)); if (entry.TryGetLongProperty(LDAPProperties.MinPwdAge, out var minpwdage)) { - props.Add("minpwdage", ConvertNanoDuration(minpwdage)); + var duration = ConvertNanoDuration(minpwdage); + if (duration != null) { + props.Add("minpwdage", duration); + } } if (entry.TryGetLongProperty(LDAPProperties.MaxPwdAge, out var maxpwdage)) { - props.Add("maxpwdage", ConvertNanoDuration(maxpwdage)); + var duration = ConvertNanoDuration(maxpwdage); + if (duration != null) { + props.Add("maxpwdage", duration); + } } if (entry.TryGetLongProperty(LDAPProperties.LockoutDuration, out var lockoutduration)) { - props.Add("lockoutduration", ConvertNanoDuration(lockoutduration)); + var duration = ConvertNanoDuration(lockoutduration); + if (duration != null) { + props.Add("lockoutduration", duration); + } } if (entry.TryGetLongProperty(LDAPProperties.LockOutObservationWindow, out var lockoutobservationwindow)) { - props.Add("lockoutobservationwindow", ConvertNanoDuration(lockoutobservationwindow)); + var duration = ConvertNanoDuration(lockoutobservationwindow); + if (duration != null) { + props.Add("lockoutobservationwindow", lockoutobservationwindow); + } } if (!entry.TryGetLongProperty(LDAPProperties.DomainFunctionalLevel, out var functionalLevel)) { functionalLevel = -1; @@ -727,6 +740,9 @@ private static string ConvertNanoDuration(long duration) // In case duration is long.MinValue, Math.Abs will overflow. Value represents Forever or Never if (duration == long.MinValue) { return "Forever"; + // And if the value is positive, it indicates an error code + } else if (duration > 0) { + return null; } // duration is in 100-nanosecond intervals