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);
                }
            }
        }
Beispiel #2
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");
        }