示例#1
0
        /// <summary>
        /// Enumerate all the trusts for the specified domain
        /// </summary>
        /// <param name="domain">Domain to enumerate</param>
        /// <returns>A list of DomainTrust objects for the domain </returns>
        public static IEnumerable <DomainTrust> DoTrustEnumeration(string domain)
        {
            if (domain == null || domain.Trim() == "")
            {
                yield break;
            }

            Utils.Verbose($"Enumerating trusts for {domain}");

            var dc = _utils
                     .DoSearch("(userAccountControl:1.2.840.113556.1.4.803:=8192)", SearchScope.Subtree,
                               new[] { "dnshostname" }, domain).DefaultIfEmpty(null).FirstOrDefault();

            if (dc == null)
            {
                yield break;
            }


            const uint flags  = 63;
            var        ddt    = typeof(DsDomainTrusts);
            var        result = DsEnumerateDomainTrusts(dc.GetProp("dnshostname"), flags, out var ptr, out var domainCount);

            if (result != 0)
            {
                yield break;
            }

            var array = new DsDomainTrusts[domainCount];

            var iter = ptr;

            //Loop over the data and store it in an array
            for (var i = 0; i < domainCount; i++)
            {
                array[i] = (DsDomainTrusts)Marshal.PtrToStructure(iter, ddt);
                iter     = (IntPtr)(iter.ToInt64() + Marshal.SizeOf(ddt));
            }

            NetApiBufferFree(ptr);

            for (var i = 0; i < domainCount; i++)
            {
                var trust = new DomainTrust {
                    SourceDomain = domain
                };
                var data         = array[i];
                var trustType    = (TrustType)data.Flags;
                var trustAttribs = (TrustAttrib)data.TrustAttributes;

                if ((trustType & TrustType.DsDomainTreeRoot) == TrustType.DsDomainTreeRoot)
                {
                    continue;
                }

                trust.TargetDomain = data.DnsDomainName;

                var inbound  = (trustType & TrustType.DsDomainDirectInbound) == TrustType.DsDomainDirectInbound;
                var outbound = (trustType & TrustType.DsDomainDirectOutbound) == TrustType.DsDomainDirectOutbound;

                if (inbound && outbound)
                {
                    trust.TrustDirection = "Bidirectional";
                }
                else if (inbound)
                {
                    trust.TrustDirection = "Inbound";
                }
                else
                {
                    trust.TrustDirection = "Outbound";
                }

                trust.TrustType = (trustType & TrustType.DsDomainInForest) == TrustType.DsDomainInForest ? "ParentChild" : "External";

                if ((trustAttribs & TrustAttrib.NonTransitive) == TrustAttrib.NonTransitive)
                {
                    trust.IsTransitive = false;
                }

                yield return(trust);
            }
        }
示例#2
0
        /// <summary>
        ///     Processes domain trusts for a domain object
        /// </summary>
        /// <param name="domain"></param>
        /// <returns></returns>
        public IEnumerable <DomainTrust> EnumerateDomainTrusts(string domain)
        {
            var query = CommonFilters.TrustedDomains;

            foreach (var result in _utils.QueryLDAP(query, SearchScope.Subtree, CommonProperties.DomainTrustProps,
                                                    domain))
            {
                var trust          = new DomainTrust();
                var targetSidBytes = result.GetByteProperty(LDAPProperties.SecurityIdentifier);
                if (targetSidBytes == null || targetSidBytes.Length == 0)
                {
                    _log.LogTrace("Trust sid is null or empty for target: {Domain}", domain);
                    continue;
                }

                string sid;
                try
                {
                    sid = new SecurityIdentifier(targetSidBytes, 0).Value;
                }
                catch
                {
                    _log.LogTrace("Failed to convert bytes to SID for target: {Domain}", domain);
                    continue;
                }

                trust.TargetDomainSid = sid;

                if (int.TryParse(result.GetProperty(LDAPProperties.TrustDirection), out var td))
                {
                    trust.TrustDirection = (TrustDirection)td;
                }
                else
                {
                    _log.LogTrace("Failed to convert trustdirection for target: {Domain}", domain);
                    continue;
                }


                TrustAttributes attributes;

                if (int.TryParse(result.GetProperty(LDAPProperties.TrustAttributes), out var ta))
                {
                    attributes = (TrustAttributes)ta;
                }
                else
                {
                    _log.LogTrace("Failed to convert trustattributes for target: {Domain}", domain);
                    continue;
                }

                trust.IsTransitive = (attributes & TrustAttributes.NonTransitive) == 0;
                var name = result.GetProperty(LDAPProperties.CanonicalName)?.ToUpper();
                if (name != null)
                {
                    trust.TargetDomainName = name;
                }

                trust.SidFilteringEnabled = (attributes & TrustAttributes.FilterSids) != 0;
                trust.TrustType           = TrustAttributesToType(attributes);

                yield return(trust);
            }
        }
示例#3
0
        public void GetDomainsAndTrusts(string DomainName)
        {
            if (dbmanager.IsDomainCompleted(DomainName) && !options.Rebuild)
            {
                return;
            }
            Console.WriteLine($"Building Domain Trust Data for {DomainName}");
            List <string>  enumerated = new List <string>();
            Queue <string> ToEnum     = new Queue <string>();

            //Get our current domain's info
            string current = DomainName;

            ToEnum.Enqueue(current);
            //Convert the DNS name to the NetBIOS name
            IntPtr pDCI = IntPtr.Zero;
            DOMAIN_CONTROLLER_INFO info;
            int dsresult = DsGetDcName(null, current, 0, null, DSGETDCNAME_FLAGS.DS_IS_DNS_NAME | DSGETDCNAME_FLAGS.DS_RETURN_FLAT_NAME, out pDCI);

            info = (DOMAIN_CONTROLLER_INFO)Marshal.PtrToStructure(pDCI, typeof(DOMAIN_CONTROLLER_INFO));
            string netbiosname = info.DomainName;

            NetApiBufferFree(pDCI);

            options.WriteVerbose("Grabbed initial trusts");

            DomainDB temp = new DomainDB()
            {
                Completed       = false,
                DomainDNSName   = current,
                DomainShortName = netbiosname,
                DomainSid       = helpers.GetDomainSid(current),
                Trusts          = new List <DomainTrust>()
            };

            dbmanager.InsertDomain(temp);

            while (!(ToEnum.Count == 0))
            {
                string d = ToEnum.Dequeue();
                dbmanager.GetDomain(d, out temp);
                enumerated.Add(d);

                options.WriteVerbose($"Grabbing trusts for {d}");

                temp.DomainDNSName = d;

                DirectorySearcher searcher = helpers.GetDomainSearcher(d);
                if (searcher == null)
                {
                    continue;
                }
                searcher.Filter = "(userAccountControl:1.2.840.113556.1.4.803:=8192)";
                string server;
                try
                {
                    SearchResult dc = searcher.FindOne();
                    server = dc.GetProp("dnshostname");
                }
                catch
                {
                    options.WriteVerbose($"Unable to get Domain Controller for {DomainName}");
                    continue;
                }


                searcher.Dispose();

                List <DomainTrust> trusts = new List <DomainTrust>();

                IntPtr ptr    = IntPtr.Zero;
                uint   types  = 63;
                Type   DDT    = typeof(DS_DOMAIN_TRUSTS);
                uint   result = DsEnumerateDomainTrusts(server, types, out ptr, out uint domaincount);
                int    error  = Marshal.GetLastWin32Error();

                if (result == 0)
                {
                    DS_DOMAIN_TRUSTS[] array = new DS_DOMAIN_TRUSTS[domaincount];
                    IntPtr             iter  = ptr;
                    for (int i = 0; i < domaincount; i++)
                    {
                        DS_DOMAIN_TRUSTS t = (DS_DOMAIN_TRUSTS)Marshal.PtrToStructure(iter, DDT);
                        array[i] = t;
                        iter     = (IntPtr)(iter.ToInt64() + Marshal.SizeOf(DDT));
                    }
                    for (int i = 0; i < domaincount; i++)
                    {
                        DS_DOMAIN_TRUSTS t            = array[i];
                        string           dns          = t.DnsDomainName;
                        string           netbios      = t.NetbiosDomainName;
                        TRUST_TYPE       trust_type   = (TRUST_TYPE)t.Flags;
                        TRUST_ATTRIB     trust_attrib = (TRUST_ATTRIB)t.TrustAttributes;


                        if ((trust_type & TRUST_TYPE.DS_DOMAIN_TREE_ROOT) == TRUST_TYPE.DS_DOMAIN_TREE_ROOT)
                        {
                            continue;
                        }

                        DomainDB tempdomain = new DomainDB()
                        {
                            DomainDNSName   = dns,
                            DomainShortName = netbios
                        };
                        ConvertSidToStringSid(t.DomainSid, out string s);
                        tempdomain.DomainSid = s;
                        tempdomain.Completed = false;
                        tempdomain.Trusts    = new List <DomainTrust>();
                        dbmanager.InsertDomain(tempdomain);

                        DomainTrust temptrust = new DomainTrust()
                        {
                            TargetDomain = t.DnsDomainName
                        };
                        bool inbound  = false;
                        bool outbound = false;

                        inbound  = (trust_type & TRUST_TYPE.DS_DOMAIN_DIRECT_INBOUND) == TRUST_TYPE.DS_DOMAIN_DIRECT_INBOUND;
                        outbound = (trust_type & TRUST_TYPE.DS_DOMAIN_DIRECT_OUTBOUND) == TRUST_TYPE.DS_DOMAIN_DIRECT_OUTBOUND;

                        if (inbound && outbound)
                        {
                            temptrust.TrustDirection = "Bidirectional";
                        }
                        else if (inbound)
                        {
                            temptrust.TrustDirection = "Inbound";
                        }
                        else
                        {
                            temptrust.TrustDirection = "Outbound";
                        }


                        if ((trust_type & TRUST_TYPE.DS_DOMAIN_IN_FOREST) == TRUST_TYPE.DS_DOMAIN_IN_FOREST)
                        {
                            temptrust.TrustType = "ParentChild";
                        }
                        else
                        {
                            temptrust.TrustType = "External";
                        }

                        temptrust.IsTransitive = !((trust_attrib & TRUST_ATTRIB.NON_TRANSITIVE) == TRUST_ATTRIB.NON_TRANSITIVE);
                        temptrust.SourceDomain = dns;
                        trusts.Add(temptrust);
                        if (!enumerated.Contains(dns))
                        {
                            ToEnum.Enqueue(dns);
                        }
                    }

                    temp.Trusts = trusts;
                    dbmanager.InsertDomain(temp);
                    NetApiBufferFree(ptr);
                }
            }
        }
示例#4
0
        public void StartEnumeration()
        {
            Console.WriteLine("Writing Domain Trusts");
            BlockingCollection <DomainTrust> output = new BlockingCollection <DomainTrust>();
            Task writer = CreateWriter(output);

            if (options.NoDB)
            {
                Dictionary <string, DomainDB> map = new Dictionary <string, DomainDB>();
                foreach (string DomainName in helpers.GetDomainList())
                {
                    List <string>  enumerated = new List <string>();
                    Queue <string> queue      = new Queue <string>();

                    string current = DomainName;
                    queue.Enqueue(current);

                    while (queue.Count > 0)
                    {
                        current = queue.Dequeue();
                        enumerated.Add(current);

                        options.WriteVerbose($"Enumerating {current}");

                        DirectorySearcher searcher = helpers.GetDomainSearcher(current);
                        if (searcher == null)
                        {
                            continue;
                        }
                        searcher.Filter = "(userAccountControl:1.2.840.113556.1.4.803:=8192)";
                        string server;
                        try
                        {
                            SearchResult dc = searcher.FindOne();
                            server = dc.GetProp("dnshostname");
                        }
                        catch
                        {
                            options.WriteVerbose($"Unable to get Domain Controller for {DomainName}");
                            continue;
                        }
                        searcher.Dispose();

                        IntPtr ptr    = IntPtr.Zero;
                        uint   types  = 63;
                        Type   DDT    = typeof(DS_DOMAIN_TRUSTS);
                        uint   result = DsEnumerateDomainTrusts(server, types, out ptr, out uint domaincount);
                        int    error  = Marshal.GetLastWin32Error();

                        if (result == 0)
                        {
                            DS_DOMAIN_TRUSTS[] array = new DS_DOMAIN_TRUSTS[domaincount];
                            IntPtr             iter  = ptr;
                            for (int i = 0; i < domaincount; i++)
                            {
                                DS_DOMAIN_TRUSTS t = (DS_DOMAIN_TRUSTS)Marshal.PtrToStructure(iter, DDT);
                                array[i] = t;
                                iter     = (IntPtr)(iter.ToInt64() + Marshal.SizeOf(DDT));
                            }
                            for (int i = 0; i < domaincount; i++)
                            {
                                DomainTrust trust = new DomainTrust()
                                {
                                    SourceDomain = current
                                };

                                DS_DOMAIN_TRUSTS t            = array[i];
                                TRUST_TYPE       trust_type   = (TRUST_TYPE)t.Flags;
                                TRUST_ATTRIB     trust_attrib = (TRUST_ATTRIB)t.TrustAttributes;


                                if ((trust_type & TRUST_TYPE.DS_DOMAIN_TREE_ROOT) == TRUST_TYPE.DS_DOMAIN_TREE_ROOT)
                                {
                                    continue;
                                }
                                trust.TargetDomain = t.DnsDomainName;

                                bool inbound  = false;
                                bool outbound = false;

                                inbound  = (trust_type & TRUST_TYPE.DS_DOMAIN_DIRECT_INBOUND) == TRUST_TYPE.DS_DOMAIN_DIRECT_INBOUND;
                                outbound = (trust_type & TRUST_TYPE.DS_DOMAIN_DIRECT_OUTBOUND) == TRUST_TYPE.DS_DOMAIN_DIRECT_OUTBOUND;

                                if (inbound && outbound)
                                {
                                    trust.TrustDirection = "Bidirectional";
                                }
                                else if (inbound)
                                {
                                    trust.TrustDirection = "Inbound";
                                }
                                else
                                {
                                    trust.TrustDirection = "Outbound";
                                }

                                if ((trust_type & TRUST_TYPE.DS_DOMAIN_IN_FOREST) == TRUST_TYPE.DS_DOMAIN_IN_FOREST)
                                {
                                    trust.TrustType = "ParentChild";
                                }
                                else
                                {
                                    trust.TrustType = "External";
                                }

                                trust.IsTransitive = !((trust_attrib & TRUST_ATTRIB.NON_TRANSITIVE) == TRUST_ATTRIB.NON_TRANSITIVE);
                                output.Add(trust);
                                if (!enumerated.Contains(t.DnsDomainName))
                                {
                                    queue.Enqueue(t.DnsDomainName);
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                foreach (DomainDB d in db.GetDomains().FindAll())
                {
                    if (d.Trusts != null)
                    {
                        d.Trusts.ForEach(output.Add);
                    }
                }
            }

            output.CompleteAdding();
            writer.Wait();

            Console.WriteLine("Finished Domain Trusts\n");
        }