private GPO ProcessGPOObject(ISearchResultEntry entry, ResolvedSearchResult resolvedSearchResult) { var ret = new GPO { ObjectIdentifier = resolvedSearchResult.ObjectId }; ret.Properties.Add("domain", resolvedSearchResult.Domain); 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) { ret.Aces = _aclProcessor.ProcessACL(resolvedSearchResult, entry).ToArray(); ret.IsACLProtected = _aclProcessor.IsACLProtected(entry); } if ((_methods & ResolvedCollectionMethod.ObjectProps) != 0) { ret.Properties = ContextUtils.Merge(ret.Properties, LDAPPropertyProcessor.ReadGPOProperties(entry)); if (_context.Flags.CollectAllProperties) { ret.Properties = ContextUtils.Merge(_ldapPropertyProcessor.ParseAllProperties(entry), ret.Properties); } } return(ret); }
private Group ProcessGroupObject(ISearchResultEntry entry, ResolvedSearchResult resolvedSearchResult) { var ret = new Group { ObjectIdentifier = resolvedSearchResult.ObjectId }; ret.Properties.Add("domain", resolvedSearchResult.Domain); ret.Properties.Add("name", resolvedSearchResult.DisplayName); ret.Properties.Add("distinguishedname", entry.DistinguishedName.ToUpper()); ret.Properties.Add("domainsid", resolvedSearchResult.DomainSid); if ((_methods & ResolvedCollectionMethod.ACL) != 0) { ret.Aces = _aclProcessor.ProcessACL(resolvedSearchResult, entry).ToArray(); ret.IsACLProtected = _aclProcessor.IsACLProtected(entry); } if ((_methods & ResolvedCollectionMethod.Group) != 0) { ret.Members = _groupProcessor .ReadGroupMembers(resolvedSearchResult, entry) .ToArray(); } if ((_methods & ResolvedCollectionMethod.ObjectProps) != 0) { var groupProps = LDAPPropertyProcessor.ReadGroupProperties(entry); ret.Properties = ContextUtils.Merge(ret.Properties, groupProps); } return(ret); }
public async Task LDAPPropertyProcessor_ReadUserProperties_NullAdminCount() { var mock = new MockSearchResultEntry("CN\u003ddfm,CN\u003dUsers,DC\u003dtestlab,DC\u003dlocal", new Dictionary <string, object> { { "description", "Test" }, { "useraccountcontrol", "66048" }, { "lastlogon", "132673011142753043" }, { "lastlogontimestamp", "132670318095676525" }, { "homedirectory", @"\\win10\testdir" }, { "serviceprincipalname", new[] { "MSSQLSVC\\win10" } }, { "sidhistory", new[] { Helpers.B64ToBytes("AQUAAAAAAAUVAAAAIE+Qun9GhKV2SBaQUQQAAA==") } }, { "pwdlastset", "132131667346106691" } }, "S-1-5-21-3130019616-2776909439-2417379446-1101", Label.User); var processor = new LDAPPropertyProcessor(new MockLDAPUtils()); var test = await processor.ReadUserProperties(mock); var props = test.Props; var keys = props.Keys; Assert.Contains("admincount", keys); Assert.False((bool)props["admincount"]); }
public async Task LDAPPropertyProcessor_ReadComputerProperties_TestBadPaths() { var mock = new MockSearchResultEntry("CN\u003dWIN10,OU\u003dTestOU,DC\u003dtestlab,DC\u003dlocal", new Dictionary <string, object> { { "description", "Test" }, { "useraccountcontrol", "abc" }, { "lastlogon", "132673011142753043" }, { "lastlogontimestamp", "132670318095676525" }, { "operatingsystem", "Windows 10 Enterprise" }, { "admincount", "c" }, { "sidhistory", new[] { Array.Empty <byte>() } }, { "msds-allowedToDelegateTo", new[] { "ldap/PRIMARY.testlab.local/testlab.local", "ldap/PRIMARY.testlab.local", "ldap/PRIMARY" } }, { "pwdlastset", "132131667346106691" }, { "serviceprincipalname", new[] { "WSMAN/WIN10", "WSMAN/WIN10.testlab.local", "RestrictedKrbHost/WIN10", "HOST/WIN10", "RestrictedKrbHost/WIN10.testlab.local", "HOST/WIN10.testlab.local" } } }, "S-1-5-21-3130019616-2776909439-2417379446-1101", Label.Computer); var processor = new LDAPPropertyProcessor(new MockLDAPUtils()); var test = await processor.ReadComputerProperties(mock); var props = test.Props; var keys = props.Keys; Assert.Contains("unconstraineddelegation", keys); Assert.Contains("enabled", keys); Assert.Contains("trustedtoauth", keys); Assert.False((bool)props["unconstraineddelegation"]); Assert.True((bool)props["enabled"]); Assert.False((bool)props["trustedtoauth"]); Assert.Contains("sidhistory", keys); Assert.Empty(props["sidhistory"] as string[]); }
public void LDAPPropertyProcessor_ReadDomainProperties_TestBadFunctionalLevel() { var mock = new MockSearchResultEntry("DC\u003dtestlab,DC\u003dlocal", new Dictionary <string, object> { { "msds-behavior-version", "a" } }, "S-1-5-21-3130019616-2776909439-2417379446", Label.Domain); var test = LDAPPropertyProcessor.ReadDomainProperties(mock); Assert.Contains("functionallevel", test.Keys); Assert.Equal("Unknown", test["functionallevel"] as string); }
public void LDAPPropertyProcessor_ReadOUProperties_TestGoodData() { var mock = new MockSearchResultEntry("OU\u003dTestOU,DC\u003dtestlab,DC\u003dlocal", new Dictionary <string, object> { { "description", "Test" } }, "2A374493-816A-4193-BEFD-D2F4132C6DCA", Label.OU); var test = LDAPPropertyProcessor.ReadOUProperties(mock); Assert.Contains("description", test.Keys); Assert.Equal("Test", test["description"] as string); }
public async Task LDAPPropertyProcessor_ReadUserProperties_TestBadPaths() { var mock = new MockSearchResultEntry("CN\u003ddfm,CN\u003dUsers,DC\u003dtestlab,DC\u003dlocal", new Dictionary <string, object> { { "description", "Test" }, { "useraccountcontrol", "abc" }, { "lastlogon", "132673011142753043" }, { "lastlogontimestamp", "132670318095676525" }, { "homedirectory", @"\\win10\testdir" }, { "serviceprincipalname", new[] { "MSSQLSVC/win10" } }, { "admincount", "c" }, { "sidhistory", new[] { Array.Empty <byte>() } }, { "pwdlastset", "132131667346106691" } }, "S-1-5-21-3130019616-2776909439-2417379446-1101", Label.User); var processor = new LDAPPropertyProcessor(new MockLDAPUtils()); var test = await processor.ReadUserProperties(mock); var props = test.Props; var keys = props.Keys; Assert.Contains("sidhistory", keys); Assert.Empty(props["sidhistory"] as string[]); Assert.Contains("admincount", keys); Assert.False((bool)props["admincount"]); Assert.Contains("sensitive", keys); Assert.Contains("dontreqpreauth", keys); Assert.Contains("passwordnotreqd", keys); Assert.Contains("unconstraineddelegation", keys); Assert.Contains("pwdneverexpires", keys); Assert.Contains("enabled", keys); Assert.Contains("trustedtoauth", keys); Assert.False((bool)props["trustedtoauth"]); Assert.False((bool)props["sensitive"]); Assert.False((bool)props["dontreqpreauth"]); Assert.False((bool)props["passwordnotreqd"]); Assert.False((bool)props["unconstraineddelegation"]); Assert.False((bool)props["pwdneverexpires"]); Assert.True((bool)props["enabled"]); }
private async Task <Domain> ProcessDomainObject(ISearchResultEntry entry, ResolvedSearchResult resolvedSearchResult) { var ret = new Domain { ObjectIdentifier = resolvedSearchResult.ObjectId }; ret.Properties.Add("domain", resolvedSearchResult.Domain); 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) { ret.Aces = _aclProcessor.ProcessACL(resolvedSearchResult, entry).ToArray(); ret.IsACLProtected = _aclProcessor.IsACLProtected(entry); } if ((_methods & ResolvedCollectionMethod.Trusts) != 0) { ret.Trusts = _domainTrustProcessor.EnumerateDomainTrusts(resolvedSearchResult.Domain).ToArray(); } if ((_methods & ResolvedCollectionMethod.ObjectProps) != 0) { ret.Properties = ContextUtils.Merge(ret.Properties, LDAPPropertyProcessor.ReadDomainProperties(entry)); if (_context.Flags.CollectAllProperties) { ret.Properties = ContextUtils.Merge(_ldapPropertyProcessor.ParseAllProperties(entry), ret.Properties); } } if ((_methods & ResolvedCollectionMethod.Container) != 0) { ret.ChildObjects = _containerProcessor.GetContainerChildObjects(resolvedSearchResult, entry).ToArray(); ret.Links = _containerProcessor.ReadContainerGPLinks(resolvedSearchResult, entry).ToArray(); } if ((_methods & ResolvedCollectionMethod.GPOLocalGroup) != 0) { var gplink = entry.GetProperty(LDAPProperties.GPLink); ret.GPOChanges = await _gpoLocalGroupProcessor.ReadGPOLocalGroups(gplink, entry.DistinguishedName); } return(ret); }
public void LDAPPropertyProcessor_ReadGroupProperties_NullAdminCount() { var mock = new MockSearchResultEntry("CN\u003dDomain Admins,CN\u003dUsers,DC\u003dtestlab,DC\u003dlocal", new Dictionary <string, object> { { "description", "Test" } }, "S-1-5-21-3130019616-2776909439-2417379446-512", Label.Group); var test = LDAPPropertyProcessor.ReadGroupProperties(mock); Assert.Contains("description", test.Keys); Assert.Equal("Test", test["description"] as string); Assert.Contains("admincount", test.Keys); Assert.False((bool)test["admincount"]); }
public ObjectProcessors(IContext context, ILogger log) { _context = context; _aclProcessor = new ACLProcessor(context.LDAPUtils); _spnProcessor = new SPNProcessors(context.LDAPUtils); _ldapPropertyProcessor = new LDAPPropertyProcessor(context.LDAPUtils); _domainTrustProcessor = new DomainTrustProcessor(context.LDAPUtils); _computerAvailability = new ComputerAvailability(context.PortScanTimeout, skipPortScan: context.Flags.SkipPortScan, skipPasswordCheck: context.Flags.SkipPasswordAgeCheck); _computerSessionProcessor = new ComputerSessionProcessor(context.LDAPUtils); _groupProcessor = new GroupProcessor(context.LDAPUtils); _containerProcessor = new ContainerProcessor(context.LDAPUtils); _gpoLocalGroupProcessor = new GPOLocalGroupProcessor(context.LDAPUtils); _methods = context.ResolvedCollectionMethods; _cancellationToken = context.CancellationTokenSource.Token; _log = log; }
public void LDAPPropertyProcessor_FunctionalLevelToString_TestFunctionalLevels() { var expected = new Dictionary <int, string> { { 0, "2000 Mixed/Native" }, { 1, "2003 Interim" }, { 2, "2003" }, { 3, "2008" }, { 4, "2008 R2" }, { 5, "2012" }, { 6, "2012 R2" }, { 7, "2016" }, { -1, "Unknown" } }; foreach (var(key, value) in expected) { Assert.Equal(value, LDAPPropertyProcessor.FunctionalLevelToString(key)); } }
private async Task <OU> ProcessOUObject(ISearchResultEntry entry, ResolvedSearchResult resolvedSearchResult) { var ret = new OU { ObjectIdentifier = resolvedSearchResult.ObjectId }; ret.Properties.Add("domain", resolvedSearchResult.Domain); ret.Properties.Add("name", resolvedSearchResult.DisplayName); ret.Properties.Add("distinguishedname", entry.DistinguishedName.ToUpper()); ret.Properties.Add("domainsid", resolvedSearchResult.DomainSid); if ((_methods & ResolvedCollectionMethod.ACL) != 0) { ret.Aces = _aclProcessor.ProcessACL(resolvedSearchResult, entry).ToArray(); ret.IsACLProtected = _aclProcessor.IsACLProtected(entry); } if ((_methods & ResolvedCollectionMethod.ObjectProps) != 0) { ret.Properties = ContextUtils.Merge(ret.Properties, LDAPPropertyProcessor.ReadOUProperties(entry)); } if ((_methods & ResolvedCollectionMethod.Container) != 0) { ret.ChildObjects = _containerProcessor.GetContainerChildObjects(resolvedSearchResult, entry).ToArray(); ret.Properties.Add("blocksinheritance", ContainerProcessor.ReadBlocksInheritance(entry.GetProperty("gpoptions"))); ret.Links = _containerProcessor.ReadContainerGPLinks(resolvedSearchResult, entry).ToArray(); } if ((_methods & ResolvedCollectionMethod.GPOLocalGroup) != 0) { var gplink = entry.GetProperty(LDAPProperties.GPLink); ret.GPOChanges = await _gpoLocalGroupProcessor.ReadGPOLocalGroups(gplink, entry.DistinguishedName); } return(ret); }
public void LDAPPropertyProcessor_ReadGPOProperties_TestGoodData() { var mock = new MockSearchResultEntry( "CN\u003d{94DD0260-38B5-497E-8876-10E7A96E80D0},CN\u003dPolicies,CN\u003dSystem,DC\u003dtestlab,DC\u003dlocal", new Dictionary <string, object> { { "gpcfilesyspath", Helpers.B64ToString( "XFx0ZXN0bGFiLmxvY2FsXFN5c1ZvbFx0ZXN0bGFiLmxvY2FsXFBvbGljaWVzXHs5NEREMDI2MC0zOEI1LTQ5N0UtODg3Ni0xMEU3QTk2RTgwRDB9") }, { "description", "Test" } }, "S-1-5-21-3130019616-2776909439-2417379446", Label.GPO); var test = LDAPPropertyProcessor.ReadGPOProperties(mock); Assert.Contains("description", test.Keys); Assert.Equal("Test", test["description"] as string); Assert.Contains("gpcpath", test.Keys); Assert.Equal(@"\\TESTLAB.LOCAL\SYSVOL\TESTLAB.LOCAL\POLICIES\{94DD0260-38B5-497E-8876-10E7A96E80D0}", test["gpcpath"] as string); }
public async Task LDAPPropertyProcessor_ReadComputerProperties_HappyPath() { //TODO: Add coverage for allowedtoact var mock = new MockSearchResultEntry("CN\u003dWIN10,OU\u003dTestOU,DC\u003dtestlab,DC\u003dlocal", new Dictionary <string, object> { { "description", "Test" }, { "useraccountcontrol", 0x1001000.ToString() }, { "lastlogon", "132673011142753043" }, { "lastlogontimestamp", "132670318095676525" }, { "operatingsystem", "Windows 10 Enterprise" }, { "operatingsystemservicepack", "1607" }, { "admincount", "c" }, { "sidhistory", new[] { Helpers.B64ToBytes("AQUAAAAAAAUVAAAAIE+Qun9GhKV2SBaQUQQAAA==") } }, { "msds-allowedtodelegateto", new[] { "ldap/PRIMARY.testlab.local/testlab.local", "ldap/PRIMARY.testlab.local", "ldap/PRIMARY" } }, { "pwdlastset", "132131667346106691" }, { "serviceprincipalname", new[] { "WSMAN/WIN10", "WSMAN/WIN10.testlab.local", "RestrictedKrbHost/WIN10", "HOST/WIN10", "RestrictedKrbHost/WIN10.testlab.local", "HOST/WIN10.testlab.local" } } }, "S-1-5-21-3130019616-2776909439-2417379446-1101", Label.Computer); var processor = new LDAPPropertyProcessor(new MockLDAPUtils()); var test = await processor.ReadComputerProperties(mock); var props = test.Props; var keys = props.Keys; //UAC Assert.Contains("enabled", keys); Assert.Contains("unconstraineddelegation", keys); Assert.Contains("lastlogon", keys); Assert.Contains("lastlogontimestamp", keys); Assert.Contains("pwdlastset", keys); Assert.True((bool)props["enabled"]); Assert.False((bool)props["unconstraineddelegation"]); Assert.Contains("lastlogon", keys); Assert.Equal(1622827514, (long)props["lastlogon"]); Assert.Contains("lastlogontimestamp", keys); Assert.Equal(1622558209, (long)props["lastlogontimestamp"]); Assert.Contains("pwdlastset", keys); Assert.Equal(1568693134, (long)props["pwdlastset"]); //AllowedToDelegate Assert.Single(test.AllowedToDelegate); Assert.Contains(new TypedPrincipal { ObjectIdentifier = "S-1-5-21-3130019616-2776909439-2417379446-1001", ObjectType = Label.Computer }, test.AllowedToDelegate); //Other Stuff Assert.Contains("serviceprincipalnames", keys); Assert.Equal(6, (props["serviceprincipalnames"] as string[]).Length); Assert.Contains("operatingsystem", keys); Assert.Equal("Windows 10 Enterprise 1607", props["operatingsystem"] as string); Assert.Contains("description", keys); Assert.Equal("Test", props["description"] as string); //SidHistory Assert.Contains("sidhistory", keys); var sh = props["sidhistory"] as string[]; Assert.Single(sh); Assert.Contains("S-1-5-21-3130019616-2776909439-2417379446-1105", sh); Assert.Single(test.SidHistory); Assert.Contains(new TypedPrincipal { ObjectIdentifier = "S-1-5-21-3130019616-2776909439-2417379446-1105", ObjectType = Label.User }, test.SidHistory); }
public async Task LDAPPropertyProcessor_ReadUserProperties_HappyPath() { var mock = new MockSearchResultEntry("CN\u003ddfm,CN\u003dUsers,DC\u003dtestlab,DC\u003dlocal", new Dictionary <string, object> { { "description", "Test" }, { "useraccountcontrol", "66048" }, { "lastlogon", "132673011142753043" }, { "lastlogontimestamp", "132670318095676525" }, { "homedirectory", @"\\win10\testdir" }, { "serviceprincipalname", new[] { "MSSQLSVC/win10" } }, { "admincount", "1" }, { "sidhistory", new[] { Helpers.B64ToBytes("AQUAAAAAAAUVAAAAIE+Qun9GhKV2SBaQUQQAAA==") } }, { "pwdlastset", "132131667346106691" } }, "S-1-5-21-3130019616-2776909439-2417379446-1101", Label.User); var processor = new LDAPPropertyProcessor(new MockLDAPUtils()); var test = await processor.ReadUserProperties(mock); var props = test.Props; var keys = props.Keys; //Random Stuff Assert.Contains("description", keys); Assert.Equal("Test", props["description"] as string); Assert.Contains("admincount", keys); Assert.True((bool)props["admincount"]); Assert.Contains("lastlogon", keys); Assert.Equal(1622827514, (long)props["lastlogon"]); Assert.Contains("lastlogontimestamp", keys); Assert.Equal(1622558209, (long)props["lastlogontimestamp"]); Assert.Contains("pwdlastset", keys); Assert.Equal(1568693134, (long)props["pwdlastset"]); Assert.Contains("homedirectory", keys); Assert.Equal(@"\\win10\testdir", props["homedirectory"] as string); //UAC stuff Assert.Contains("sensitive", keys); Assert.False((bool)props["sensitive"]); Assert.Contains("dontreqpreauth", keys); Assert.False((bool)props["dontreqpreauth"]); Assert.Contains("passwordnotreqd", keys); Assert.False((bool)props["passwordnotreqd"]); Assert.Contains("unconstraineddelegation", keys); Assert.False((bool)props["unconstraineddelegation"]); Assert.Contains("enabled", keys); Assert.True((bool)props["enabled"]); Assert.Contains("trustedtoauth", keys); Assert.False((bool)props["trustedtoauth"]); //SPN Assert.Contains("hasspn", keys); Assert.True((bool)props["hasspn"]); Assert.Contains("serviceprincipalnames", keys); Assert.Contains("MSSQLSVC/win10", props["serviceprincipalnames"] as string[]); //SidHistory Assert.Contains("sidhistory", keys); var sh = props["sidhistory"] as string[]; Assert.Single(sh); Assert.Contains("S-1-5-21-3130019616-2776909439-2417379446-1105", sh); Assert.Single(test.SidHistory); Assert.Contains(new TypedPrincipal { ObjectIdentifier = "S-1-5-21-3130019616-2776909439-2417379446-1105", ObjectType = Label.User }, test.SidHistory); }
public async Task LDAPPropertyProcessor_ReadUserProperties_TestTrustedToAuth() { var mock = new MockSearchResultEntry("CN\u003ddfm,CN\u003dUsers,DC\u003dtestlab,DC\u003dlocal", new Dictionary <string, object> { { "description", "Test" }, { "useraccountcontrol", 0x1000000.ToString() }, { "lastlogon", "132673011142753043" }, { "lastlogontimestamp", "132670318095676525" }, { "homedirectory", @"\\win10\testdir" }, { "serviceprincipalname", new[] { "MSSQLSVC\\win10" } }, { "admincount", "1" }, { "sidhistory", new[] { Helpers.B64ToBytes("AQUAAAAAAAUVAAAAIE+Qun9GhKV2SBaQUQQAAA==") } }, { "pwdlastset", "132131667346106691" }, { "msds-allowedtodelegateto", new[] { "host/primary", "rdpman/win10" } } }, "S-1-5-21-3130019616-2776909439-2417379446-1101", Label.User); var processor = new LDAPPropertyProcessor(new MockLDAPUtils()); var test = await processor.ReadUserProperties(mock); var props = test.Props; var keys = props.Keys; Assert.Contains("allowedtodelegate", keys); var atd = props["allowedtodelegate"] as string[]; Assert.Equal(2, atd.Length); Assert.Contains("host/primary", atd); Assert.Contains("rdpman/win10", atd); var atdr = test.AllowedToDelegate; Assert.Equal(2, atdr.Length); var expected = new TypedPrincipal[] { new() { ObjectIdentifier = "S-1-5-21-3130019616-2776909439-2417379446-1001", ObjectType = Label.Computer }, new() { ObjectIdentifier = "S-1-5-21-3130019616-2776909439-2417379446-1104", ObjectType = Label.Computer } }; Assert.Equal(expected, atdr); }