Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: SpecterOps/SharpHound
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.0.2
Choose a base ref
...
head repository: SpecterOps/SharpHound
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v1.0.3
Choose a head ref
  • 13 commits
  • 8 files changed
  • 3 contributors

Commits on Feb 23, 2022

  1. Copy the full SHA
    fa7538e View commit details
  2. Copy the full SHA
    555c1a9 View commit details
  3. docs: update readme

    rvazarkar committed Feb 23, 2022
    Copy the full SHA
    f0ff337 View commit details
  4. Copy the full SHA
    570464c View commit details
  5. Copy the full SHA
    811fe6c View commit details
  6. Copy the full SHA
    35eb874 View commit details

Commits on Mar 2, 2022

  1. Copy the full SHA
    f076806 View commit details
  2. Merge pull request #11 from BloodHoundAD/fix-highvalue

    fix: ensure highlevel is being set on all objects
    rvazarkar authored Mar 2, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    c3e15ba View commit details
  3. fix: update commonlib version to fix netonly issues

    fix: initialize commonlib logging early
    rvazarkar committed Mar 2, 2022
    Copy the full SHA
    8768f8e View commit details
  4. Copy the full SHA
    b2d21a7 View commit details
  5. Copy the full SHA
    6b356fc View commit details

Commits on Mar 7, 2022

  1. Copy the full SHA
    16f48bf View commit details
  2. Copy the full SHA
    97f5d42 View commit details
Showing with 74 additions and 16 deletions.
  1. +3 −1 FodyWeavers.xml
  2. +1 −1 README.md
  3. +9 −10 Sharphound.csproj
  4. +1 −1 src/Client/Flags.cs
  5. +3 −0 src/Producers/BaseProducer.cs
  6. +1 −0 src/Producers/LdapProducer.cs
  7. +32 −1 src/Runtime/ObjectProcessors.cs
  8. +24 −2 src/Sharphound.cs
4 changes: 3 additions & 1 deletion FodyWeavers.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ILMerge HideImportedTypes="false"/>
<!-- <ILMerge HideImportedTypes="false" CompactMode="false" IncludeAssemblies="System.ValueTuple|CommandLine|ICSharpCode.*|Microsoft.*|SharpHoundCommon.*|System.*|Utf8.*" />-->
<!-- TODO: Remove these excludes when CS fixes their size limit -->
<Costura IncludeDebugSymbols="false" ExcludeAssemblies="System.Console|System.Diagnostics.Tracing|System.Globalization.Calendar|System.Net.Http" />
</Weavers>
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
SharpHound Open Source Client version: 1.0
SharpHound Open Source Client version: 1.0.2
---

# SharpHound
19 changes: 9 additions & 10 deletions Sharphound.csproj
Original file line number Diff line number Diff line change
@@ -6,37 +6,36 @@
<LangVersion>latest</LangVersion>
<DebugType>full</DebugType>
<ApplicationIcon>favicon.ico</ApplicationIcon>
<Version>1.0.1</Version>
<FileVersion>1.0.1</FileVersion>
<Version>1.0.3</Version>
<FileVersion>1.0.3</FileVersion>
<Company>SpecterOps</Company>
<Product>SharpHound</Product>
<AssemblyName>SharpHound</AssemblyName>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="CommandLineParser" Version="2.9.0-preview1" />
<PackageReference Include="CommandLineParser" Version="2.8.0" />
<PackageReference Include="Costura.Fody" Version="5.7.0">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Fody" Version="6.6.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="ILMerge.Fody" Version="1.22.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" />
<PackageReference Include="SharpHoundCommon" Version="2.0.12" />
<PackageReference Include="SharpHoundCommon" Version="2.0.13" />
<PackageReference Include="SharpZipLib" Version="1.3.3" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
<PackageReference Include="System.Threading.Channels" Version="6.0.0" />
<PackageReference Include="Utf8Json" Version="1.3.7" />
</ItemGroup>

<ItemGroup>
<!-- <Reference Include="SharpHoundCommonLib, Version=2.0.10.0, Culture=neutral, PublicKeyToken=null">-->
<!-- <Reference Include="SharpHoundCommonLib, Version=2.0.12.0, Culture=neutral, PublicKeyToken=null">-->
<!-- <HintPath>..\SharpHoundCommon\src\CommonLib\bin\Debug\net462\SharpHoundCommonLib.dll</HintPath>-->
<!-- </Reference>-->
<Reference Include="System.DirectoryServices" />
<Reference Include="System.DirectoryServices.Protocols" />
<Reference Include="System.IO.Compression" />
</ItemGroup>


</Project>
2 changes: 1 addition & 1 deletion src/Client/Flags.cs
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ public class Flags
public bool IsFaulted { get; set; }
public bool NoOutput { get; set; }
public bool RandomizeFilenames { get; set; }
public bool NoSaveCache { get; set; }
public bool MemCache { get; set; }
public bool NoZip { get; set; }
public bool InvalidateCache { get; set; }
public bool SecureLDAP { get; set; }
3 changes: 3 additions & 0 deletions src/Producers/BaseProducer.cs
Original file line number Diff line number Diff line change
@@ -43,7 +43,10 @@ protected LDAPData CreateLDAPData()
props.AddRange(CommonProperties.ContainerProps);

if ((methods & ResolvedCollectionMethod.Group) != 0)
{
props.AddRange(CommonProperties.GroupResolutionProps);
query = query.AddPrimaryGroups();
}

if ((methods & ResolvedCollectionMethod.ACL) != 0) props.AddRange(CommonProperties.ACLProps);

1 change: 1 addition & 0 deletions src/Producers/LdapProducer.cs
Original file line number Diff line number Diff line change
@@ -41,6 +41,7 @@ public override async Task Produce()
continue;

await Channel.Writer.WriteAsync(searchResult, cancellationToken);
Context.Logger.LogTrace("Producer wrote {DistinguishedName} to channel", searchResult.DistinguishedName);
}
}

33 changes: 32 additions & 1 deletion src/Runtime/ObjectProcessors.cs
Original file line number Diff line number Diff line change
@@ -85,6 +85,7 @@ private async Task<User> ProcessUserObject(ISearchResultEntry entry,
ret.Properties.Add("name", resolvedSearchResult.DisplayName);
ret.Properties.Add("distinguishedname", entry.DistinguishedName.ToUpper());
ret.Properties.Add("domainsid", resolvedSearchResult.DomainSid);
ret.Properties.Add("highvalue", false);

if ((_methods & ResolvedCollectionMethod.ACL) != 0)
{
@@ -136,6 +137,7 @@ private async Task<Computer> ProcessComputerObject(ISearchResultEntry entry,
ret.Properties.Add("name", resolvedSearchResult.DisplayName);
ret.Properties.Add("distinguishedname", entry.DistinguishedName.ToUpper());
ret.Properties.Add("domainsid", resolvedSearchResult.DomainSid);
ret.Properties.Add("highvalue", false);

var hasLaps = entry.HasLAPS();
ret.Properties.Add("haslaps", hasLaps);
@@ -320,6 +322,7 @@ private Group ProcessGroupObject(ISearchResultEntry entry,
ret.Properties.Add("name", resolvedSearchResult.DisplayName);
ret.Properties.Add("distinguishedname", entry.DistinguishedName.ToUpper());
ret.Properties.Add("domainsid", resolvedSearchResult.DomainSid);
ret.Properties.Add("highvalue", IsHighValueGroup(resolvedSearchResult.ObjectId));

if ((_methods & ResolvedCollectionMethod.ACL) != 0)
{
@@ -341,6 +344,30 @@ private Group ProcessGroupObject(ISearchResultEntry entry,
return ret;
}

private bool IsHighValueGroup(string objectId)
{
// TODO: replace w/ a more definitive/centralized list
var suffixes = new string []
{
"-512",
"-516",
"-519",
"S-1-5-32-544",
"S-1-5-32-548",
"S-1-5-32-549",
"S-1-5-32-550",
"S-1-5-32-551",
};
foreach (var suffix in suffixes)
{
if (objectId.EndsWith(suffix))
{
return true;
}
}
return false;
}

private async Task<Domain> ProcessDomainObject(ISearchResultEntry entry,
ResolvedSearchResult resolvedSearchResult)
{
@@ -353,6 +380,7 @@ private async Task<Domain> ProcessDomainObject(ISearchResultEntry entry,
ret.Properties.Add("name", resolvedSearchResult.DisplayName);
ret.Properties.Add("distinguishedname", entry.DistinguishedName.ToUpper());
ret.Properties.Add("domainsid", resolvedSearchResult.DomainSid);
ret.Properties.Add("highvalue", true);

if ((_methods & ResolvedCollectionMethod.ACL) != 0)
{
@@ -393,6 +421,7 @@ private GPO ProcessGPOObject(ISearchResultEntry entry,
ret.Properties.Add("name", resolvedSearchResult.DisplayName);
ret.Properties.Add("distinguishedname", entry.DistinguishedName.ToUpper());
ret.Properties.Add("domainsid", resolvedSearchResult.DomainSid);
ret.Properties.Add("highvalue", false);

if ((_methods & ResolvedCollectionMethod.ACL) != 0)
{
@@ -418,6 +447,7 @@ private async Task<OU> ProcessOUObject(ISearchResultEntry entry,
ret.Properties.Add("name", resolvedSearchResult.DisplayName);
ret.Properties.Add("distinguishedname", entry.DistinguishedName.ToUpper());
ret.Properties.Add("domainsid", resolvedSearchResult.DomainSid);
ret.Properties.Add("highvalue", false);

if ((_methods & ResolvedCollectionMethod.ACL) != 0)
{
@@ -457,6 +487,7 @@ private Container ProcessContainerObject(ISearchResultEntry entry,
ret.Properties.Add("name", resolvedSearchResult.DisplayName);
ret.Properties.Add("distinguishedname", entry.DistinguishedName.ToUpper());
ret.Properties.Add("domainsid", resolvedSearchResult.DomainSid);
ret.Properties.Add("highvalue", false);

if ((_methods & ResolvedCollectionMethod.Container) != 0)
ret.ChildObjects = _containerProcessor.GetContainerChildObjects(entry.DistinguishedName).ToArray();
@@ -477,4 +508,4 @@ private Container ProcessContainerObject(ISearchResultEntry entry,
return ret;
}
}
}
}
26 changes: 24 additions & 2 deletions src/Sharphound.cs
Original file line number Diff line number Diff line change
@@ -85,6 +85,7 @@ internal class SharpLinks : Links<IContext>
public IContext Initialize(IContext context, LDAPConfig options)
{
context.Logger.LogTrace("Entering initialize link");
CommonLib.ReconfigureLogging(context.Logger);
//We've successfully parsed arguments, lets do some options post-processing.
var currentTime = DateTime.Now;
//var padString = new string('-', initString.Length);
@@ -111,6 +112,24 @@ public IContext Initialize(IContext context, LDAPConfig options)

if (context.LoopInterval == TimeSpan.Zero)
context.LoopInterval = TimeSpan.FromSeconds(30);

if (!context.Flags.NoOutput)
{
var filename = context.ResolveFileName(Path.GetRandomFileName(), "", false);
try
{
using (File.Create(filename))
{
}

File.Delete(filename);
}
catch (Exception e)
{
context.Logger.LogCritical("unable to write to target directory");
context.Flags.IsFaulted = true;
}
}

context.Logger.LogTrace("Exiting initialize link");

@@ -257,6 +276,8 @@ public IContext Finish(IContext context)

public IContext SaveCacheFile(IContext context)
{
if (context.Flags.MemCache)
return context;
// 15. Program exit started. Save the cache file
var cache = Cache.GetCacheInstance();
var serialized = JsonSerializer.Serialize(cache, StandardResolver.AllowPrivate);
@@ -338,7 +359,7 @@ await options.WithParsedAsync(async options =>
NoOutput = false,
Stealth = options.Stealth,
RandomizeFilenames = options.RandomFileNames,
NoSaveCache = options.MemCache,
MemCache = options.MemCache,
CollectAllProperties = options.CollectAllProperties,
DCOnly = dconly,
PrettyPrint = options.PrettyPrint,
@@ -349,7 +370,8 @@ await options.WithParsedAsync(async options =>
{
Port = options.LDAPPort,
DisableSigning = options.DisableSigning,
SSL = options.SecureLDAP
SSL = options.SecureLDAP,
AuthType = AuthType.Negotiate
};

if (options.DomainController != null) ldapOptions.Server = options.DomainController;