Skip to content

Commit

Permalink
feat: add certservices collection method
Browse files Browse the repository at this point in the history
  • Loading branch information
urangel committed Nov 17, 2023
1 parent b817b82 commit 8d02dba
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 38 deletions.
1 change: 1 addition & 0 deletions src/Client/Enums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public enum CollectionMethodOptions
ComputerOnly,
CARegistry,
DCRegistry,
CertServices,
All
}
}
19 changes: 10 additions & 9 deletions src/Options.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class Options
// Options that affect what is collected
[Option('c', "collectionmethods", Default = new[] { "Default" },
HelpText =
"Collection Methods: Group, LocalGroup, LocalAdmin, RDP, DCOM, PSRemote, Session, Trusts, ACL, Container, ComputerOnly, GPOLocalGroup, LoggedOn, ObjectProps, SPNTargets, UserRights, Default, DCOnly, CARegistry, DCRegistry, All")]
"Collection Methods: Group, LocalGroup, LocalAdmin, RDP, DCOM, PSRemote, Session, Trusts, ACL, Container, ComputerOnly, GPOLocalGroup, LoggedOn, ObjectProps, SPNTargets, UserRights, Default, DCOnly, CARegistry, DCRegistry, CertServices, All")]
public IEnumerable<string> CollectionMethods { get; set; }

[Option('d', "domain", Default = null, HelpText = "Specify domain to enumerate")]
Expand Down Expand Up @@ -61,7 +61,7 @@ public class Options

[Option(HelpText = "Don't zip files", Default = false)]
public bool NoZip { get; set; }

[Option(HelpText = "Password protects the zip with the specified password", Default = null)]
public string ZipPassword { get; set; }

Expand All @@ -87,7 +87,7 @@ public class Options

[Option(HelpText = "Connect to LDAP SSL instead of regular LDAP", Default = false)]
public bool SecureLDAP { get; set; }

[Option(HelpText = "Disables certificate verification when using LDAPS", Default = false)]
public bool DisableCertVerification { get; set; }

Expand All @@ -97,10 +97,10 @@ public class Options
//Options that affect how enumeration is performed
[Option(HelpText = "Skip checking if 445 is open", Default = false)]
public bool SkipPortCheck { get; set; }

[Option(HelpText = "Timeout for port checks in milliseconds", Default = 500)]
public int PortCheckTimeout { get; set; }

[Option(HelpText = "Skip check for PwdLastSet when enumerating computers", Default = false)]
public bool SkipPasswordCheck { get; set; }

Expand All @@ -114,7 +114,7 @@ public class Options
[Option(HelpText = "Add jitter to throttle (percent)")]
public int Jitter { get; set; }

[Option('t',"threads", HelpText = "Number of threads to run enumeration with", Default = 50)]
[Option('t', "threads", HelpText = "Number of threads to run enumeration with", Default = 50)]
public int Threads { get; set; }

[Option(HelpText = "Skip registry session enumeration")]
Expand All @@ -133,10 +133,10 @@ public class Options
[Option('l', "Loop", HelpText = "Loop computer collection")]
public bool Loop { get; set; }

[Option(HelpText="Loop duration (hh:mm:ss - 05:00:00 is 5 hours, default: 2 hrs)")]
[Option(HelpText = "Loop duration (hh:mm:ss - 05:00:00 is 5 hours, default: 2 hrs)")]
public TimeSpan LoopDuration { get; set; }

[Option(HelpText="Add delay between loops (hh:mm:ss - 00:03:00 is 3 minutes)")] public TimeSpan LoopInterval { get; set; }
[Option(HelpText = "Add delay between loops (hh:mm:ss - 00:03:00 is 3 minutes)")] public TimeSpan LoopInterval { get; set; }

//Misc Options
[Option(HelpText = "Interval in which to display status in milliseconds", Default = 30000)]
Expand Down Expand Up @@ -189,6 +189,7 @@ internal bool ResolveCollectionMethods(ILogger logger, out ResolvedCollectionMet
CollectionMethodOptions.ComputerOnly => ResolvedCollectionMethod.ComputerOnly,
CollectionMethodOptions.CARegistry => ResolvedCollectionMethod.CARegistry,
CollectionMethodOptions.DCRegistry => ResolvedCollectionMethod.DCRegistry,
CollectionMethodOptions.CertServices => ResolvedCollectionMethod.CertServices,
CollectionMethodOptions.All => ResolvedCollectionMethod.All,
CollectionMethodOptions.None => ResolvedCollectionMethod.None,
_ => throw new ArgumentOutOfRangeException()
Expand Down Expand Up @@ -234,7 +235,7 @@ internal bool ResolveCollectionMethods(ILogger logger, out ResolvedCollectionMet
resolved ^= ResolvedCollectionMethod.LocalAdmin;
updates.Add("[-] Removed LocalAdmin Collection");
}

if ((resolved & ResolvedCollectionMethod.CARegistry) != 0)
{
resolved ^= ResolvedCollectionMethod.CARegistry;
Expand Down
56 changes: 34 additions & 22 deletions src/Producers/BaseProducer.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
using System.Collections.Generic;

using System.Threading.Channels;

using System.Threading.Tasks;

using Sharphound.Client;

using SharpHoundCommonLib;

using SharpHoundCommonLib.Enums;

using SharpHoundCommonLib.LDAPQueries;

using SharpHoundCommonLib.OutputTypes;

namespace Sharphound.Producers
Expand All @@ -28,7 +35,7 @@ protected BaseProducer(IContext context, Channel<ISearchResultEntry> channel, Ch
public abstract Task Produce();
public abstract Task ProduceConfigNC();

protected LDAPData CreateLDAPData()
protected LDAPData CreateDefaultNCData()
{
var query = new LDAPFilter();
var props = new List<string>();
Expand Down Expand Up @@ -60,9 +67,9 @@ protected LDAPData CreateLDAPData()
(methods & ResolvedCollectionMethod.RDP) != 0 ||
(methods & ResolvedCollectionMethod.LoggedOn) != 0 ||
(methods & ResolvedCollectionMethod.Session) != 0 ||
(methods & ResolvedCollectionMethod.ObjectProps) != 0 ||
(methods & ResolvedCollectionMethod.ObjectProps) != 0 ||
(methods & ResolvedCollectionMethod.UserRights) != 0)

props.AddRange(CommonProperties.ComputerMethodProps);

if ((methods & ResolvedCollectionMethod.Trusts) != 0) props.AddRange(CommonProperties.DomainTrustProps);
Expand Down Expand Up @@ -96,7 +103,7 @@ protected LDAPData CreateLDAPData()
(methods & ResolvedCollectionMethod.RDP) != 0 ||
(methods & ResolvedCollectionMethod.LoggedOn) != 0 ||
(methods & ResolvedCollectionMethod.Session) != 0 ||
(methods & ResolvedCollectionMethod.ObjectProps) != 0 ||
(methods & ResolvedCollectionMethod.ObjectProps) != 0 ||
(methods & ResolvedCollectionMethod.UserRights) != 0)
{
query = query.AddComputers();
Expand Down Expand Up @@ -144,34 +151,39 @@ protected LDAPData CreateConfigNCData()
props.AddRange(CommonProperties.TypeResolutionProps);

var methods = Context.ResolvedCollectionMethods;
var allObjectTypesQuery = query.AddContainers().AddConfiguration().AddCertificateTemplates().AddCertificateAuthorities().AddEnterpriseCertificationAuthorities();

if ((methods & ResolvedCollectionMethod.ObjectProps) != 0 || (methods & ResolvedCollectionMethod.ACL) != 0)
if ((methods & ResolvedCollectionMethod.ObjectProps) != 0)
{
query = query.AddContainers().AddConfiguration().AddCertificateTemplates().AddCertificateAuthorities().AddEnterpriseCertificationAuthorities();
query = allObjectTypesQuery;
props.AddRange(CommonProperties.ObjectPropsProps);
props.AddRange(CommonProperties.CertAbuseProps);
}

if ((methods & ResolvedCollectionMethod.Container) != 0)
props.AddRange(CommonProperties.ContainerProps);
if ((methods & ResolvedCollectionMethod.ACL) != 0)
{
query = allObjectTypesQuery;
props.AddRange(CommonProperties.ACLProps);
}

if ((methods & ResolvedCollectionMethod.ACL) != 0)
props.AddRange(CommonProperties.ACLProps);
if ((methods & ResolvedCollectionMethod.CertServices) != 0)
{
query = allObjectTypesQuery;
props.AddRange(CommonProperties.CertAbuseProps);
}
else

if ((methods & ResolvedCollectionMethod.Container) != 0)
{
if ((methods & ResolvedCollectionMethod.Container) != 0)
{
query = query.AddContainers().AddConfiguration().AddCertificateTemplates().AddCertificateAuthorities().AddEnterpriseCertificationAuthorities();
props.AddRange(CommonProperties.ContainerProps);
}
query = allObjectTypesQuery;
props.AddRange(CommonProperties.ContainerProps);
}

if ((methods & ResolvedCollectionMethod.CARegistry) != 0)
{
query = query.AddEnterpriseCertificationAuthorities();
props.AddRange(CommonProperties.CertAbuseProps);
}
if ((methods & ResolvedCollectionMethod.CARegistry) != 0)
{
query = query.AddEnterpriseCertificationAuthorities();
props.AddRange(CommonProperties.CertAbuseProps);
}


if (Context.LdapFilter != null) query.AddFilter(Context.LdapFilter, true);

data.Filter = query;
Expand Down
2 changes: 1 addition & 1 deletion src/Producers/ComputerFileProducer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public override async Task Produce()
var computerFile = Context.ComputerFile;
var cancellationToken = Context.CancellationTokenSource.Token;

var ldapData = CreateLDAPData();
var ldapData = CreateDefaultNCData();

try
{
Expand Down
8 changes: 4 additions & 4 deletions src/Producers/LdapProducer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public override async Task Produce()
{
var cancellationToken = Context.CancellationTokenSource.Token;

var ldapData = CreateLDAPData();
var ldapData = CreateDefaultNCData();

var log = Context.Logger;
var utils = Context.LDAPUtils;
Expand Down Expand Up @@ -67,7 +67,7 @@ await OutputChannel.Writer.WriteAsync(new Domain
{ "collected", true },
}
});

foreach (var searchResult in Context.LDAPUtils.QueryLDAP(ldapData.Filter.GetFilter(), SearchScope.Subtree,
ldapData.Props.Distinct().ToArray(), cancellationToken, domain.Name,
adsPath: Context.SearchBase,
Expand All @@ -83,7 +83,7 @@ await OutputChannel.Writer.WriteAsync(new Domain
Context.Logger.LogTrace("Producer wrote {DistinguishedName} to channel", searchResult.DistinguishedName);
}
}

}

/// <summary>
Expand Down Expand Up @@ -121,7 +121,7 @@ public override async Task ProduceConfigNC()
Context.Logger.LogTrace("Skipping already collected config NC '{path}' for domain {Domain}", configAdsPath, domain.Name);
}
}

}

}
Expand Down
4 changes: 2 additions & 2 deletions src/Producers/StealthProducer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ internal class StealthProducer : BaseProducer

public StealthProducer(IContext context, Channel<ISearchResultEntry> channel, Channel<OutputBase> outputChannel) : base(context, channel, outputChannel)
{
var ldapData = CreateLDAPData();
var ldapData = CreateDefaultNCData();
_query = ldapData.Filter;
_props = ldapData.Props;

Expand Down Expand Up @@ -124,7 +124,7 @@ private async Task<Dictionary<string, ISearchResultEntry>> FindPathTargetSids()
}
});
}



// Loop over the paths we grabbed, and resolve them to sids.
Expand Down

0 comments on commit 8d02dba

Please sign in to comment.