Skip to content

Commit

Permalink
Added Asserts to LocalGroupProcessorTest.cs and added error testing f…
Browse files Browse the repository at this point in the history
…or CertAbuseProcessorTest.cs and UserRightsAssignmentProcessorTest.cs
  • Loading branch information
ktstrader committed Dec 6, 2024
1 parent fe89a1c commit 3694f25
Show file tree
Hide file tree
Showing 5 changed files with 165 additions and 10 deletions.
29 changes: 19 additions & 10 deletions test/unit/CertAbuseProcessorTest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
using System;
using System.DirectoryServices;
using System.Threading.Tasks;
using CommonLibTest.Facades;
using Moq;
using Newtonsoft.Json;
using SharpHoundCommonLib;
using SharpHoundCommonLib.Processors;
using Xunit;
using Xunit.Abstractions;

namespace CommonLibTest {
Expand Down Expand Up @@ -77,26 +85,27 @@ public void Dispose() {
// Assert.Empty(results);
// }

// [Fact]
// public void CertAbuseProcessor_ProcessCAPermissions_NullSecurity_ReturnsNull()
// {
// var mockUtils = new Mock<MockLDAPUtils>();
// var processor = new CertAbuseProcessor(mockUtils.Object);
[Fact]
public async Task CertAbuseProcessor_ProcessCAPermissions_NullSecurity_ReturnsNull()
{
var processor = new CertAbuseProcessor(new MockLdapUtils());

// var results = processor.ProcessRegistryEnrollmentPermissions(null, null, "test");
var results = await processor.ProcessRegistryEnrollmentPermissions(null, "DUMPSTER.FIRE", null, "test");

// Assert.Empty(results);
// }
Assert.Equal("Value cannot be null. (Parameter 'machineName')", results.FailureReason);
Assert.False(results.Collected);
Assert.Empty(results.Data);
}

// [WindowsOnlyFact]
// public void CertAbuseProcessor_ProcessCAPermissions_ReturnsCorrectValues()
// {
// var mockUtils = new Mock<MockLDAPUtils>();
// var mockUtils = new Mock<MockLdapUtils>();
// var sd = new ActiveDirectorySecurityDescriptor(new ActiveDirectorySecurity());
// mockUtils.Setup(x => x.MakeSecurityDescriptor()).Returns(sd);
// var processor = new CertAbuseProcessor(mockUtils.Object);
// var bytes = Helpers.B64ToBytes(CASecurityFixture);

//
// var results = processor.ProcessCAPermissions(bytes, "TESTLAB.LOCAL", "test", false);
// _testOutputHelper.WriteLine(JsonConvert.SerializeObject(results, Formatting.Indented));
// Assert.Contains(results,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Security.Principal;
using SharpHoundRPC;
using SharpHoundRPC.Shared;
using SharpHoundRPC.Wrappers;

namespace CommonLibTest.Facades.LSAMocks.WorkstationMocks
{
[SuppressMessage("Interoperability", "CA1416:Validate platform compatibility")]
public class MockFailLSAPolicy_GetLocalDomainInformation : ILSAPolicy
{
public Result<(string Name, string Sid)> GetLocalDomainInformation()
{
return NtStatus.StatusAccessDenied;
}

public Result<IEnumerable<SecurityIdentifier>> GetPrincipalsWithPrivilege(string userRight)
{
throw new NotImplementedException();
}

public Result<IEnumerable<(SecurityIdentifier sid, string Name, SharedEnums.SidNameUse Use, string Domain)>>
GetResolvedPrincipalsWithPrivilege(string userRight)
{
return new List<(SecurityIdentifier sid, string Name, SharedEnums.SidNameUse Use, string Domain)>
{
(new SecurityIdentifier("S-1-5-32-555"), "Remote Desktop Users", SharedEnums.SidNameUse.Alias, "abc"),
(new SecurityIdentifier("S-1-5-32-544"), "Administrators", SharedEnums.SidNameUse.Alias, "abc"),
(new SecurityIdentifier($"{Consts.MockWorkstationMachineSid}-1000"), "John", SharedEnums.SidNameUse.User, "abc"),
(new SecurityIdentifier($"{Consts.MockWorkstationMachineSid}-1001"), "TestGroup", SharedEnums.SidNameUse.Alias, "abc"),
};
}

public Result<(string Name, SharedEnums.SidNameUse Use, string Domains)> LookupSid(SecurityIdentifier sid)
{
throw new NotImplementedException();
}

public Result<IEnumerable<(SecurityIdentifier Sid, string Name, SharedEnums.SidNameUse Use, string Domain)>>
LookupSids(SecurityIdentifier[] sids)
{
throw new NotImplementedException();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Security.Principal;
using SharpHoundRPC;
using SharpHoundRPC.Shared;
using SharpHoundRPC.Wrappers;

namespace CommonLibTest.Facades.LSAMocks.WorkstationMocks
{
[SuppressMessage("Interoperability", "CA1416:Validate platform compatibility")]
public class MockFailLSAPolicy_GetResolvedPrincipalsWithPrivilege : ILSAPolicy
{
public Result<(string Name, string Sid)> GetLocalDomainInformation()
{
return ("WIN10", Consts.MockWorkstationMachineSid);
}

public Result<IEnumerable<SecurityIdentifier>> GetPrincipalsWithPrivilege(string userRight)
{
throw new NotImplementedException();
}

public Result<IEnumerable<(SecurityIdentifier sid, string Name, SharedEnums.SidNameUse Use, string Domain)>>
GetResolvedPrincipalsWithPrivilege(string userRight)
{
return NtStatus.StatusAccessDenied;
}

public Result<(string Name, SharedEnums.SidNameUse Use, string Domains)> LookupSid(SecurityIdentifier sid)
{
throw new NotImplementedException();
}

public Result<IEnumerable<(SecurityIdentifier Sid, string Name, SharedEnums.SidNameUse Use, string Domain)>>
LookupSids(SecurityIdentifier[] sids)
{
throw new NotImplementedException();
}
}
}
6 changes: 6 additions & 0 deletions test/unit/LocalGroupProcessorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ public async Task LocalGroupProcessor_GetLocalGroups_GetMachineSidResultFailed()
Assert.Single(receivedStatus);
var status = receivedStatus[0];
Assert.Equal("StatusAccessDenied", status.Status);
Assert.Equal("GetMachineSid", status.Task);
}

[Fact]
Expand All @@ -229,6 +230,7 @@ public async Task LocalGroupProcessor_GetLocalGroups_GetDomainsResultFailed() {
Assert.Single(receivedStatus);
var status = receivedStatus[0];
Assert.Equal("StatusAccessDenied", status.Status);
Assert.Equal("GetDomains", status.Task);
}

[Fact]
Expand All @@ -249,6 +251,7 @@ public async Task LocalGroupProcessor_GetLocalGroups_OpenDomainResultFailed()
Assert.Single(receivedStatus);
var status = receivedStatus[0];
Assert.Equal("StatusAccessDenied", status.Status);
Assert.Equal("OpenDomain - BUILTIN", status.Task);
}

[Fact]
Expand All @@ -269,6 +272,7 @@ public async Task LocalGroupProcessor_GetLocalGroups_GetAliasesFailed()
Assert.Single(receivedStatus);
var status = receivedStatus[0];
Assert.Equal("StatusAccessDenied", status.Status);
Assert.Equal("GetAliases - BUILTIN", status.Task);
}

[Fact]
Expand All @@ -291,6 +295,7 @@ public async Task LocalGroupProcessor_GetLocalGroups_OpenAliasFailed()
Assert.Single(receivedStatus);
var status = receivedStatus[0];
Assert.Equal("StatusAccessDenied", status.Status);
Assert.Equal("OpenAlias - Administrators", status.Task);
}

[Fact]
Expand All @@ -313,6 +318,7 @@ public async Task LocalGroupProcessor_GetLocalGroups_GetMembersFailed()
Assert.Single(receivedStatus);
var status = receivedStatus[0];
Assert.Equal("StatusAccessDenied", status.Status);
Assert.Equal("GetMembersInAlias - Users", status.Task);
}

[Fact]
Expand Down
52 changes: 52 additions & 0 deletions test/unit/UserRightsAssignmentProcessorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,57 @@ public async Task UserRightsAssignmentProcessor_TestTimeout() {
var status = receivedStatus[0];
Assert.Equal("Timeout", status.Status);
}

[WindowsOnlyFact]
public async Task UserRightsAssignmentProcessor_TestGetLocalDomainInformationFail()
{
var mockProcessor = new Mock<UserRightsAssignmentProcessor>(new MockLdapUtils(), null);
var mockLSAPolicy = new MockFailLSAPolicy_GetLocalDomainInformation();
mockProcessor.Setup(x => x.OpenLSAPolicy(It.IsAny<string>())).Returns(()=> {
Task.Delay(100).Wait();
return NtStatus.StatusAccessDenied;
});
mockProcessor.Setup(x => x.OpenLSAPolicy(It.IsAny<string>())).Returns(mockLSAPolicy);
var processor = mockProcessor.Object;
var machineDomainSid = $"{Consts.MockDomainSid}-1001";
var receivedStatus = new List<CSVComputerStatus>();
processor.ComputerStatusEvent += async status => {

Check warning on line 105 in test/unit/UserRightsAssignmentProcessorTest.cs

View workflow job for this annotation

GitHub Actions / build

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
receivedStatus.Add(status);
};
var results = await processor.GetUserRightsAssignments("win10.testlab.local", machineDomainSid, "testlab.local", false)
.ToArrayAsync();

Assert.Empty(results);
Assert.Single(receivedStatus);
var status = receivedStatus[0];
Assert.Equal("StatusAccessDenied", status.Status);
Assert.Equal("LSAGetMachineSID", status.Task);
}

[WindowsOnlyFact]
public async Task UserRightsAssignmentProcessor_TestGetResolvedPrincipalsWithPrivilegeFail()
{
var mockProcessor = new Mock<UserRightsAssignmentProcessor>(new MockLdapUtils(), null);
var mockLSAPolicy = new MockFailLSAPolicy_GetResolvedPrincipalsWithPrivilege();
mockProcessor.Setup(x => x.OpenLSAPolicy(It.IsAny<string>())).Returns(mockLSAPolicy);
var processor = mockProcessor.Object;
var machineDomainSid = $"{Consts.MockDomainSid}-1001";
var receivedStatus = new List<CSVComputerStatus>();
processor.ComputerStatusEvent += async status => {

Check warning on line 127 in test/unit/UserRightsAssignmentProcessorTest.cs

View workflow job for this annotation

GitHub Actions / build

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
receivedStatus.Add(status);
};
var results = await processor.GetUserRightsAssignments("win10.testlab.local", machineDomainSid, "testlab.local", false)
.ToArrayAsync();

Assert.Single(results);

var result = results[0];
Assert.False(result.Collected);
Assert.Equal("LSAEnumerateAccountsWithUserRights returned StatusAccessDenied", result.FailureReason);
Assert.Single(receivedStatus);
var status = receivedStatus[0];
Assert.Equal("StatusAccessDenied", status.Status);
Assert.Equal("LSAEnumerateAccountsWithUserRight", status.Task);
}
}
}

0 comments on commit 3694f25

Please sign in to comment.