public bool GetMapValueUnknownType(string key, out MappedPrincipal principal) { if (_groupCache.TryGetValue(key, out string resolved)) { principal = new MappedPrincipal(resolved, "group"); return(true); } if (_userCache.TryGetValue(key, out resolved)) { principal = new MappedPrincipal(resolved, "user"); return(true); } if (_computerCache.TryGetValue(key, out resolved)) { principal = new MappedPrincipal(resolved, "computer"); return(true); } principal = null; return(false); }
public static bool GetCommon(string sid, out MappedPrincipal result) { switch (sid) { case "S-1-0": result = new MappedPrincipal("Null Authority", "USER"); break; case "S-1-0-0": result = new MappedPrincipal("Nobody", "USER"); break; case "S-1-1": result = new MappedPrincipal("World Authority", "USER"); break; case "S-1-1-0": result = new MappedPrincipal("Everyone", "GROUP"); break; case "S-1-2": result = new MappedPrincipal("Local Authority", "USER"); break; case "S-1-2-0": result = new MappedPrincipal("Local", "GROUP"); break; case "S-1-2-1": result = new MappedPrincipal("Console Logon", "GROUP"); break; case "S-1-3": result = new MappedPrincipal("Creator Authority", "USER"); break; case "S-1-3-0": result = new MappedPrincipal("Creator Owner", "USER"); break; case "S-1-3-1": result = new MappedPrincipal("Creator Group", "GROUP"); break; case "S-1-3-2": result = new MappedPrincipal("Creator Owner Server", "COMPUTER"); break; case "S-1-3-3": result = new MappedPrincipal("Creator Group Server", "COMPUTER"); break; case "S-1-3-4": result = new MappedPrincipal("Owner Rights", "GROUP"); break; case "S-1-4": result = new MappedPrincipal("Non-unique Authority", "USER"); break; case "S-1-5": result = new MappedPrincipal("NT Authority", "USER"); break; case "S-1-5-1": result = new MappedPrincipal("Dialup", "GROUP"); break; case "S-1-5-2": result = new MappedPrincipal("Network", "GROUP"); break; case "S-1-5-3": result = new MappedPrincipal("Batch", "GROUP"); break; case "S-1-5-4": result = new MappedPrincipal("Interactive", "GROUP"); break; case "S-1-5-6": result = new MappedPrincipal("Service", "GROUP"); break; case "S-1-5-7": result = new MappedPrincipal("Anonymous", "GROUP"); break; case "S-1-5-8": result = new MappedPrincipal("Proxy", "GROUP"); break; case "S-1-5-9": result = new MappedPrincipal("Enterprise Domain Controllers", "GROUP"); break; case "S-1-5-10": result = new MappedPrincipal("Principal Self", "USER"); break; case "S-1-5-11": result = new MappedPrincipal("Authenticated Users", "GROUP"); break; case "S-1-5-12": result = new MappedPrincipal("Restricted Code", "GROUP"); break; case "S-1-5-13": result = new MappedPrincipal("Terminal Server Users", "GROUP"); break; case "S-1-5-14": result = new MappedPrincipal("Remote Interactive Logon", "GROUP"); break; case "S-1-5-15": result = new MappedPrincipal("This Organization ", "GROUP"); break; case "S-1-5-17": result = new MappedPrincipal("This Organization ", "GROUP"); break; case "S-1-5-18": result = new MappedPrincipal("Local System", "USER"); break; case "S-1-5-19": result = new MappedPrincipal("NT Authority", "USER"); break; case "S-1-5-20": result = new MappedPrincipal("NT Authority", "USER"); break; case "S-1-5-80-0": result = new MappedPrincipal("All Services ", "GROUP"); break; case "S-1-5-32-544": result = new MappedPrincipal("Administrators", "GROUP"); break; case "S-1-5-32-545": result = new MappedPrincipal("Users", "GROUP"); break; case "S-1-5-32-546": result = new MappedPrincipal("Guests", "GROUP"); break; case "S-1-5-32-547": result = new MappedPrincipal("Power Users", "GROUP"); break; case "S-1-5-32-548": result = new MappedPrincipal("Account Operators", "GROUP"); break; case "S-1-5-32-549": result = new MappedPrincipal("Server Operators", "GROUP"); break; case "S-1-5-32-550": result = new MappedPrincipal("Print Operators", "GROUP"); break; case "S-1-5-32-551": result = new MappedPrincipal("Backup Operators", "GROUP"); break; case "S-1-5-32-552": result = new MappedPrincipal("Replicators", "GROUP"); break; case "S-1-5-32-554": result = new MappedPrincipal("Pre-Windows 2000 Compatible Access", "GROUP"); break; case "S-1-5-32-555": result = new MappedPrincipal("Remote Desktop Users", "GROUP"); break; case "S-1-5-32-556": result = new MappedPrincipal("Network Configuration Operators", "GROUP"); break; case "S-1-5-32-557": result = new MappedPrincipal("Incoming Forest Trust Builders", "GROUP"); break; case "S-1-5-32-558": result = new MappedPrincipal("Performance Monitor Users", "GROUP"); break; case "S-1-5-32-559": result = new MappedPrincipal("Performance Log Users", "GROUP"); break; case "S-1-5-32-560": result = new MappedPrincipal("Windows Authorization Access Group", "GROUP"); break; case "S-1-5-32-561": result = new MappedPrincipal("Terminal Server License Servers", "GROUP"); break; case "S-1-5-32-562": result = new MappedPrincipal("Distributed COM Users", "GROUP"); break; case "S-1-5-32-568": result = new MappedPrincipal("IIS_IUSRS", "GROUP"); break; case "S-1-5-32-569": result = new MappedPrincipal("Cryptographic Operators", "GROUP"); break; case "S-1-5-32-573": result = new MappedPrincipal("Event Log Readers", "GROUP"); break; case "S-1-5-32-574": result = new MappedPrincipal("Certificate Service DCOM Access", "GROUP"); break; case "S-1-5-32-575": result = new MappedPrincipal("RDS Remote Access Servers", "GROUP"); break; case "S-1-5-32-576": result = new MappedPrincipal("RDS Endpoint Servers", "GROUP"); break; case "S-1-5-32-577": result = new MappedPrincipal("RDS Management Servers", "GROUP"); break; case "S-1-5-32-578": result = new MappedPrincipal("Hyper-V Administrators", "GROUP"); break; case "S-1-5-32-579": result = new MappedPrincipal("Access Control Assistance Operators", "GROUP"); break; case "S-1-5-32-580": result = new MappedPrincipal("Access Control Assistance Operators", "GROUP"); break; default: result = null; break; } return(result != null); }
internal static ResolvedEntry ResolveAdEntry(this SearchResultEntry result) { var entry = new ResolvedEntry(); var accountName = result.GetProp("samaccountname"); var distinguishedName = result.DistinguishedName; var accountType = result.GetProp("samaccounttype"); if (distinguishedName == null) { return(null); } var domainName = Utils.ConvertDnToDomain(distinguishedName); if (MappedPrincipal.GetCommon(result.GetSid(), out var temp)) { return(new ResolvedEntry { BloodHoundDisplay = $"{temp.PrincipalName}@{domainName}".ToUpper(), ObjectType = temp.ObjectType }); } if (Groups.Contains(accountType)) { entry.BloodHoundDisplay = $"{accountName}@{domainName}".ToUpper(); entry.ObjectType = "group"; return(entry); } if (Users.Contains(accountType)) { entry.BloodHoundDisplay = $"{accountName}@{domainName}".ToUpper(); entry.ObjectType = "user"; return(entry); } if (Computers.Contains(accountType)) { var shortName = accountName?.TrimEnd('$'); var dnshostname = result.GetProp("dnshostname"); if (dnshostname == null) { bool hostFound; if (domainName.Equals(_primaryDomain, StringComparison.CurrentCultureIgnoreCase)) { hostFound = DnsManager.HostExistsDns(shortName, out dnshostname); if (!hostFound) { hostFound = DnsManager.HostExistsDns($"{shortName}.{domainName}", out dnshostname); } } else { hostFound = DnsManager.HostExistsDns($"{shortName}.{domainName}", out dnshostname); if (!hostFound) { hostFound = DnsManager.HostExistsDns(shortName, out dnshostname); } } if (!hostFound) { return(null); } } entry.BloodHoundDisplay = dnshostname; entry.ObjectType = "computer"; entry.ComputerSamAccountName = shortName; return(entry); } if (accountType == null) { var objClass = result.GetPropArray("objectClass"); if (objClass.Contains("groupPolicyContainer")) { entry.BloodHoundDisplay = $"{result.GetProp("displayname")}@{domainName}"; entry.ObjectType = "gpo"; return(entry); } if (objClass.Contains("organizationalUnit")) { entry.BloodHoundDisplay = $"{result.GetProp("name")}@{domainName}"; entry.ObjectType = "ou"; return(entry); } if (objClass.Contains("container")) { entry.BloodHoundDisplay = domainName; entry.ObjectType = "container"; return(entry); } } else { if (accountType.Equals("805306370")) { return(null); } } entry.BloodHoundDisplay = domainName; entry.ObjectType = "domain"; return(entry); }
internal static ResolvedEntry ResolveAdEntry(this SearchResultEntry result, bool bypassDns = false) { var entry = new ResolvedEntry(); var accountName = result.GetProp("samaccountname"); var distinguishedName = result.DistinguishedName; var accountType = result.GetProp("samaccounttype"); if (distinguishedName == null) { return(null); } var domainName = Utils.ConvertDnToDomain(distinguishedName); if (MappedPrincipal.GetCommon(result.GetSid(), out var temp)) { return(new ResolvedEntry { IngestCacheDisplay = $"{temp.PrincipalName}@{domainName}".ToUpper(), ObjectType = temp.ObjectType }); } if (Groups.Contains(accountType)) { entry.IngestCacheDisplay = $"{accountName}@{domainName}".ToUpper(); entry.ObjectType = "group"; return(entry); } if (Users.Contains(accountType)) { entry.IngestCacheDisplay = $"{accountName}@{domainName}".ToUpper(); entry.ObjectType = "user"; return(entry); } if (Computers.Contains(accountType)) { var shortName = accountName?.TrimEnd('$'); var dnshostname = result.GetProp("dnshostname"); if (dnshostname == null) { var domain = Utils.ConvertDnToDomain(result.DistinguishedName); dnshostname = $"{shortName}.{domain}".ToUpper(); } entry.IngestCacheDisplay = dnshostname; entry.ObjectType = "computer"; entry.ComputerSamAccountName = shortName; return(entry); } if (accountType == null) { var objClass = result.GetPropArray("objectClass"); if (objClass.Contains("groupPolicyContainer")) { entry.IngestCacheDisplay = $"{result.GetProp("displayname")}@{domainName}"; entry.ObjectType = "gpo"; return(entry); } if (objClass.Contains("organizationalUnit")) { entry.IngestCacheDisplay = $"{result.GetProp("name")}@{domainName}"; entry.ObjectType = "ou"; return(entry); } if (objClass.Contains("container")) { entry.IngestCacheDisplay = domainName; entry.ObjectType = "container"; return(entry); } } else { if (accountType.Equals("805306370")) { return(null); } } entry.IngestCacheDisplay = domainName; entry.ObjectType = "domain"; return(entry); }
Task StartConsumer(BlockingCollection <DBObject> input, BlockingCollection <ACLInfo> output, TaskFactory factory) { return(factory.StartNew(() => { foreach (DBObject obj in input.GetConsumingEnumerable()) { Interlocked.Increment(ref count); if (obj.NTSecurityDescriptor == null) { options.WriteVerbose($"DACL was null on ${obj.SAMAccountName}"); continue; } RawSecurityDescriptor desc = new RawSecurityDescriptor(obj.NTSecurityDescriptor, 0); RawAcl acls = desc.DiscretionaryAcl; //Figure out whose the owner string ownersid = desc.Owner.ToString(); if (!manager.FindBySID(ownersid, CurrentDomain, out DBObject owner)) { if (MappedPrincipal.GetCommon(ownersid, out MappedPrincipal mapped)) { owner = new DBObject { BloodHoundDisplayName = $"{mapped.SimpleName}@{CurrentDomain}", Type = "group", Domain = CurrentDomain, DistinguishedName = $"{mapped.SimpleName}@{CurrentDomain}", }; } else if (NullSIDS.TryGetValue(ownersid, out byte val)) { owner = null; continue; } else { try { DirectoryEntry entry = new DirectoryEntry($"LDAP://<SID={ownersid}>"); owner = entry.ConvertToDB(); manager.InsertRecord(owner); } catch { owner = null; NullSIDS.TryAdd(ownersid, new byte()); options.WriteVerbose($"Unable to resolve {ownersid} for object owner"); continue; } } } if (owner != null) { output.Add(new ACLInfo { ObjectName = obj.BloodHoundDisplayName, ObjectType = obj.Type, Inherited = false, RightName = "Owner", PrincipalName = owner.BloodHoundDisplayName, PrincipalType = owner.Type, AceType = "", Qualifier = "AccessAllowed" }); } foreach (QualifiedAce r in acls) { string PrincipalSID = r.SecurityIdentifier.ToString(); //Try to map our SID to the principal using a few different methods if (!manager.FindBySID(PrincipalSID, CurrentDomain, out DBObject principal)) { if (MappedPrincipal.GetCommon(PrincipalSID, out MappedPrincipal mapped)) { principal = new DBObject { BloodHoundDisplayName = $"{mapped.SimpleName}@{CurrentDomain}", Type = "group", Domain = CurrentDomain, DistinguishedName = $"{mapped.SimpleName}@{CurrentDomain}" }; } else if (NullSIDS.TryGetValue(ownersid, out byte val)) { continue; } else { try { DirectoryEntry entry = new DirectoryEntry($"LDAP://<SID={PrincipalSID}>"); principal = entry.ConvertToDB(); manager.InsertRecord(principal); } catch { NullSIDS.TryAdd(PrincipalSID, new byte()); options.WriteVerbose($"Unable to resolve {PrincipalSID} for ACL"); continue; } } } //If we're here, we have a principal. Yay! //Resolve the ActiveDirectoryRight ActiveDirectoryRights right = (ActiveDirectoryRights)Enum.ToObject(typeof(ActiveDirectoryRights), r.AccessMask); string rs = right.ToString(); string guid = r is ObjectAce ? ((ObjectAce)r).ObjectAceType.ToString() : ""; List <string> foundrights = new List <string>(); bool cont = false; //Figure out if we need more processing cont |= (rs.Contains("WriteDacl") || rs.Contains("WriteOwner")); if (rs.Contains("GenericWrite") || rs.Contains("GenericAll")) { cont |= ("00000000-0000-0000-0000-000000000000".Equals(guid) || guid.Equals("") || cont); } if (rs.Contains("ExtendedRight")) { cont |= (guid.Equals("00000000-0000-0000-0000-000000000000") || guid.Equals("") || guid.Equals("00299570-246d-11d0-a768-00aa006e0529") || cont); //DCSync cont |= (guid.Equals("1131f6aa-9c07-11d1-f79f-00c04fc2dcd2") || guid.Equals("1131f6ad-9c07-11d1-f79f-00c04fc2dcd2") || cont); } if (rs.Contains("WriteProperty")) { cont |= (guid.Equals("00000000-0000-0000-0000-000000000000") || guid.Equals("bf9679c0-0de6-11d0-a285-00aa003049e2") || guid.Equals("bf9679a8-0de6-11d0-a285-00aa003049e2") || cont); } if (!cont) { continue; } string acetype = null; MatchCollection coll = GenericRegex.Matches(rs); if (rs.Contains("ExtendedRight")) { switch (guid) { case "1131f6aa-9c07-11d1-f79f-00c04fc2dcd2": acetype = "DS-Replication-Get-Changes"; break; case "1131f6ad-9c07-11d1-f79f-00c04fc2dcd2": acetype = "DS-Replication-Get-Changes-All"; break; default: acetype = "All"; break; } } if (acetype != null && (acetype.Equals("DS-Replication-Get-Changes-All") || acetype.Equals("DS-Replication-Get-Changes"))) { if (!syncers.TryGetValue(principal.DistinguishedName, out DCSync SyncObject)) { SyncObject = new DCSync { Domain = obj.BloodHoundDisplayName, PrincipalName = principal.BloodHoundDisplayName, PrincipalType = principal.Type }; } if (acetype.Contains("-All")) { SyncObject.GetChangesAll = true; } else { SyncObject.GetChanges = true; } syncers.AddOrUpdate(principal.DistinguishedName, SyncObject, (key, oldVar) => SyncObject); //We only care about these privs if we have both, so store that stuff and continue on continue; } if (rs.Contains("GenericAll")) { output.Add(new ACLInfo { ObjectName = obj.BloodHoundDisplayName, ObjectType = obj.Type, AceType = "", Inherited = r.IsInherited, PrincipalName = principal.BloodHoundDisplayName, PrincipalType = principal.Type, Qualifier = r.AceQualifier.ToString(), RightName = "GenericAll" }); } if (rs.Contains("GenericWrite")) { output.Add(new ACLInfo { ObjectName = obj.BloodHoundDisplayName, ObjectType = obj.Type, AceType = "", Inherited = r.IsInherited, PrincipalName = principal.BloodHoundDisplayName, PrincipalType = principal.Type, Qualifier = r.AceQualifier.ToString(), RightName = "GenericWrite" }); } if (rs.Contains("WriteOwner")) { output.Add(new ACLInfo { ObjectName = obj.BloodHoundDisplayName, ObjectType = obj.Type, AceType = "", Inherited = r.IsInherited, PrincipalName = principal.BloodHoundDisplayName, PrincipalType = principal.Type, Qualifier = r.AceQualifier.ToString(), RightName = "WriteOwner" }); } if (rs.Contains("WriteDacl")) { output.Add(new ACLInfo { ObjectName = obj.BloodHoundDisplayName, ObjectType = obj.Type, AceType = "", Inherited = r.IsInherited, PrincipalName = principal.BloodHoundDisplayName, PrincipalType = principal.Type, Qualifier = r.AceQualifier.ToString(), RightName = "WriteDacl" }); } if (rs.Contains("WriteProperty")) { if (guid.Equals("bf9679c0-0de6-11d0-a285-00aa003049e2")) { output.Add(new ACLInfo { ObjectName = obj.BloodHoundDisplayName, ObjectType = obj.Type, AceType = "Member", Inherited = r.IsInherited, PrincipalName = principal.BloodHoundDisplayName, PrincipalType = principal.Type, Qualifier = r.AceQualifier.ToString(), RightName = "WriteProperty" }); } else { output.Add(new ACLInfo { ObjectName = obj.BloodHoundDisplayName, ObjectType = obj.Type, AceType = "Script-Path", Inherited = r.IsInherited, PrincipalName = principal.BloodHoundDisplayName, PrincipalType = principal.Type, Qualifier = r.AceQualifier.ToString(), RightName = "WriteProperty" }); } } if (rs.Contains("ExtendedRight")) { if (guid.Equals("00299570-246d-11d0-a768-00aa006e0529")) { output.Add(new ACLInfo { ObjectName = obj.BloodHoundDisplayName, ObjectType = obj.Type, AceType = "User-Force-Change-Password", Inherited = r.IsInherited, PrincipalName = principal.BloodHoundDisplayName, PrincipalType = principal.Type, Qualifier = r.AceQualifier.ToString(), RightName = "ExtendedRight" }); } else { output.Add(new ACLInfo { ObjectName = obj.BloodHoundDisplayName, ObjectType = obj.Type, AceType = "All", Inherited = r.IsInherited, PrincipalName = principal.BloodHoundDisplayName, PrincipalType = principal.Type, Qualifier = r.AceQualifier.ToString(), RightName = "ExtendedRight" }); } } } } })); }