Skip to content

Commit

Permalink
Merge branch 'v4' into kstrader/BED-5004
Browse files Browse the repository at this point in the history
  • Loading branch information
ktstrader committed Nov 19, 2024
2 parents a7d503f + 812d105 commit b99a490
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 8 deletions.
19 changes: 11 additions & 8 deletions src/CommonLib/LdapUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ public IAsyncEnumerable<LdapResult<IDirectoryObject>> PagedQuery(LdapQueryParame
return (false, null);
}

public async Task<(bool Success, string DomainName)> GetDomainNameFromSid(string sid) {
public virtual async Task<(bool Success, string DomainName)> GetDomainNameFromSid(string sid) {
string domainSid;
try {
domainSid = new SecurityIdentifier(sid).AccountDomainSid?.Value.ToUpper();
Expand Down Expand Up @@ -408,7 +408,7 @@ public IAsyncEnumerable<LdapResult<IDirectoryObject>> PagedQuery(LdapQueryParame
return (false, string.Empty);
}

public async Task<(bool Success, string DomainSid)> GetDomainSidFromDomainName(string domainName) {
public virtual async Task<(bool Success, string DomainSid)> GetDomainSidFromDomainName(string domainName) {
if (Cache.GetDomainSidMapping(domainName, out var domainSid)) return (true, domainSid);

try {
Expand Down Expand Up @@ -938,7 +938,7 @@ public async IAsyncEnumerable<OutputBase> GetWellKnownPrincipalOutput() {
OutputBase output = principal.ObjectType switch {
Label.User => new User(),
Label.Computer => new Computer(),
Label.Group => new OutputTypes.Group(),
Label.Group => new Group(),
Label.GPO => new GPO(),
Label.Domain => new OutputTypes.Domain(),
Label.OU => new OU(),
Expand All @@ -961,7 +961,7 @@ public async IAsyncEnumerable<OutputBase> GetWellKnownPrincipalOutput() {
yield return entdc;
}
}

private async IAsyncEnumerable<Group> GetEnterpriseDCGroups() {
var grouped = new ConcurrentDictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
var forestSidToName = new ConcurrentDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
Expand All @@ -972,7 +972,7 @@ await GetForest(domainName) is (true, var forestName) &&
await GetDomainSidFromDomainName(forestName) is (true, var forestDomainSid)) {
forestSidToName.TryAdd(forestDomainSid, forestName);
if (!grouped.ContainsKey(forestDomainSid)) {
grouped[forestDomainSid] = new List<string>();
grouped[forestDomainSid] = [];
}

foreach (var k in domainSid) {
Expand All @@ -982,10 +982,13 @@ await GetDomainSidFromDomainName(forestName) is (true, var forestDomainSid)) {
}

foreach (var f in grouped) {
var group = new Group { ObjectIdentifier = $"{f.Key}-S-1-5-9" };
group.Properties.Add("name", $"ENTERPRISE DOMAIN CONTROLLERS@{forestSidToName[f.Key]}".ToUpper());
if (!forestSidToName.TryGetValue(f.Key, out var forestName)) {
continue;
}
var group = new Group { ObjectIdentifier = $"{forestName}-S-1-5-9" };
group.Properties.Add("name", $"ENTERPRISE DOMAIN CONTROLLERS@{forestName}".ToUpper());
group.Properties.Add("domainsid", f.Key);
group.Properties.Add("domain", forestSidToName[f.Key]);
group.Properties.Add("domain", forestName);
group.Members = f.Value.Select(x => new TypedPrincipal(x, Label.Computer)).ToArray();
yield return group;
}
Expand Down
29 changes: 29 additions & 0 deletions test/unit/LDAPUtilsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Moq;
using SharpHoundCommonLib;
using SharpHoundCommonLib.Enums;
using SharpHoundCommonLib.OutputTypes;
using Xunit;
using Xunit.Abstractions;

Expand Down Expand Up @@ -231,5 +232,33 @@ public async Task Test_ResolveHostToSid_BlankHost() {
var (success, sid) = await utils.ResolveHostToSid(spn, "");
Assert.False(success);
}

[WindowsOnlyFact]
public async Task EnterpriseDomainControllersGroup_CorrectValues() {
var utilsMock = new Mock<LdapUtils>();

//We're going to say TESTLAB.LOCAL is forest root, and SECONDARY is a child domain underneath TESTLAB.LOCAL

utilsMock.Setup(x => x.GetDomainNameFromSid("S-1-5-21-3130019616-2776909439-2417379446"))
.ReturnsAsync((true, "TESTLAB.LOCAL"));
utilsMock.Setup(x => x.GetDomainNameFromSid("S-1-5-21-3130019616-2776909439-2417379447"))
.ReturnsAsync((true, "SECONDARY.TESTLAB.LOCAL"));

utilsMock.Setup(x => x.GetForest("TESTLAB.LOCAL")).ReturnsAsync((true, "TESTLAB.LOCAL"));
utilsMock.Setup(x => x.GetForest("SECONDARY.TESTLAB.LOCAL")).ReturnsAsync((true, "TESTLAB.LOCAL"));

utilsMock.Setup(x => x.GetDomainSidFromDomainName("TESTLAB.LOCAL")).ReturnsAsync((true, "S-1-5-21-3130019616-2776909439-2417379446"));

var utils = utilsMock.Object;
utils.AddDomainController("S-1-5-21-3130019616-2776909439-2417379446-2105");
utils.AddDomainController("S-1-5-21-3130019616-2776909439-2417379446-2106");
utils.AddDomainController("S-1-5-21-3130019616-2776909439-2417379447-2105");

var result = await utils.GetWellKnownPrincipalOutput().ToArrayAsync();
Assert.Single(result);
var entDCGroup = result[0] as Group;
Assert.Equal("TESTLAB.LOCAL-S-1-5-9", entDCGroup.ObjectIdentifier);
Assert.Equal(3, entDCGroup.Members.Length);
}
}
}

0 comments on commit b99a490

Please sign in to comment.