From a7d503f74fa04270338def51c66ced5cffe8a2b8 Mon Sep 17 00:00:00 2001 From: Katie Strader Date: Tue, 19 Nov 2024 12:34:10 -0700 Subject: [PATCH] Added mocks to test error cases for LocalGroupProcessor --- test/unit/CommonLibTest.csproj | 3 - .../MockFailDomainBuiltIn_GetAliases.cs | 46 +++++ .../MockFailDomainBuiltIn_GetMembers.cs | 42 +++++ .../MockFailDomainBuiltIn_OpenAlias.cs | 45 +++++ .../MockFailSAMAliasUsers_GetMembers.cs | 16 ++ .../MockFailSAMServer_GetAliases.cs | 58 +++++++ .../MockFailSAMServer_GetDomains.cs | 60 +++++++ .../MockFailSAMServer_GetMachineSid.cs | 60 +++++++ .../MockFailSAMServer_GetMembers.cs | 58 +++++++ .../MockFailSAMServer_OpenAlias.cs | 58 +++++++ .../MockFailSAMServer_OpenDomain.cs | 58 +++++++ test/unit/LocalGroupProcessorTest.cs | 160 ++++++++++++++---- 12 files changed, 630 insertions(+), 34 deletions(-) create mode 100644 test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailDomainBuiltIn_GetAliases.cs create mode 100644 test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailDomainBuiltIn_GetMembers.cs create mode 100644 test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailDomainBuiltIn_OpenAlias.cs create mode 100644 test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMAliasUsers_GetMembers.cs create mode 100644 test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMServer_GetAliases.cs create mode 100644 test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMServer_GetDomains.cs create mode 100644 test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMServer_GetMachineSid.cs create mode 100644 test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMServer_GetMembers.cs create mode 100644 test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMServer_OpenAlias.cs create mode 100644 test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMServer_OpenDomain.cs diff --git a/test/unit/CommonLibTest.csproj b/test/unit/CommonLibTest.csproj index cd4ca2f3..6620cb6e 100644 --- a/test/unit/CommonLibTest.csproj +++ b/test/unit/CommonLibTest.csproj @@ -42,9 +42,6 @@ - - - diff --git a/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailDomainBuiltIn_GetAliases.cs b/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailDomainBuiltIn_GetAliases.cs new file mode 100644 index 00000000..bbf61b4a --- /dev/null +++ b/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailDomainBuiltIn_GetAliases.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using SharpHoundRPC; +using SharpHoundRPC.SAMRPCNative; +using SharpHoundRPC.Shared; +using SharpHoundRPC.Wrappers; + +namespace CommonLibTest.Facades +{ + public class MockFailDomainBuiltIn_GetAliases : ISAMDomain + { + public Result<(string Name, SharedEnums.SidNameUse Type)> LookupPrincipalByRid(int rid) + { + throw new System.NotImplementedException(); + } + + public Result> GetAliases() + { + // var results = new List<(string, int)> + // { + // ("Administrators", 544), + // ("Users", 545) + // }; + // return results; + return NtStatus.StatusAccessDenied; + } + + public Result OpenAlias(int rid, SAMEnums.AliasOpenFlags desiredAccess = SAMEnums.AliasOpenFlags.ListMembers) + { + switch (rid) + { + case 544: + return new MockDCAliasAdministrators(); + case 545: + return new MockDCAliasUsers(); + default: + throw new IndexOutOfRangeException(); + } + } + + public Result OpenAlias(string name) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailDomainBuiltIn_GetMembers.cs b/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailDomainBuiltIn_GetMembers.cs new file mode 100644 index 00000000..3efdfce9 --- /dev/null +++ b/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailDomainBuiltIn_GetMembers.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using SharpHoundRPC; +using SharpHoundRPC.SAMRPCNative; +using SharpHoundRPC.Shared; +using SharpHoundRPC.Wrappers; + +namespace CommonLibTest.Facades +{ + public class MockFailDomainBuiltIn_GetMembers : ISAMDomain + { + public Result<(string Name, SharedEnums.SidNameUse Type)> LookupPrincipalByRid(int rid) + { + throw new System.NotImplementedException(); + } + + public Result> GetAliases() + { + var results = new List<(string, int)> + { + ("Users", 545) + }; + return results; + } + + public Result OpenAlias(int rid, SAMEnums.AliasOpenFlags desiredAccess = SAMEnums.AliasOpenFlags.ListMembers) + { + switch (rid) + { + case 545: + return new MockFailSAMAliasUsers_GetMembers(); + default: + throw new IndexOutOfRangeException(); + } + } + + public Result OpenAlias(string name) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailDomainBuiltIn_OpenAlias.cs b/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailDomainBuiltIn_OpenAlias.cs new file mode 100644 index 00000000..f17cc861 --- /dev/null +++ b/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailDomainBuiltIn_OpenAlias.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using SharpHoundRPC; +using SharpHoundRPC.SAMRPCNative; +using SharpHoundRPC.Shared; +using SharpHoundRPC.Wrappers; + +namespace CommonLibTest.Facades +{ + public class MockFailDomainBuiltIn_OpenAlias : ISAMDomain + { + public Result<(string Name, SharedEnums.SidNameUse Type)> LookupPrincipalByRid(int rid) + { + throw new System.NotImplementedException(); + } + + public Result> GetAliases() + { + var results = new List<(string, int)> + { + ("Administrators", 544) + }; + return results; + } + + public Result OpenAlias(int rid, SAMEnums.AliasOpenFlags desiredAccess = SAMEnums.AliasOpenFlags.ListMembers) + { + // switch (rid) + // { + // case 544: + // return new MockDCAliasAdministrators(); + // case 545: + // return new MockDCAliasUsers(); + // default: + // throw new IndexOutOfRangeException(); + // } + return NtStatus.StatusAccessDenied; + } + + public Result OpenAlias(string name) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMAliasUsers_GetMembers.cs b/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMAliasUsers_GetMembers.cs new file mode 100644 index 00000000..dae83c1e --- /dev/null +++ b/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMAliasUsers_GetMembers.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using SharpHoundRPC; +using SharpHoundRPC.Wrappers; +using System.Security.Principal; + +namespace CommonLibTest.Facades +{ + public class MockFailSAMAliasUsers_GetMembers : ISAMAlias + { + public Result> GetMembers() + { + return NtStatus.StatusAccessDenied; + } + } +} + diff --git a/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMServer_GetAliases.cs b/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMServer_GetAliases.cs new file mode 100644 index 00000000..3400e9fe --- /dev/null +++ b/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMServer_GetAliases.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Security.Principal; +using SharpHoundRPC; +using SharpHoundRPC.SAMRPCNative; +using SharpHoundRPC.Shared; +using SharpHoundRPC.Wrappers; + +namespace CommonLibTest.Facades +{ + [SuppressMessage("Interoperability", "CA1416:Validate platform compatibility")] + public class MockFailSAMServer_GetAliases : ISAMServer + { + public bool IsNull { get; } + public Result> GetDomains() + { + var domains = new List<(string, int)> + { + ("BUILTIN", 1) + }; + return domains; + } + + public virtual Result LookupDomain(string name) + { + throw new System.NotImplementedException(); + } + + public Result GetMachineSid(string testName = null) + { + var securityIdentifier = new SecurityIdentifier(Consts.MockWorkstationMachineSid); + return Result.Ok(securityIdentifier); + } + + public Result<(string Name, SharedEnums.SidNameUse Type)> LookupPrincipalBySid(SecurityIdentifier securityIdentifier) + { + throw new System.NotImplementedException(); + } + + public Result OpenDomain(string domainName, + SAMEnums.DomainAccessMask requestedDomainAccess = SAMEnums.DomainAccessMask.ListAccounts | SAMEnums.DomainAccessMask.Lookup) + { + if (domainName.Equals("builtin", StringComparison.OrdinalIgnoreCase)) + { + return new MockFailDomainBuiltIn_GetAliases(); + } + + throw new NotImplementedException(); + } + + public Result OpenDomain(SecurityIdentifier securityIdentifier, + SAMEnums.DomainAccessMask requestedDomainAccess = SAMEnums.DomainAccessMask.ListAccounts | SAMEnums.DomainAccessMask.Lookup) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMServer_GetDomains.cs b/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMServer_GetDomains.cs new file mode 100644 index 00000000..96d0c51e --- /dev/null +++ b/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMServer_GetDomains.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Security.Principal; +using SharpHoundRPC; +using SharpHoundRPC.SAMRPCNative; +using SharpHoundRPC.Shared; +using SharpHoundRPC.Wrappers; + +namespace CommonLibTest.Facades +{ + [SuppressMessage("Interoperability", "CA1416:Validate platform compatibility")] + public class MockFailSAMServer_GetDomains : ISAMServer + { + public bool IsNull { get; } + public Result> GetDomains() + { + // var domains = new List<(string, int)> + // { + // ("BUILTIN", 1) + // }; + // return domains; + + return Result>.Fail(NtStatus.StatusAccessDenied); + } + + public virtual Result LookupDomain(string name) + { + throw new System.NotImplementedException(); + } + + public Result GetMachineSid(string testName = null) + { + var securityIdentifier = new SecurityIdentifier(Consts.MockWorkstationMachineSid); + return Result.Ok(securityIdentifier); + } + + public Result<(string Name, SharedEnums.SidNameUse Type)> LookupPrincipalBySid(SecurityIdentifier securityIdentifier) + { + throw new System.NotImplementedException(); + } + + public Result OpenDomain(string domainName, + SAMEnums.DomainAccessMask requestedDomainAccess = SAMEnums.DomainAccessMask.ListAccounts | SAMEnums.DomainAccessMask.Lookup) + { + if (domainName.Equals("builtin", StringComparison.OrdinalIgnoreCase)) + { + return new MockDCDomainBuiltIn(); + } + + throw new NotImplementedException(); + } + + public Result OpenDomain(SecurityIdentifier securityIdentifier, + SAMEnums.DomainAccessMask requestedDomainAccess = SAMEnums.DomainAccessMask.ListAccounts | SAMEnums.DomainAccessMask.Lookup) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMServer_GetMachineSid.cs b/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMServer_GetMachineSid.cs new file mode 100644 index 00000000..3179e1de --- /dev/null +++ b/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMServer_GetMachineSid.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Security.Principal; +using SharpHoundRPC; +using SharpHoundRPC.SAMRPCNative; +using SharpHoundRPC.Shared; +using SharpHoundRPC.Wrappers; + +namespace CommonLibTest.Facades +{ + [SuppressMessage("Interoperability", "CA1416:Validate platform compatibility")] + public class MockFailSAMServer_GetMachineSid : ISAMServer + { + public bool IsNull { get; } + public Result> GetDomains() + { + var domains = new List<(string, int)> + { + ("BUILTIN", 1) + }; + return domains; + } + + public virtual Result LookupDomain(string name) + { + throw new System.NotImplementedException(); + } + + public Result GetMachineSid(string testName = null) + { + // var securityIdentifier = new SecurityIdentifier(Consts.MockWorkstationMachineSid); + // return Result.Ok(securityIdentifier); + + return Result.Fail(NtStatus.StatusAccessDenied); + } + + public Result<(string Name, SharedEnums.SidNameUse Type)> LookupPrincipalBySid(SecurityIdentifier securityIdentifier) + { + throw new System.NotImplementedException(); + } + + public Result OpenDomain(string domainName, + SAMEnums.DomainAccessMask requestedDomainAccess = SAMEnums.DomainAccessMask.ListAccounts | SAMEnums.DomainAccessMask.Lookup) + { + if (domainName.Equals("builtin", StringComparison.OrdinalIgnoreCase)) + { + return new MockDCDomainBuiltIn(); + } + + throw new NotImplementedException(); + } + + public Result OpenDomain(SecurityIdentifier securityIdentifier, + SAMEnums.DomainAccessMask requestedDomainAccess = SAMEnums.DomainAccessMask.ListAccounts | SAMEnums.DomainAccessMask.Lookup) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMServer_GetMembers.cs b/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMServer_GetMembers.cs new file mode 100644 index 00000000..79a16931 --- /dev/null +++ b/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMServer_GetMembers.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Security.Principal; +using SharpHoundRPC; +using SharpHoundRPC.SAMRPCNative; +using SharpHoundRPC.Shared; +using SharpHoundRPC.Wrappers; + +namespace CommonLibTest.Facades +{ + [SuppressMessage("Interoperability", "CA1416:Validate platform compatibility")] + public class MockFailSAMServer_GetMembers : ISAMServer + { + public bool IsNull { get; } + public Result> GetDomains() + { + var domains = new List<(string, int)> + { + ("BUILTIN", 1) + }; + return domains; + } + + public virtual Result LookupDomain(string name) + { + throw new System.NotImplementedException(); + } + + public Result GetMachineSid(string testName = null) + { + var securityIdentifier = new SecurityIdentifier(Consts.MockWorkstationMachineSid); + return Result.Ok(securityIdentifier); + } + + public Result<(string Name, SharedEnums.SidNameUse Type)> LookupPrincipalBySid(SecurityIdentifier securityIdentifier) + { + throw new System.NotImplementedException(); + } + + public Result OpenDomain(string domainName, + SAMEnums.DomainAccessMask requestedDomainAccess = SAMEnums.DomainAccessMask.ListAccounts | SAMEnums.DomainAccessMask.Lookup) + { + if (domainName.Equals("builtin", StringComparison.OrdinalIgnoreCase)) + { + return new MockFailDomainBuiltIn_GetMembers(); + } + + throw new NotImplementedException(); + } + + public Result OpenDomain(SecurityIdentifier securityIdentifier, + SAMEnums.DomainAccessMask requestedDomainAccess = SAMEnums.DomainAccessMask.ListAccounts | SAMEnums.DomainAccessMask.Lookup) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMServer_OpenAlias.cs b/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMServer_OpenAlias.cs new file mode 100644 index 00000000..6c32e81d --- /dev/null +++ b/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMServer_OpenAlias.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Security.Principal; +using SharpHoundRPC; +using SharpHoundRPC.SAMRPCNative; +using SharpHoundRPC.Shared; +using SharpHoundRPC.Wrappers; + +namespace CommonLibTest.Facades +{ + [SuppressMessage("Interoperability", "CA1416:Validate platform compatibility")] + public class MockFailSAMServer_OpenAlias : ISAMServer + { + public bool IsNull { get; } + public Result> GetDomains() + { + var domains = new List<(string, int)> + { + ("BUILTIN", 1) + }; + return domains; + } + + public virtual Result LookupDomain(string name) + { + throw new System.NotImplementedException(); + } + + public Result GetMachineSid(string testName = null) + { + var securityIdentifier = new SecurityIdentifier(Consts.MockWorkstationMachineSid); + return Result.Ok(securityIdentifier); + } + + public Result<(string Name, SharedEnums.SidNameUse Type)> LookupPrincipalBySid(SecurityIdentifier securityIdentifier) + { + throw new System.NotImplementedException(); + } + + public Result OpenDomain(string domainName, + SAMEnums.DomainAccessMask requestedDomainAccess = SAMEnums.DomainAccessMask.ListAccounts | SAMEnums.DomainAccessMask.Lookup) + { + if (domainName.Equals("builtin", StringComparison.OrdinalIgnoreCase)) + { + return new MockFailDomainBuiltIn_OpenAlias(); + } + + throw new NotImplementedException(); + } + + public Result OpenDomain(SecurityIdentifier securityIdentifier, + SAMEnums.DomainAccessMask requestedDomainAccess = SAMEnums.DomainAccessMask.ListAccounts | SAMEnums.DomainAccessMask.Lookup) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMServer_OpenDomain.cs b/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMServer_OpenDomain.cs new file mode 100644 index 00000000..3a21f8a3 --- /dev/null +++ b/test/unit/Facades/SAMMocks/ErrorCaseMocks/LocalGroupProcessorErrorCases/MockFailSAMServer_OpenDomain.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Security.Principal; +using SharpHoundRPC; +using SharpHoundRPC.SAMRPCNative; +using SharpHoundRPC.Shared; +using SharpHoundRPC.Wrappers; + +namespace CommonLibTest.Facades +{ + [SuppressMessage("Interoperability", "CA1416:Validate platform compatibility")] + public class MockFailSAMServer_OpenDomain : ISAMServer + { + public bool IsNull { get; } + public Result> GetDomains() + { + var domains = new List<(string, int)> + { + ("BUILTIN", 1) + }; + return domains; + } + + public virtual Result LookupDomain(string name) + { + throw new System.NotImplementedException(); + } + + public Result GetMachineSid(string testName = null) + { + var securityIdentifier = new SecurityIdentifier(Consts.MockWorkstationMachineSid); + return Result.Ok(securityIdentifier); + } + + public Result<(string Name, SharedEnums.SidNameUse Type)> LookupPrincipalBySid(SecurityIdentifier securityIdentifier) + { + throw new System.NotImplementedException(); + } + + public Result OpenDomain(string domainName, + SAMEnums.DomainAccessMask requestedDomainAccess = SAMEnums.DomainAccessMask.ListAccounts | SAMEnums.DomainAccessMask.Lookup) + { + // if (domainName.Equals("builtin", StringComparison.OrdinalIgnoreCase)) + // { + // return new MockDCDomainBuiltIn(); + // } + + return NtStatus.StatusAccessDenied; + } + + public Result OpenDomain(SecurityIdentifier securityIdentifier, + SAMEnums.DomainAccessMask requestedDomainAccess = SAMEnums.DomainAccessMask.ListAccounts | SAMEnums.DomainAccessMask.Lookup) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/test/unit/LocalGroupProcessorTest.cs b/test/unit/LocalGroupProcessorTest.cs index 335dfbd9..2eac3b43 100644 --- a/test/unit/LocalGroupProcessorTest.cs +++ b/test/unit/LocalGroupProcessorTest.cs @@ -66,6 +66,7 @@ public async Task LocalGroupProcessor_TestDomainController() var mockProcessor = new Mock(new MockLdapUtils(), null); var mockSamServer = new MockDCSAMServer(); mockProcessor.Setup(x => x.OpenSamServer(It.IsAny())).Returns(mockSamServer); + var processor = mockProcessor.Object; var machineDomainSid = $"{Consts.MockWorkstationMachineSid}-1000"; var results = await processor.GetLocalGroups("primary.testlab.local", machineDomainSid, "TESTLAB.LOCAL", true) @@ -142,13 +143,32 @@ public async Task LocalGroupProcessor_ResolveGroupName_NullComputerDomainSid_Non var resultTask = TestPrivateMethod.InstanceMethod>(proc, "ResolveGroupName", new object[] { - "ADMINISTRATORS", "PRIMARY.TESTLAB.LOCAL", null, "TESTLAB.LOCAL", 544, false, true + "ADMINISTRATORS", "PRIMARY.TESTLAB.LOCAL", null, "TESTLAB.LOCAL", 544, false, false }); var result = await resultTask; Assert.Equal(null, result); } + + [Fact] + public async Task LocalGroupProcessor_ResolveGroupName_DC_NotBuiltIn() + { + var mockUtils = new Mock(); + var proc = new LocalGroupProcessor(mockUtils.Object); + + var resultTask = TestPrivateMethod.InstanceMethod>(proc, "ResolveGroupName", + new object[] + { + "ADMINISTRATORS", "PRIMARY.TESTLAB.LOCAL", "S-1-5-32-123-123-1000", "TESTLAB.LOCAL", 544, true, false + }); + + var result = await resultTask; + + Assert.Equal("IGNOREME", result.PrincipalName); + + Assert.Equal("S-1-5-32-123-123-1000-544", result.ObjectId); + } [Fact] public async Task LocalGroupProcessor_TestTimeout() { @@ -174,21 +194,56 @@ public async Task LocalGroupProcessor_TestTimeout() { } [Fact] - public async Task LocalGroupProcessor_TestStatusAccessDenied() { - var mockUtils = new Mock(); - var mockProcessor = new Mock(mockUtils.Object, null); - - mockProcessor.Setup(x => x.OpenSamServer(It.IsAny())).Returns(() => { - Task.Delay(100).Wait(); - return NtStatus.StatusAccessDenied; - }); + public async Task LocalGroupProcessor_GetLocalGroups_GetMachineSidResultFailed() { + var mockProcessor = new Mock(new MockLdapUtils(), null); + var mockSamServer = new MockFailSAMServer_GetMachineSid(); + mockProcessor.Setup(x => x.OpenSamServer(It.IsAny())).Returns(mockSamServer); var processor = mockProcessor.Object; - var machineDomainSid = $"{Consts.MockDomainSid}-1000"; + var machineDomainSid = $"{Consts.MockWorkstationMachineSid}-1000"; + var receivedStatus = new List(); + processor.ComputerStatusEvent += async status => { + receivedStatus.Add(status); + }; + var results = await processor.GetLocalGroups("primary.testlab.local", machineDomainSid, "TESTLAB.LOCAL", true) + .ToArrayAsync(); + Assert.Empty(results); + Assert.Single(receivedStatus); + var status = receivedStatus[0]; + Assert.Equal("StatusAccessDenied", status.Status); + } + + [Fact] + public async Task LocalGroupProcessor_GetLocalGroups_GetDomainsResultFailed() { + var mockProcessor = new Mock(new MockLdapUtils(), null); + var mockSamServer = new MockFailSAMServer_GetDomains(); + mockProcessor.Setup(x => x.OpenSamServer(It.IsAny())).Returns(mockSamServer); + var processor = mockProcessor.Object; + var machineDomainSid = $"{Consts.MockWorkstationMachineSid}-1000"; + var receivedStatus = new List(); + processor.ComputerStatusEvent += async status => { + receivedStatus.Add(status); + }; + var results = await processor.GetLocalGroups("primary.testlab.local", machineDomainSid, "TESTLAB.LOCAL", true) + .ToArrayAsync(); + Assert.Empty(results); + Assert.Single(receivedStatus); + var status = receivedStatus[0]; + Assert.Equal("StatusAccessDenied", status.Status); + } + + [Fact] + public async Task LocalGroupProcessor_GetLocalGroups_OpenDomainResultFailed() + { + var mockProcessor = new Mock(new MockLdapUtils(), null); + var mockSamServer = new MockFailSAMServer_OpenDomain(); + mockProcessor.Setup(x => x.OpenSamServer(It.IsAny())).Returns(mockSamServer); + var processor = mockProcessor.Object; + var machineDomainSid = $"{Consts.MockWorkstationMachineSid}-1000"; var receivedStatus = new List(); processor.ComputerStatusEvent += async status => { receivedStatus.Add(status); }; - var results = await processor.GetLocalGroups("primary.testlab.local", machineDomainSid, "testlab.local", true) + var results = await processor.GetLocalGroups("primary.testlab.local", machineDomainSid, "TESTLAB.LOCAL", true) .ToArrayAsync(); Assert.Empty(results); Assert.Single(receivedStatus); @@ -196,25 +251,68 @@ public async Task LocalGroupProcessor_TestStatusAccessDenied() { Assert.Equal("StatusAccessDenied", status.Status); } - // [Fact] - // public async Task LocalGroupProcessor_OpenSamServer() - // { - // var mockUtils = new Mock(); - // var mockProcessor = new Mock(mockUtils.Object, null); - // var mockSamServer = new MockWorkstationSAMServer(); - // var receivedStatus = new SharpHoundRPC.Result(); - // // mockProcessor.Setup(x => SAMServer.OpenServer("primary.testlab.local", mockSamServer.)).Returns(() => { - // // Task.Delay(100).Wait(); - // // return receivedStatus.Error; - // // }); - // var processor = mockProcessor.Object; - // - // - // var results = processor.OpenSamServer(It.IsAny()); - // - // Assert.True(results.IsFailed); - // - // - // } + [Fact] + public async Task LocalGroupProcessor_GetLocalGroups_GetAliasesFailed() + { + var mockProcessor = new Mock(new MockLdapUtils(), null); + var mockSamServer = new MockFailSAMServer_GetAliases(); + mockProcessor.Setup(x => x.OpenSamServer(It.IsAny())).Returns(mockSamServer); + var processor = mockProcessor.Object; + var machineDomainSid = $"{Consts.MockWorkstationMachineSid}-1000"; + var receivedStatus = new List(); + processor.ComputerStatusEvent += async status => { + receivedStatus.Add(status); + }; + var results = await processor.GetLocalGroups("primary.testlab.local", machineDomainSid, "TESTLAB.LOCAL", true) + .ToArrayAsync(); + Assert.Empty(results); + Assert.Single(receivedStatus); + var status = receivedStatus[0]; + Assert.Equal("StatusAccessDenied", status.Status); + } + + [Fact] + public async Task LocalGroupProcessor_GetLocalGroups_OpenAliasFailed() + { + var mockProcessor = new Mock(new MockLdapUtils(), null); + var mockSamServer = new MockFailSAMServer_OpenAlias(); + mockProcessor.Setup(x => x.OpenSamServer(It.IsAny())).Returns(mockSamServer); + var processor = mockProcessor.Object; + var machineDomainSid = $"{Consts.MockWorkstationMachineSid}-1000"; + var receivedStatus = new List(); + processor.ComputerStatusEvent += async status => { + receivedStatus.Add(status); + }; + var results = await processor.GetLocalGroups("primary.testlab.local", machineDomainSid, "TESTLAB.LOCAL", true) + .ToArrayAsync(); + + var failureReason = results[0]; + Assert.Contains("StatusAccessDenied", failureReason.FailureReason); + Assert.Single(receivedStatus); + var status = receivedStatus[0]; + Assert.Equal("StatusAccessDenied", status.Status); + } + + [Fact] + public async Task LocalGroupProcessor_GetLocalGroups_GetMembersFailed() + { + var mockProcessor = new Mock(new MockLdapUtils(), null); + var mockSamServer = new MockFailSAMServer_GetMembers(); + mockProcessor.Setup(x => x.OpenSamServer(It.IsAny())).Returns(mockSamServer); + var processor = mockProcessor.Object; + var machineDomainSid = $"{Consts.MockWorkstationMachineSid}-1000"; + var receivedStatus = new List(); + processor.ComputerStatusEvent += async status => { + receivedStatus.Add(status); + }; + var results = await processor.GetLocalGroups("primary.testlab.local", machineDomainSid, "TESTLAB.LOCAL", true) + .ToArrayAsync(); + + var failureReason = results[0]; + Assert.Contains("StatusAccessDenied", failureReason.FailureReason); + Assert.Single(receivedStatus); + var status = receivedStatus[0]; + Assert.Equal("StatusAccessDenied", status.Status); + } } } \ No newline at end of file