Skip to content

Commit a8d2ae5

Browse files
authored
TrustedBy replacement related changes (#196)
* trust enum alternative * add group scope * switch to use ldaputil's GetDomain for trusts * fix type
1 parent 8bd9e78 commit a8d2ae5

5 files changed

Lines changed: 51 additions & 3 deletions

File tree

src/CommonLib/Enums/LDAPProperties.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,5 +94,6 @@ public static class LDAPProperties
9494
public const string LockoutDuration = "lockoutduration";
9595
public const string LockoutThreshold = "lockoutthreshold";
9696
public const string LockOutObservationWindow = "lockoutobservationwindow";
97+
public const string GroupType = "grouptype";
9798
}
9899
}

src/CommonLib/Enums/TrustType.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22
{
33
public enum TrustType
44
{
5+
TreeRoot,
56
ParentChild,
67
CrossLink,
7-
Forest,
88
External,
9+
Forest,
10+
Kerberos,
911
Unknown
1012
}
1113
}

src/CommonLib/LdapQueries/CommonProperties.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public static class CommonProperties
6060
LDAPProperties.SupportedEncryptionTypes, LDAPProperties.DSHeuristics,
6161
LDAPProperties.MinPwdLength, LDAPProperties.PwdProperties, LDAPProperties.MinPwdAge,
6262
LDAPProperties.MaxPwdAge, LDAPProperties.PwdHistoryLength, LDAPProperties.LockoutDuration,
63-
LDAPProperties.LockoutThreshold, LDAPProperties.LockOutObservationWindow
63+
LDAPProperties.LockoutThreshold, LDAPProperties.LockOutObservationWindow, LDAPProperties.GroupType
6464
};
6565

6666
public static readonly string[] ContainerProps =

src/CommonLib/Processors/DomainTrustProcessor.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections.Generic;
22
using System.DirectoryServices.Protocols;
3+
using System.Linq;
34
using System.Security.Principal;
45
using Microsoft.Extensions.Logging;
56
using SharpHoundCommonLib.Enums;
@@ -27,6 +28,20 @@ public DomainTrustProcessor(ILdapUtils utils, ILogger log = null)
2728
public async IAsyncEnumerable<DomainTrust> EnumerateDomainTrusts(string domain)
2829
{
2930
_log.LogDebug("Running trust enumeration for {Domain}", domain);
31+
32+
// Attempt to get trust type
33+
var trustInfoList = new List<(string TargetName, System.DirectoryServices.ActiveDirectory.TrustType TrustType)>();
34+
try
35+
{
36+
_utils.GetDomain(domain, out var domainObject);
37+
trustInfoList.AddRange(from System.DirectoryServices.ActiveDirectory.TrustRelationshipInformation trust in domainObject.GetAllTrustRelationships()
38+
select (trust.TargetName, trust.TrustType));
39+
}
40+
catch
41+
{
42+
_log.LogWarning("Trust type enumeration using non-LDAP for {Domain} failed", domain);
43+
}
44+
3045
await foreach (var result in _utils.Query(new LdapQueryParameters {
3146
LDAPFilter = CommonFilters.TrustedDomains,
3247
Attributes = CommonProperties.DomainTrustProps,
@@ -90,7 +105,9 @@ public async IAsyncEnumerable<DomainTrust> EnumerateDomainTrusts(string domain)
90105
(attributes.HasFlag(TrustAttributes.WithinForest) ||
91106
attributes.HasFlag(TrustAttributes.CrossOrganizationEnableTGTDelegation));
92107

93-
trust.TrustType = TrustAttributesToType(attributes);
108+
var match = trustInfoList.FirstOrDefault(t =>
109+
t.TargetName.ToUpper().Equals(trust.TargetDomainName));
110+
trust.TrustType = !string.IsNullOrEmpty(match.TargetName) ? (TrustType) match.TrustType : TrustAttributesToType(attributes);
94111

95112
yield return trust;
96113
}

src/CommonLib/Processors/LdapPropertyProcessor.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,9 @@ public static Dictionary<string, object> ReadGroupProperties(IDirectoryObject en
179179
var props = GetCommonProps(entry);
180180
entry.TryGetLongProperty(LDAPProperties.AdminCount, out var ac);
181181
props.Add("admincount", ac != 0);
182+
entry.TryGetLongProperty(LDAPProperties.GroupType, out var groupType);
183+
props.Add("groupscope", GetGroupScope(groupType));
184+
182185
return props;
183186
}
184187

@@ -854,6 +857,31 @@ private static string ConvertPKIPeriod(byte[] bytes) {
854857
}
855858
}
856859

860+
private static string GetGroupScope(long groupType)
861+
{
862+
// Constants from ADS_GROUP_TYPE_ENUM in Active Directory
863+
const int ADS_GROUP_TYPE_GLOBAL_GROUP = 0x00000002;
864+
const int ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP = 0x00000004;
865+
const int ADS_GROUP_TYPE_UNIVERSAL_GROUP = 0x00000008;
866+
867+
if ((groupType & ADS_GROUP_TYPE_UNIVERSAL_GROUP) == ADS_GROUP_TYPE_UNIVERSAL_GROUP)
868+
{
869+
return "Universal";
870+
}
871+
else if ((groupType & ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP) == ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP)
872+
{
873+
return "DomainLocal";
874+
}
875+
else if ((groupType & ADS_GROUP_TYPE_GLOBAL_GROUP) == ADS_GROUP_TYPE_GLOBAL_GROUP)
876+
{
877+
return "Global";
878+
}
879+
else
880+
{
881+
return "Unknown";
882+
}
883+
}
884+
857885
[DllImport("Advapi32", SetLastError = false)]
858886
private static extern bool IsTextUnicode(byte[] buf, int len, ref IsTextUnicodeFlags opt);
859887

0 commit comments

Comments
 (0)