Exemple #1
0
 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);
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        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);
        }
Exemple #5
0
        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"
                                });
                            }
                        }
                    }
                }
            }));
        }