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