internal static void DoTrustEnumeration(ResolvedEntry resolved, ref Domain obj) { if (!Utils.IsMethodSet(ResolvedCollectionMethod.Trusts)) { return; } if (resolved == null) { return; } var trusts = new List <Trust>(); var dc = _utils.GetUsableDomainController(_utils.GetDomain(resolved.BloodHoundDisplay)); //var dc = _utils // .DoSearch("(userAccountControl:1.2.840.113556.1.4.803:=8192)", SearchScope.Subtree, // new[] { "dnshostname" }, resolved.BloodHoundDisplay).DefaultIfEmpty(null).FirstOrDefault(); if (dc == null) { return; } const uint flags = 63; var ddt = typeof(DsDomainTrusts); var result = DsEnumerateDomainTrusts(dc, flags, out var ptr, out var domainCount); if (result != 0) { return; } 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 Trust(); var data = array[i]; var trustFlags = (TrustFlags)data.Flags; var trustAttribs = (TrustAttrib)data.TrustAttributes; // the domain itself if ((trustFlags & TrustFlags.DsDomainPrimary) == TrustFlags.DsDomainPrimary) { continue; } if (data.DnsDomainName == null) { continue; } trust.TargetName = data.DnsDomainName; var inbound = (trustFlags & TrustFlags.DsDomainDirectInbound) == TrustFlags.DsDomainDirectInbound; var outbound = (trustFlags & TrustFlags.DsDomainDirectOutbound) == TrustFlags.DsDomainDirectOutbound; if (inbound && outbound) { trust.TrustDirection = (int)TrustDirection.Bidirectional; } else if (inbound) { trust.TrustDirection = (int)TrustDirection.Inbound; } else if (outbound) { trust.TrustDirection = (int)TrustDirection.Outbound; } else { // a trust with no direction is probably not enabled (According to MS documentation) // see: https://docs.microsoft.com/fr-fr/windows/desktop/api/ntsecapi/ns-ntsecapi-_trusted_domain_information_ex (TrustDirection) continue; } // parentChild occure only when one of the domain is the forest root // Check is trusted domain is the current forest root or if trusted domain's parent is current enumerated domain if (((trustFlags & TrustFlags.DsDomainTreeRoot) == TrustFlags.DsDomainTreeRoot) && ((trustFlags & TrustFlags.DsDomainInForest) == TrustFlags.DsDomainInForest) || array[data.ParentIndex].DnsDomainName?.ToUpper() == resolved.BloodHoundDisplay) { trust.TrustType = "ParentChild"; } else if ((trustFlags & TrustFlags.DsDomainInForest) == TrustFlags.DsDomainInForest) { trust.TrustType = "CrossLink"; } else if ((trustAttribs & TrustAttrib.ForestTransitive) == TrustAttrib.ForestTransitive) { trust.TrustType = "Forest"; } else { trust.TrustType = "External"; } if ((trustAttribs & TrustAttrib.NonTransitive) == TrustAttrib.NonTransitive) { trust.IsTransitive = false; } else { trust.IsTransitive = true; } trusts.Add(trust); } obj.Trusts = trusts.ToArray(); }
internal static void DoTrustEnumeration(ResolvedEntry resolved, ref Domain obj) { if (!Utils.IsMethodSet(ResolvedCollectionMethod.Trusts)) { return; } if (resolved == null) { return; } var trusts = new List <Trust>(); var dc = _utils .DoSearch("(userAccountControl:1.2.840.113556.1.4.803:=8192)", SearchScope.Subtree, new[] { "dnshostname" }, resolved.BloodHoundDisplay).DefaultIfEmpty(null).FirstOrDefault(); if (dc == null) { return; } const uint flags = 63; var ddt = typeof(DsDomainTrusts); var result = DsEnumerateDomainTrusts(dc.GetProp("dnshostname"), flags, out var ptr, out var domainCount); if (result != 0) { return; } 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 Trust(); var data = array[i]; var trustType = (TrustType)data.Flags; var trustAttribs = (TrustAttrib)data.TrustAttributes; if ((trustType & TrustType.DsDomainTreeRoot) == TrustType.DsDomainTreeRoot) { continue; } trust.TargetName = data.DnsDomainName; var inbound = (trustType & TrustType.DsDomainDirectInbound) == TrustType.DsDomainDirectInbound; var outbound = (trustType & TrustType.DsDomainDirectOutbound) == TrustType.DsDomainDirectOutbound; if (inbound && outbound) { trust.TrustDirection = (int)TrustDirection.Bidrectional; } else if (inbound) { trust.TrustDirection = (int)TrustDirection.Inbound; } else { trust.TrustDirection = (int)TrustDirection.Outbound; } trust.TrustType = (trustType & TrustType.DsDomainInForest) == TrustType.DsDomainInForest ? "ParentChild" : "External"; if ((trustAttribs & TrustAttrib.NonTransitive) == TrustAttrib.NonTransitive) { trust.IsTransitive = false; } else { trust.IsTransitive = true; } trusts.Add(trust); } obj.Trusts = trusts.ToArray(); }
/// <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); } }