From d04467ad3b27c58a9a764214c99b79303ba18ae5 Mon Sep 17 00:00:00 2001 From: JonasBK Date: Thu, 23 Apr 2026 15:02:26 +0200 Subject: [PATCH 1/3] collect or skip custom deny aces count --- .codex | 0 README.md | 2 ++ src/Options.cs | 3 +++ src/PowerShell/Template.ps1 | 7 +++++++ src/Runtime/ObjectProcessors.cs | 18 +++++++++--------- src/Sharphound.cs | 5 +++-- 6 files changed, 24 insertions(+), 11 deletions(-) create mode 100644 .codex diff --git a/.codex b/.codex new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md index fe61e32..864f3e9 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,8 @@ The listing below details the CLI arguments SharpHound supports. Additional deta --collectallproperties Collect all LDAP properties from objects + --skipdenyacescount Skip collecting custom deny ACE counts in LDAP object properties + -l, --Loop Loop computer collection --loopduration Loop duration (hh:mm:ss - 05:00:00 is 5 hours, default: 2 hrs) diff --git a/src/Options.cs b/src/Options.cs index bdc84e2..98ed40b 100644 --- a/src/Options.cs +++ b/src/Options.cs @@ -139,6 +139,9 @@ public class Options [Option(HelpText = "Collect all LDAP properties from objects")] public bool CollectAllProperties { get; set; } + + [Option(HelpText = "Skip collecting custom deny ACE counts in LDAP object properties")] + public bool SkipDenyAcesCount { get; set; } [Option(HelpText = "Split the main ldap query into smaller chunks to attempt to reduce server load")] public bool PartitionLdapQueries { get; set; } diff --git a/src/PowerShell/Template.ps1 b/src/PowerShell/Template.ps1 index f19d7bb..6292b2e 100644 --- a/src/PowerShell/Template.ps1 +++ b/src/PowerShell/Template.ps1 @@ -184,6 +184,10 @@ .PARAMETER CollectAllProperties Collect all string LDAP properties on objects + + .PARAMETER SkipDenyAcesCount + + Skip collecting custom deny ACE counts in LDAP object properties .PARAMETER Loop @@ -360,6 +364,9 @@ [Switch] $CollectAllProperties, + [Switch] + $SkipDenyAcesCount, + [Switch] $Loop, diff --git a/src/Runtime/ObjectProcessors.cs b/src/Runtime/ObjectProcessors.cs index 457ddbf..5d2f5e6 100644 --- a/src/Runtime/ObjectProcessors.cs +++ b/src/Runtime/ObjectProcessors.cs @@ -581,7 +581,7 @@ private async Task ProcessGPOObject(IDirectoryObject entry, } if (_methods.HasFlag(CollectionMethod.ObjectProps)) { - ret.Properties = ContextUtils.Merge(ret.Properties, LdapPropertyProcessor.ReadGPOProperties(entry)); + ret.Properties = ContextUtils.Merge(ret.Properties, await _ldapPropertyProcessor.ReadGPOProperties(entry)); if (_context.Flags.CollectAllProperties) { ret.Properties = ContextUtils.Merge(_ldapPropertyProcessor.ParseAllProperties(entry), ret.Properties); @@ -611,7 +611,7 @@ private async Task ProcessOUObject(IDirectoryObject entry, } if (_methods.HasFlag(CollectionMethod.ObjectProps)) { - ret.Properties = ContextUtils.Merge(ret.Properties, LdapPropertyProcessor.ReadOUProperties(entry)); + ret.Properties = ContextUtils.Merge(ret.Properties, await _ldapPropertyProcessor.ReadOUProperties(entry)); if (_context.Flags.CollectAllProperties) { ret.Properties = ContextUtils.Merge(_ldapPropertyProcessor.ParseAllProperties(entry), ret.Properties); @@ -662,7 +662,7 @@ private async Task ProcessContainerObject(IDirectoryObject entry, if (_methods.HasFlag(CollectionMethod.ObjectProps) || _methods.HasFlag(CollectionMethod.CertServices)) { ret.Properties = - ContextUtils.Merge(LdapPropertyProcessor.ReadContainerProperties(entry), ret.Properties); + ContextUtils.Merge(await _ldapPropertyProcessor.ReadContainerProperties(entry), ret.Properties); if (_context.Flags.CollectAllProperties) { ret.Properties = ContextUtils.Merge(_ldapPropertyProcessor.ParseAllProperties(entry), ret.Properties); @@ -693,7 +693,7 @@ private async Task ProcessRootCA(IDirectoryObject entry, ResolvedSearchR } if (_methods.HasFlag(CollectionMethod.ObjectProps) || _methods.HasFlag(CollectionMethod.CertServices)) { - var props = LdapPropertyProcessor.ReadRootCAProperties(entry); + var props = await _ldapPropertyProcessor.ReadRootCAProperties(entry); ret.Properties.Merge(props); } @@ -724,7 +724,7 @@ private async Task ProcessAIACA(IDirectoryObject entry, ResolvedSearchRes } if (_methods.HasFlag(CollectionMethod.ObjectProps) || _methods.HasFlag(CollectionMethod.CertServices)) { - var props = LdapPropertyProcessor.ReadAIACAProperties(entry); + var props = await _ldapPropertyProcessor.ReadAIACAProperties(entry); ret.Properties.Merge(props); } @@ -754,7 +754,7 @@ private async Task ProcessEnterpriseCA(IDirectoryObject entry, Res } if (_methods.HasFlag(CollectionMethod.ObjectProps) || _methods.HasFlag(CollectionMethod.CertServices)) { - var props = LdapPropertyProcessor.ReadEnterpriseCAProperties(entry); + var props = await _ldapPropertyProcessor.ReadEnterpriseCAProperties(entry); ret.Properties.Merge(props); // Enabled cert templates @@ -871,7 +871,7 @@ private async Task ProcessNTAuthStore(IDirectoryObject entry, } if (_methods.HasFlag(CollectionMethod.ObjectProps) || _methods.HasFlag(CollectionMethod.CertServices)) { - var props = LdapPropertyProcessor.ReadNTAuthStoreProperties(entry); + var props = await _ldapPropertyProcessor.ReadNTAuthStoreProperties(entry); if (entry.TryGetByteArrayProperty(LDAPProperties.CACertificate, out var rawCertificates)) { var certificates = from rawCertificate in rawCertificates @@ -910,7 +910,7 @@ private async Task ProcessCertTemplate(IDirectoryObject entry, } if (_methods.HasFlag(CollectionMethod.ObjectProps) || _methods.HasFlag(CollectionMethod.CertServices)) { - var certTemplatesProps = LdapPropertyProcessor.ReadCertTemplateProperties(entry); + var certTemplatesProps = await _ldapPropertyProcessor.ReadCertTemplateProperties(entry); ret.Properties.Merge(certTemplatesProps); } @@ -956,4 +956,4 @@ private async Task ProcessIssuancePolicy(IDirectoryObject entry, return ret; } } -} \ No newline at end of file +} diff --git a/src/Sharphound.cs b/src/Sharphound.cs index 1229650..f0cebd1 100644 --- a/src/Sharphound.cs +++ b/src/Sharphound.cs @@ -104,7 +104,8 @@ await options.WithParsedAsync(async options => DisableSigning = options.DisableSigning, ForceSSL = options.ForceSecureLDAP, AuthType = AuthType.Negotiate, - DisableCertVerification = options.DisableCertVerification + DisableCertVerification = options.DisableCertVerification, + SkipDenyAcesCount = options.SkipDenyAcesCount }; if (options.DomainController != null) ldapOptions.Server = options.DomainController; @@ -264,4 +265,4 @@ public static void InvokeSharpHound(string[] args) { } #endregion -} \ No newline at end of file +} From b2079f19fcd2e054a226d295dfa0e9a4e72e8071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20B=C3=BClow=20Knudsen?= <12843299+JonasBK@users.noreply.github.com> Date: Thu, 14 May 2026 20:41:23 +0200 Subject: [PATCH 2/3] Delete .codex --- .codex | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .codex diff --git a/.codex b/.codex deleted file mode 100644 index e69de29..0000000 From a671f27424f8966239ac328fb62ac62e083a3897 Mon Sep 17 00:00:00 2001 From: JonasBK Date: Fri, 3 Jul 2026 15:47:47 +0200 Subject: [PATCH 3/3] update deny aces implementation --- src/Client/Flags.cs | 3 +- src/Runtime/ObjectProcessors.cs | 79 +++++++++++++++++++-------------- src/Sharphound.cs | 4 +- 3 files changed, 49 insertions(+), 37 deletions(-) diff --git a/src/Client/Flags.cs b/src/Client/Flags.cs index 0f04ccc..234f0f4 100644 --- a/src/Client/Flags.cs +++ b/src/Client/Flags.cs @@ -22,6 +22,7 @@ public class Flags public bool NoRegistryLoggedOn { get; set; } public bool DumpComputerStatus { get; set; } public bool CollectAllProperties { get; set; } + public bool SkipDenyAcesCount { get; set; } public bool DCOnly { get; set; } public bool PrettyPrint { get; set; } public bool SearchForest { get; set; } @@ -30,4 +31,4 @@ public class Flags public bool ParititonLdapQueries { get; set; } public bool Metrics { get; set; } } -} \ No newline at end of file +} diff --git a/src/Runtime/ObjectProcessors.cs b/src/Runtime/ObjectProcessors.cs index 5d2f5e6..89f8acf 100644 --- a/src/Runtime/ObjectProcessors.cs +++ b/src/Runtime/ObjectProcessors.cs @@ -22,6 +22,8 @@ namespace Sharphound.Runtime { public class ObjectProcessors { private const string StatusSuccess = "Success"; + private const string CustomExplicitDenyAcesCountProperty = "customexplicitdenyacescount"; + private const string CustomInheritedDenyAcesCountProperty = "custominheriteddenyacescount"; private readonly ACLProcessor _aclProcessor; private readonly CertAbuseProcessor _certAbuseProcessor; private readonly CancellationToken _cancellationToken; @@ -165,6 +167,28 @@ private string GetAdminSdHolderHash(string domain) return null; } + private async Task ProcessACL(IDirectoryObject entry, ResolvedSearchResult resolvedSearchResult, + Dictionary properties) { + if (_context.Flags.SkipDenyAcesCount) { + return await _aclProcessor.ProcessACL(resolvedSearchResult, entry, true) + .ToArrayAsync(cancellationToken: _cancellationToken); + } + + var result = await _aclProcessor.ProcessACLWithCustomDenyAces(resolvedSearchResult, entry); + AddCustomDenyAceCounts(properties, result.CustomDenyAceCounts); + return result.Aces; + } + + private static void AddCustomDenyAceCounts(Dictionary properties, + ACLProcessor.CustomDenyAceCounts counts) { + if (counts.Total == 0) { + return; + } + + properties[CustomExplicitDenyAcesCountProperty] = counts.ExplicitCount; + properties[CustomInheritedDenyAcesCountProperty] = counts.InheritedCount; + } + private async Task ProcessUserObject(IDirectoryObject entry, ResolvedSearchResult resolvedSearchResult) { @@ -185,8 +209,7 @@ private async Task ProcessUserObject(IDirectoryObject entry, // AdminSDHolderProtected only on security principal nodes: User, Computer, Group var adminSdHolderHash = GetAdminSdHolderHash(resolvedSearchResult.Domain); - var aces = await _aclProcessor.ProcessACL(resolvedSearchResult, entry, true) - .ToArrayAsync(cancellationToken: _cancellationToken); + var aces = await ProcessACL(entry, resolvedSearchResult, ret.Properties); ret.Properties.Add("doesanyacegrantownerrights", aces.Any(ace => ace.IsPermissionForOwnerRightsSid)); ret.Properties.Add("doesanyinheritedacegrantownerrights", aces.Any(ace => ace.IsInheritedPermissionForOwnerRightsSid)); var gmsa = entry.GetByteProperty(LDAPProperties.GroupMSAMembership); @@ -262,8 +285,7 @@ ResolvedSearchResult resolvedSearchResult // AdminSDHolderProtected only on security principal nodes: User, Computer, Group var adminSdHolderHash = GetAdminSdHolderHash(resolvedSearchResult.Domain); - var aces = await _aclProcessor.ProcessACL(resolvedSearchResult, entry, true) - .ToArrayAsync(cancellationToken: _cancellationToken); + var aces = await ProcessACL(entry, resolvedSearchResult, ret.Properties); ret.Properties.Add("doesanyacegrantownerrights", aces.Any(ace => ace.IsPermissionForOwnerRightsSid)); ret.Properties.Add("doesanyinheritedacegrantownerrights", aces.Any(ace => ace.IsInheritedPermissionForOwnerRightsSid)); ret.Aces = aces; @@ -475,8 +497,7 @@ private async Task ProcessGroupObject(IDirectoryObject entry, // AdminSDHolderProtected only on security principal nodes: User, Computer, Group var adminSdHolderHash = GetAdminSdHolderHash(resolvedSearchResult.Domain); - var aces = await _aclProcessor.ProcessACL(resolvedSearchResult, entry, true) - .ToArrayAsync(cancellationToken: _cancellationToken); + var aces = await ProcessACL(entry, resolvedSearchResult, ret.Properties); ret.Properties.Add("doesanyacegrantownerrights", aces.Any(ace => ace.IsPermissionForOwnerRightsSid)); ret.Properties.Add("doesanyinheritedacegrantownerrights", aces.Any(ace => ace.IsInheritedPermissionForOwnerRightsSid)); ret.Aces = aces; @@ -528,8 +549,7 @@ await _context.LDAPUtils.GetDomainSidFromDomainName(forest) is (true, var forest ret.Properties = new Dictionary(GetCommonProperties(entry, resolvedSearchResult)); if (_methods.HasFlag(CollectionMethod.ACL)) { - var aces = await _aclProcessor.ProcessACL(resolvedSearchResult, entry, true) - .ToArrayAsync(cancellationToken: _cancellationToken); + var aces = await ProcessACL(entry, resolvedSearchResult, ret.Properties); ret.Aces = aces; ret.Properties.Add("doesanyacegrantownerrights", aces.Any(ace => ace.IsPermissionForOwnerRightsSid)); ret.Properties.Add("doesanyinheritedacegrantownerrights", aces.Any(ace => ace.IsInheritedPermissionForOwnerRightsSid)); @@ -571,8 +591,7 @@ private async Task ProcessGPOObject(IDirectoryObject entry, ret.Properties = new Dictionary(GetCommonProperties(entry, resolvedSearchResult)); if (_methods.HasFlag(CollectionMethod.ACL)) { - var aces = await _aclProcessor.ProcessACL(resolvedSearchResult, entry, true) - .ToArrayAsync(cancellationToken: _cancellationToken); + var aces = await ProcessACL(entry, resolvedSearchResult, ret.Properties); ret.Properties.Add("doesanyacegrantownerrights", aces.Any(ace => ace.IsPermissionForOwnerRightsSid)); ret.Properties.Add("doesanyinheritedacegrantownerrights", aces.Any(ace => ace.IsInheritedPermissionForOwnerRightsSid)); ret.Aces = aces; @@ -581,7 +600,7 @@ private async Task ProcessGPOObject(IDirectoryObject entry, } if (_methods.HasFlag(CollectionMethod.ObjectProps)) { - ret.Properties = ContextUtils.Merge(ret.Properties, await _ldapPropertyProcessor.ReadGPOProperties(entry)); + ret.Properties = ContextUtils.Merge(ret.Properties, LdapPropertyProcessor.ReadGPOProperties(entry)); if (_context.Flags.CollectAllProperties) { ret.Properties = ContextUtils.Merge(_ldapPropertyProcessor.ParseAllProperties(entry), ret.Properties); @@ -600,8 +619,7 @@ private async Task ProcessOUObject(IDirectoryObject entry, ret.Properties = new Dictionary(GetCommonProperties(entry, resolvedSearchResult)); if (_methods.HasFlag(CollectionMethod.ACL)) { - var aces = await _aclProcessor.ProcessACL(resolvedSearchResult, entry, true) - .ToArrayAsync(cancellationToken: _cancellationToken); + var aces = await ProcessACL(entry, resolvedSearchResult, ret.Properties); ret.Properties.Add("doesanyacegrantownerrights", aces.Any(ace => ace.IsPermissionForOwnerRightsSid)); ret.Properties.Add("doesanyinheritedacegrantownerrights", aces.Any(ace => ace.IsInheritedPermissionForOwnerRightsSid)); ret.Aces = aces; @@ -611,7 +629,7 @@ private async Task ProcessOUObject(IDirectoryObject entry, } if (_methods.HasFlag(CollectionMethod.ObjectProps)) { - ret.Properties = ContextUtils.Merge(ret.Properties, await _ldapPropertyProcessor.ReadOUProperties(entry)); + ret.Properties = ContextUtils.Merge(ret.Properties, LdapPropertyProcessor.ReadOUProperties(entry)); if (_context.Flags.CollectAllProperties) { ret.Properties = ContextUtils.Merge(_ldapPropertyProcessor.ParseAllProperties(entry), ret.Properties); @@ -650,8 +668,7 @@ private async Task ProcessContainerObject(IDirectoryObject entry, } if (_methods.HasFlag(CollectionMethod.ACL) || _methods.HasFlag(CollectionMethod.CertServices)) { - var aces = await _aclProcessor.ProcessACL(resolvedSearchResult, entry, true) - .ToArrayAsync(cancellationToken: _cancellationToken); + var aces = await ProcessACL(entry, resolvedSearchResult, ret.Properties); ret.Properties.Add("doesanyacegrantownerrights", aces.Any(ace => ace.IsPermissionForOwnerRightsSid)); ret.Properties.Add("doesanyinheritedacegrantownerrights", aces.Any(ace => ace.IsInheritedPermissionForOwnerRightsSid)); ret.Aces = aces; @@ -662,7 +679,7 @@ private async Task ProcessContainerObject(IDirectoryObject entry, if (_methods.HasFlag(CollectionMethod.ObjectProps) || _methods.HasFlag(CollectionMethod.CertServices)) { ret.Properties = - ContextUtils.Merge(await _ldapPropertyProcessor.ReadContainerProperties(entry), ret.Properties); + ContextUtils.Merge(LdapPropertyProcessor.ReadContainerProperties(entry), ret.Properties); if (_context.Flags.CollectAllProperties) { ret.Properties = ContextUtils.Merge(_ldapPropertyProcessor.ParseAllProperties(entry), ret.Properties); @@ -683,8 +700,7 @@ private async Task ProcessRootCA(IDirectoryObject entry, ResolvedSearchR if (_methods.HasFlag(CollectionMethod.ACL) || _methods.HasFlag(CollectionMethod.CertServices)) { - var aces = await _aclProcessor.ProcessACL(resolvedSearchResult, entry, true) - .ToArrayAsync(cancellationToken: _cancellationToken); + var aces = await ProcessACL(entry, resolvedSearchResult, ret.Properties); ret.Properties.Add("doesanyacegrantownerrights", aces.Any(ace => ace.IsPermissionForOwnerRightsSid)); ret.Properties.Add("doesanyinheritedacegrantownerrights", aces.Any(ace => ace.IsInheritedPermissionForOwnerRightsSid)); ret.Aces = aces; @@ -693,7 +709,7 @@ private async Task ProcessRootCA(IDirectoryObject entry, ResolvedSearchR } if (_methods.HasFlag(CollectionMethod.ObjectProps) || _methods.HasFlag(CollectionMethod.CertServices)) { - var props = await _ldapPropertyProcessor.ReadRootCAProperties(entry); + var props = LdapPropertyProcessor.ReadRootCAProperties(entry); ret.Properties.Merge(props); } @@ -714,8 +730,7 @@ private async Task ProcessAIACA(IDirectoryObject entry, ResolvedSearchRes ret.Properties = new Dictionary(GetCommonProperties(entry, resolvedSearchResult)); if (_methods.HasFlag(CollectionMethod.ACL) || _methods.HasFlag(CollectionMethod.CertServices)) { - var aces = await _aclProcessor.ProcessACL(resolvedSearchResult, entry, true) - .ToArrayAsync(cancellationToken: _cancellationToken); + var aces = await ProcessACL(entry, resolvedSearchResult, ret.Properties); ret.Properties.Add("doesanyacegrantownerrights", aces.Any(ace => ace.IsPermissionForOwnerRightsSid)); ret.Properties.Add("doesanyinheritedacegrantownerrights", aces.Any(ace => ace.IsInheritedPermissionForOwnerRightsSid)); ret.Aces = aces; @@ -724,7 +739,7 @@ private async Task ProcessAIACA(IDirectoryObject entry, ResolvedSearchRes } if (_methods.HasFlag(CollectionMethod.ObjectProps) || _methods.HasFlag(CollectionMethod.CertServices)) { - var props = await _ldapPropertyProcessor.ReadAIACAProperties(entry); + var props = LdapPropertyProcessor.ReadAIACAProperties(entry); ret.Properties.Merge(props); } @@ -744,8 +759,7 @@ private async Task ProcessEnterpriseCA(IDirectoryObject entry, Res }; if (_methods.HasFlag(CollectionMethod.ACL) || _methods.HasFlag(CollectionMethod.CertServices)) { - var aces = await _aclProcessor.ProcessACL(resolvedSearchResult, entry, true) - .ToArrayAsync(cancellationToken: _cancellationToken); + var aces = await ProcessACL(entry, resolvedSearchResult, ret.Properties); ret.Properties.Add("doesanyacegrantownerrights", aces.Any(ace => ace.IsPermissionForOwnerRightsSid)); ret.Properties.Add("doesanyinheritedacegrantownerrights", aces.Any(ace => ace.IsInheritedPermissionForOwnerRightsSid)); ret.Aces = aces; @@ -754,7 +768,7 @@ private async Task ProcessEnterpriseCA(IDirectoryObject entry, Res } if (_methods.HasFlag(CollectionMethod.ObjectProps) || _methods.HasFlag(CollectionMethod.CertServices)) { - var props = await _ldapPropertyProcessor.ReadEnterpriseCAProperties(entry); + var props = LdapPropertyProcessor.ReadEnterpriseCAProperties(entry); ret.Properties.Merge(props); // Enabled cert templates @@ -861,8 +875,7 @@ private async Task ProcessNTAuthStore(IDirectoryObject entry, ret.Properties = new Dictionary(GetCommonProperties(entry, resolvedSearchResult)); if (_methods.HasFlag(CollectionMethod.ACL) || _methods.HasFlag(CollectionMethod.CertServices)) { - var aces = await _aclProcessor.ProcessACL(resolvedSearchResult, entry, true) - .ToArrayAsync(cancellationToken: _cancellationToken); + var aces = await ProcessACL(entry, resolvedSearchResult, ret.Properties); ret.Properties.Add("doesanyacegrantownerrights", aces.Any(ace => ace.IsPermissionForOwnerRightsSid)); ret.Properties.Add("doesanyinheritedacegrantownerrights", aces.Any(ace => ace.IsInheritedPermissionForOwnerRightsSid)); ret.Aces = aces; @@ -871,7 +884,7 @@ private async Task ProcessNTAuthStore(IDirectoryObject entry, } if (_methods.HasFlag(CollectionMethod.ObjectProps) || _methods.HasFlag(CollectionMethod.CertServices)) { - var props = await _ldapPropertyProcessor.ReadNTAuthStoreProperties(entry); + var props = LdapPropertyProcessor.ReadNTAuthStoreProperties(entry); if (entry.TryGetByteArrayProperty(LDAPProperties.CACertificate, out var rawCertificates)) { var certificates = from rawCertificate in rawCertificates @@ -900,8 +913,7 @@ private async Task ProcessCertTemplate(IDirectoryObject entry, ret.Properties = new Dictionary(GetCommonProperties(entry, resolvedSearchResult)); if (_methods.HasFlag(CollectionMethod.ACL) || _methods.HasFlag(CollectionMethod.CertServices)) { - var aces = await _aclProcessor.ProcessACL(resolvedSearchResult, entry, true) - .ToArrayAsync(cancellationToken: _cancellationToken); + var aces = await ProcessACL(entry, resolvedSearchResult, ret.Properties); ret.Properties.Add("doesanyacegrantownerrights", aces.Any(ace => ace.IsPermissionForOwnerRightsSid)); ret.Properties.Add("doesanyinheritedacegrantownerrights", aces.Any(ace => ace.IsInheritedPermissionForOwnerRightsSid)); ret.Aces = aces; @@ -910,7 +922,7 @@ private async Task ProcessCertTemplate(IDirectoryObject entry, } if (_methods.HasFlag(CollectionMethod.ObjectProps) || _methods.HasFlag(CollectionMethod.CertServices)) { - var certTemplatesProps = await _ldapPropertyProcessor.ReadCertTemplateProperties(entry); + var certTemplatesProps = LdapPropertyProcessor.ReadCertTemplateProperties(entry); ret.Properties.Merge(certTemplatesProps); } @@ -932,8 +944,7 @@ private async Task ProcessIssuancePolicy(IDirectoryObject entry, ret.Properties = new Dictionary(GetCommonProperties(entry, resolvedSearchResult)); if (_methods.HasFlag(CollectionMethod.ACL) || _methods.HasFlag(CollectionMethod.CertServices)) { - var aces = await _aclProcessor.ProcessACL(resolvedSearchResult, entry, true) - .ToArrayAsync(cancellationToken: _cancellationToken); + var aces = await ProcessACL(entry, resolvedSearchResult, ret.Properties); ret.Properties.Add("doesanyacegrantownerrights", aces.Any(ace => ace.IsPermissionForOwnerRightsSid)); ret.Properties.Add("doesanyinheritedacegrantownerrights", aces.Any(ace => ace.IsInheritedPermissionForOwnerRightsSid)); ret.Aces = aces; diff --git a/src/Sharphound.cs b/src/Sharphound.cs index f0cebd1..443ee94 100644 --- a/src/Sharphound.cs +++ b/src/Sharphound.cs @@ -88,6 +88,7 @@ await options.WithParsedAsync(async options => RandomizeFilenames = options.RandomFileNames, MemCache = options.MemCache, CollectAllProperties = options.CollectAllProperties, + SkipDenyAcesCount = options.SkipDenyAcesCount, DCOnly = dconly, PrettyPrint = options.PrettyPrint, SearchForest = options.SearchForest, @@ -104,8 +105,7 @@ await options.WithParsedAsync(async options => DisableSigning = options.DisableSigning, ForceSSL = options.ForceSecureLDAP, AuthType = AuthType.Negotiate, - DisableCertVerification = options.DisableCertVerification, - SkipDenyAcesCount = options.SkipDenyAcesCount + DisableCertVerification = options.DisableCertVerification }; if (options.DomainController != null) ldapOptions.Server = options.DomainController;