예제 #1
0
        /// <summary>
        /// Search an IP address in Bing
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public bool SearchIpBingSingleIp(string ip)
        {
            if (CheckToSkip())
            {
                EnableSkip("Skip to next IP");
                return(false);
            }

            if (ip.Contains("\\") || ip.Contains("/") || !DNSUtil.IsIPv4(ip))
            {
                return(false);
            }

            var message = $"[{PanelSearchIPBing.EngineToString(searchIPEngine)}] Searching domains in IP {ip}";

            Program.LogThis(new Log(Log.ModuleType.IPBingSearch, message, Log.LogType.debug));
            Program.ChangeStatus(message);
            List <string> currentResults;

            switch (searchIPEngine)
            {
            case PanelSearchIPBing.Engine.BingWeb:
                try
                {
                    var bingSearcher = new BingWebSearcher
                    {
                        LocatedInRegion = BingWebSearcher.Region.AnyRegion,
                        SearchAll       = true,
                        WriteInLanguage = BingWebSearcher.Language.AnyLanguage
                    };

                    currentResults = new List <string>();

                    SerchLinkWebBingEvent(ip, bingSearcher, currentResults);
                    break;
                }
                catch
                {
                    break;
                }

            case PanelSearchIPBing.Engine.BingAPI:
                var bingSearcherApi = new BingAPISearcher(Program.cfgCurrent.BingApiKey);
                currentResults = new List <string>();
                SerchLinkApiBingEvent(ip, bingSearcherApi, currentResults);
                break;
            }

            return(true);
        }
예제 #2
0
        public bool IsIpInLimitRange(string ip)
        {
            var result = false;

            if (DNSUtil.IsIPv4(ip))
            {
                foreach (var limit in lstLimits)
                {
                    result = limit.IsInRangeLimit(ip);

                    if (result)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
예제 #3
0
        /// <summary>
        /// Search an IP address in Bing
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public bool SearchIpBingSingleIp(string ip)
        {
            CancelIfSkipRequested();

            if (ip.Contains("\\") || ip.Contains("/") || !DNSUtil.IsIPv4(ip))
            {
                return(false);
            }

            var message = $"[{PanelSearchIPBing.EngineToString(searchIPEngine)}] Searching domains in IP {ip}";

            Program.LogThis(new Log(Log.ModuleType.IPBingSearch, message, Log.LogType.debug));
            Program.ChangeStatus(message);
            LinkSearcher searcher = null;

            try
            {
                switch (searchIPEngine)
                {
                case PanelSearchIPBing.Engine.BingWeb:
                    searcher = new BingWebSearcher
                    {
                        LocatedInRegion = BingWebSearcher.Region.AnyRegion,
                        WriteInLanguage = BingWebSearcher.Language.AnyLanguage
                    };
                    break;

                case PanelSearchIPBing.Engine.BingAPI:
                    searcher = new BingAPISearcher(Program.cfgCurrent.BingApiKey);
                    break;
                }
                SearchIP(ip, searcher);
            }
            catch (Exception)
            {
                return(false);
            }

            return(true);
        }
예제 #4
0
 /// <summary>
 /// Devuelve el primer DNS que funcione para un dominio dado
 /// </summary>
 /// <param name="r"></param>
 /// <param name="domain"></param>
 /// <returns></returns>
 public static string GetNSServer(Resolver r, string domain)
 {
     try
     {
         Response response = r.Query(domain, QType.NS);
         if (response.RecordsNS.Length > 0)
         {
             //Se busca hasta encontrar el DNS autoritativo
             if (response.header.AA == false)
             {
                 foreach (RecordNS rNS in response.RecordsNS)
                 {
                     List <string> NSServers = GetNSServer(r, domain, rNS.NSDNAME);
                     if (NSServers.Count > 0)
                     {
                         foreach (string dns in NSServers)
                         {
                             //Se devuelve el primero de ellos
                             return(DNSUtil.RemoveLastPoint(dns));
                         }
                     }
                 }
             }
             else
             {
                 foreach (RecordNS rNS in response.RecordsNS)
                 {
                     //Si no es una respuesta autoritativa volver a preguntar
                     string dns = RemoveLastPoint(rNS.NSDNAME);
                     if (TestDNS(dns))
                     {
                         return(dns);
                     }
                 }
             }
         }
         //Hay servidores autoritativos para esta petición
         else if (response.Authorities.Count > 0)
         {
             try
             {
                 //Se devuelve el servidor DNS autoritativo
                 if (((RR)response.Authorities[0]).RECORD is RecordSOA)
                 {
                     string dns = RemoveLastPoint(((RecordSOA)((RR)response.Authorities[0]).RECORD).MNAME);
                     if (TestDNS(dns))
                     {
                         return(dns);
                     }
                 }
                 if (((RR)response.Authorities[0]).RECORD is RecordNS)
                 {
                     string dns = RemoveLastPoint(((RecordNS)((RR)response.Authorities[0]).RECORD).NSDNAME);
                     if (TestDNS(dns))
                     {
                         return(dns);
                     }
                 }
             }
             catch { }
         }
     }
     catch { }
     //Devuelve el primer DNS local que funcione...
     foreach (IPEndPoint dns in GetLocalNSServer())
     {
         if (TestDNS(dns.Address.ToString()))
         {
             return(dns.Address.ToString());
         }
     }
     //Si ninguno a funcionado devolver el primero...
     return(GetLocalNSServer()[0].Address.ToString());
 }
예제 #5
0
        /// <summary>
        /// Devuelve todos los DNS que funcionen para un determinado dominio
        /// </summary>
        /// <param name="r"></param>
        /// <param name="domain"></param>
        /// <param name="NSServer"></param>
        /// <returns></returns>
        public static List <string> GetNSServer(Resolver r, string domain, string NSServer)
        {
            List <IPEndPoint> lastNSServers = new List <IPEndPoint>(r.DnsServers);

            try
            {
                r.DnsServer = NSServer;
                Response response = r.Query(domain, QType.NS);
                if (response.RecordsNS.Length > 0)
                {
                    List <string> lst = new List <string>();
                    //No es autoritativa, volver a preguntar
                    if (!response.header.AA)
                    {
                        if (response.RecordsNS.Length > 0)
                        {
                            foreach (RecordNS rNS in response.RecordsNS)
                            {
                                if (NSServer != rNS.NSDNAME)
                                {
                                    foreach (string ns in GetNSServer(r, domain, rNS.NSDNAME))
                                    {
                                        if (!lst.Contains(ns, StringComparer.OrdinalIgnoreCase))
                                        {
                                            lst.Add(ns);
                                        }
                                    }
                                }
                                else
                                {
                                    lst.Add(NSServer);
                                }
                            }
                        }
                    }
                    else
                    {
                        foreach (RecordNS rNS in response.RecordsNS)
                        {
                            lst.Add(RemoveLastPoint(rNS.NSDNAME));
                        }
                    }
                    //Resuleve los dominios de los DNS
                    List <string> ips = new List <string>();
                    foreach (string ns in lst)
                    {
                        foreach (IPAddress ip in DNSUtil.GetHostAddresses(ns))
                        {
                            if (!ips.Contains(ip.ToString()))
                            {
                                if (TestDNS(ip.ToString()))
                                {
                                    ips.Add(ip.ToString());
                                }
                            }
                        }
                    }
                    return(ips);
                }
                //Hay servidores autoritativos para esta petición
                else if (response.Authorities.Count > 0)
                {
                    try
                    {
                        //Se devuelve el servidor DNS autoritativo
                        if (((RR)response.Authorities[0]).RECORD is RecordSOA)
                        {
                            string dns = RemoveLastPoint(((RecordSOA)((RR)response.Authorities[0]).RECORD).MNAME);
                            if (TestDNS(dns))
                            {
                                List <string> lst = new List <string>();
                                lst.Add(dns);
                                return(lst);
                            }
                        }
                        if (((RR)response.Authorities[0]).RECORD is RecordNS)
                        {
                            string dns = RemoveLastPoint(((RecordNS)((RR)response.Authorities[0]).RECORD).NSDNAME);
                            if (TestDNS(dns))
                            {
                                List <string> lst = new List <string>();
                                lst.Add(dns);
                                return(lst);
                            }
                        }
                    }
                    catch { }
                }
            }
            catch { }
            finally
            {
                r.DnsServers = lastNSServers.ToArray();
            }
            return(new List <string>());
        }
예제 #6
0
        /// <summary>
        /// Search subdomains using wordlists
        /// </summary>
        private void SearchCommonNames()
        {
            var message = $"Searching subdomains of {strDomain} using common DNS names";

            Program.LogThis(new Log(Log.ModuleType.DNSCommonNames, message, Log.LogType.debug));
            Program.ChangeStatus(message);

            var names = new List <string>();

            try
            {
                names.AddRange(File.ReadAllLines(CommonNamesFileName));
            }
            catch
            {
                Program.LogThis(new Log(Log.ModuleType.DNSCommonNames,
                                        $"Error opening file: {CommonNamesFileName}", Log.LogType.error));
                return;
            }

            List <string> nsServerList = new List <string>();

            foreach (var item in Resolve.DnsServers)
            {
                nsServerList.AddRange(DNSUtil.GetNSServer(Resolve, strDomain, item.Address.ToString()));
            }

            foreach (var nsServer in nsServerList)
            {
                if (DNSUtil.IsDNSAnyCast(Resolve, nsServer, strDomain))
                {
                    Program.LogThis(new Log(Log.ModuleType.DNSCommonNames,
                                            $"DNS server is Anycast, not used: {nsServer}", Log.LogType.debug));
                }
                else
                {
                    var op = Partitioner.Create(names);
                    var po = new ParallelOptions();
                    if (Program.cfgCurrent.ParallelDnsQueries != 0)
                    {
                        po.MaxDegreeOfParallelism = Program.cfgCurrent.ParallelDnsQueries;
                    }

                    try
                    {
                        Parallel.ForEach(op, po, delegate(string name)
                        {
                            CancelIfSkipRequested();

                            var subdomain = $"{name}.{strDomain}";
                            Program.LogThis(new Log(Log.ModuleType.DNSCommonNames,
                                                    string.Format("[{0}] Trying resolve subdomain: {1} with NameServer {0}", nsServer, subdomain),
                                                    Log.LogType.debug));

                            foreach (var ip in DNSUtil.GetHostAddresses(Resolve, subdomain, nsServer))
                            {
                                Program.LogThis(new Log(Log.ModuleType.DNSCommonNames,
                                                        $"[{nsServer}] Found subdomain {subdomain}", Log.LogType.medium));

                                CancelIfSkipRequested();
                                try
                                {
                                    Program.data.AddResolution(subdomain, ip.ToString(),
                                                               $"Common Names [{subdomain}]", MaxRecursion, Program.cfgCurrent,
                                                               true);
                                }
                                catch (Exception)
                                {
                                }
                            }
                        });
                    }
                    catch (AggregateException)
                    { }
                    catch (OperationCanceledException)
                    {
                    }

                    if (!bSearchWithAllDNS)
                    {
                        break;
                    }
                }
            }
        }
예제 #7
0
        /// <summary>
        /// Add Ip.
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="source"></param>
        /// <param name="domainSource"></param>
        public void AddIP(string ip, string source, string domainSource, int MaxRecursion, bool doptr)
        {
            ip = ip.Trim();

            if (isIPv6(ip))
            {
                ip = ParseIPV6(ip);
            }

            if (!Ips.Items.Any(I => I.Ip.ToLower() == ip.ToLower()))
            {
                if (isPublicIP(ip))
                {
                    var isInNetrange = Project.IsIpInNetrange(ip);

                    if (!isInNetrange)
                    {
                        var host = string.Empty;
                        try
                        {
                            host = Dns.GetHostEntry(ip).HostName;

                            if (Program.data.Project.LstNetRange.Count == 0)
                            {
                                if (Program.data.Project.Domain != null)
                                {
                                    if (!IsMainDomainOrAlternative(host))
                                    {
                                        if (Program.data.Project.AlternativeDomains.Select(S => host.Contains(S.ToString())).Count() == 0)
                                        {
                                            string[] arrDom = host.Split(new char[] { '.' });
                                            if (arrDom.Count() > 1)
                                            {
                                                string auxFinalDom = arrDom[arrDom.Length - 2] + "." + arrDom[arrDom.Length - 1];
                                                Program.data.Project.AlternativeDomains.Add(auxFinalDom);
                                                MessageBox.Show("IP address associated to " + Program.data.Project.Domain + " belongs to a Netrange of " + auxFinalDom + ". It is going to be added as an alternative domain.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        catch (Exception)
                        {
                        }

                        if (IsMainDomainOrAlternative(host))
                        {
                            var netrange = Project.GetNetrange(ip);

                            if (netrange != null)
                            {
                                Project.LstNetRange.Add(netrange);
#if PLUGINS
                                Thread tPluginOnNetrange = new Thread(new ParameterizedThreadStart(Program.data.plugins.OnNewNetrange));
                                tPluginOnNetrange.IsBackground = true;
                                object[] oNetRange = new object[] { new object[] { netrange.from, netrange.to } };
                                tPluginOnNetrange.Start(oNetRange);
#endif

                                if (!Program.cfgCurrent.ScanNetranges255 || Project.GetIpsOfNetrange(netrange) <= 255)
                                {
                                    List <string> lstIps = netrange.GenerateIpsOfNetrange();
                                    Program.LogThis(new Log(Log.ModuleType.IPRangeSearch, "Netrange with " + lstIps.Count.ToString() + " IPs", Log.LogType.low));
                                    Thread tAddIps = new Thread(new ParameterizedThreadStart(AddIpListAsync));
                                    tAddIps.IsBackground = true;
                                    tAddIps.Priority     = ThreadPriority.Lowest;
                                    tAddIps.Start(lstIps);
                                }
                            }
                        }
                    }
                }

                var ipItem = new IPsItem(ip, source);
                Ips.Items.Add(ipItem);

                // OnNewIP
#if PLUGINS
                Thread tPluginOnIP = new Thread(new ParameterizedThreadStart(Program.data.plugins.OnNewIP));
                tPluginOnIP.IsBackground = true;

                object[] oIP = new object[] { new object[] { ip } };
                tPluginOnIP.Start(oIP);
#endif
                if (MaxRecursion <= 0)
                {
                    OnChangeEvent(null);
                    return;
                }

                List <string> domains;
                if (doptr)
                {
                    if (domainSource != null)
                    {
                        if (Program.cfgCurrent.UseAllDns)
                        {
                            domains = new List <string>();
                            List <string> dnsServers = DNSUtil.GetNSServer(resolver, domainSource, DNSUtil.GetLocalNSServer().First().ToString());

                            foreach (string dns in dnsServers)
                            {
                                OnLog(null, new EventsThreads.ThreadStringEventArgs(string.Format("Making reverse resolution to IP: {0} Using DNS server: {1}", ip, dns)));

                                foreach (var domain in DNSUtil.GetHostNames(resolver, ip, dns).Where(domain => !domains.Contains(domain)))
                                {
                                    domains.Add(domain);
                                }
                            }
                        }
                        else
                        {
                            var dnsserver = DNSUtil.GetNSServer(resolver, domainSource);
                            OnLog(null, new EventsThreads.ThreadStringEventArgs(string.Format("Making reverse resolution to IP: {0} Using DNS server: {1}", ip, dnsserver)));
                            domains = DNSUtil.GetHostNames(resolver, ip, dnsserver);
                        }
                    }
                    else
                    {
                        domains = DNSUtil.GetHostNames(resolver, ip);
                    }
                    foreach (var domain in domains)
                    {
                        AddResolution(domain, ip, string.Format("{0} > DNS reverse resolution [{1}]", GetIpSource(ip), domain), MaxRecursion - 1, Program.cfgCurrent, true);
                    }
                }
                OnChangeEvent(null);
            }
        }
예제 #8
0
        /// <summary>
        /// Add domain if this not exist in the list.
        /// </summary>
        /// <param name="domain"></param>
        /// <param name="source"></param>
        /// <param name="maxRecursion"></param>
        /// <param name="cfgCurrent"></param>
        public void AddDomain(string domain, string source, int maxRecursion, Configuration cfgCurrent)
        {
            domain = domain.Trim();

            if (domains.Items.Any(S => S.Domain.ToLower() == domain.ToLower()))
            {
                return;
            }

            var dItem = new DomainsItem(domain, source);

            domains.Items.Add(dItem);
#if PLUGINS
            Thread tPluginOnDomain = new Thread(new ParameterizedThreadStart(Program.data.plugins.OnNewDomain));
            tPluginOnDomain.IsBackground = true;
            object[] oDomain = new object[] { new object[] { domain } };
            tPluginOnDomain.Start(oDomain);
#endif
            var domainParts   = domain.Split('.');
            var currentdomain = domainParts[domainParts.Length - 1];

            for (var i = 2; i < domainParts.Length; i++)
            {
                currentdomain = domainParts[domainParts.Length - i] + "." + currentdomain;

                AddDomain(currentdomain, string.Format("{0} > Inferred by {2} [{1}]", GetDomainSource(domain), currentdomain, domain), maxRecursion - 1, cfgCurrent);
            }

            if (maxRecursion <= 0)
            {
                OnChangeEvent(null);
                return;
            }

            //OnLog(null, new EventsThreads.ThreadStringEventArgs(string.Format("Resolving domain: {0}", domain)));

            var listIpsOfDomain = DNSUtil.GetHostAddresses(domain);

            if (listIpsOfDomain.Count == 0)
            {
                var computer = new ComputersItem();
                computer.type  = ComputersItem.Tipo.Server;
                computer.name  = domain;
                computer.NotOS = true;
                computer.os    = OperatingSystem.OS.Unknown;
                if (!computers.Items.Any(S => S.name == domain))
                {
                    computers.Items.Add(computer);
                }
            }

            foreach (var IP in listIpsOfDomain)
            {
                if (Program.data.IsMainDomainOrAlternative(domain))
                {
                    var limit = Program.data.GetLimitFromIp(IP.ToString());

                    if (limit == null)
                    {
                        Program.data.AddLimit(new Limits(IP.ToString()));
                    }
                    else
                    {
                        var lastOct = int.Parse(IP.ToString().Split(new char[] { '.' })[3]);

                        if (lastOct < limit.Lower)
                        {
                            limit.Lower = lastOct;
                        }
                        else if (lastOct > limit.Higher)
                        {
                            limit.Higher = lastOct;
                        }
                    }
                }

                AddResolution(domain, IP.ToString(), string.Format("{0} > DNS resolution [{1}]", GetDomainSource(domain), IP.ToString()), maxRecursion - 1, Program.cfgCurrent, false);
            }

            // Fingerprinting HTTP
            if (cfgCurrent.PassiveFingerPrintingHttp && cfgCurrent.FingerPrintingAllHttp)
            {
                if (NewDomainByHTTPServer != null)
                {
                    NewDomainByHTTPServer(dItem, null);
                }
            }
            else if ((cfgCurrent.PassiveFingerPrintingHttp) && (source.ToLower() == "documents search" || source.ToLower().Contains("websearch") || source.ToLower().Contains("bing ip search") || source.ToLower().Contains("technologyrecognition") || source.ToLower().Contains("fingerprinting") || source.ToLower().Contains("certificate fingerprinting")))
            {
                if (NewDomainByHTTPServer != null)
                {
                    NewDomainByHTTPServer(dItem, null);
                }
            }
            // Fingerprinting SMTP
            if (cfgCurrent.PasiveFingerPrintingSmtp && cfgCurrent.FingerPrintingAllSmtp)
            {
                if (NewDomainByMXServer != null)
                {
                    NewDomainByMXServer(dItem, null);
                }
            }

            else if ((cfgCurrent.PasiveFingerPrintingSmtp) && (source.ToLower().Contains("mx server")))
            {
                if (NewDomainByMXServer != null)
                {
                    NewDomainByMXServer(dItem, null);
                }
            }

            // Fingerprinting FTP
            if (cfgCurrent.FingerPrintingAllFtp)
            {
                if (NewDomainByFTPServer != null)
                {
                    NewDomainByFTPServer(dItem, null);
                }
            }

            OnChangeEvent(null);
        }
예제 #9
0
        /// <summary>
        /// Search subdomains using wordlists
        /// </summary>
        private void SearchCommonNames()
        {
            string initialMessage        = $"Searching subdomains of {strDomain} using common DNS names.";
            string progressMessageFormat = initialMessage + " ({0} of {1}) queries";

            Program.LogThis(new Log(Log.ModuleType.DNSCommonNames, initialMessage, Log.LogType.debug));
            Program.ChangeStatus(initialMessage);

            List <string> names = new List <string>();

            try
            {
                names.AddRange(File.ReadAllLines(CommonNamesFileName));
            }
            catch
            {
                Program.LogThis(new Log(Log.ModuleType.DNSCommonNames,
                                        $"Error opening file: {CommonNamesFileName}", Log.LogType.error));
                return;
            }
            if (names.Count > 0)
            {
                List <string> nsServerList = new List <string>();
                foreach (IPEndPoint item in Resolve.DnsServers)
                {
                    nsServerList.AddRange(DNSUtil.GetNSServer(Resolve, strDomain, item.Address.ToString()));
                }
                int totalPossibilities = nsServerList.Count * names.Count;

                int queriedCount = 0;

                foreach (string nsServer in nsServerList)
                {
                    if (DNSUtil.IsDNSAnyCast(Resolve, nsServer, strDomain))
                    {
                        Program.LogThis(new Log(Log.ModuleType.DNSCommonNames,
                                                $"DNS server is Anycast, not used: {nsServer}", Log.LogType.debug));
                    }
                    else
                    {
                        var op = Partitioner.Create(names);
                        var po = new ParallelOptions();
                        if (Program.cfgCurrent.ParallelDnsQueries != 0)
                        {
                            po.MaxDegreeOfParallelism = Program.cfgCurrent.ParallelDnsQueries;
                        }

                        try
                        {
                            Parallel.ForEach(op, po, delegate(string name)
                            {
                                CancelIfSkipRequested();

                                var subdomain = $"{name}.{strDomain}";
                                Program.LogThis(new Log(Log.ModuleType.DNSCommonNames,
                                                        string.Format("[{0}] Trying resolve subdomain: {1} with NameServer {0}", nsServer, subdomain),
                                                        Log.LogType.debug));

                                foreach (var ip in DNSUtil.GetHostAddresses(Resolve, subdomain, nsServer))
                                {
                                    Program.LogThis(new Log(Log.ModuleType.DNSCommonNames,
                                                            $"[{nsServer}] Found subdomain {subdomain}", Log.LogType.medium));

                                    CancelIfSkipRequested();
                                    try
                                    {
                                        Program.data.AddResolution(subdomain, ip.ToString(),
                                                                   $"Common Names [{subdomain}]", MaxRecursion, Program.cfgCurrent,
                                                                   true);
                                    }
                                    catch (Exception)
                                    {
                                    }
                                }
                                Interlocked.Increment(ref queriedCount);

                                Invoke(new MethodInvoker(delegate
                                {
                                    Program.FormMainInstance.toolStripProgressBarDownload.Value = queriedCount * 100 / totalPossibilities;
                                    Program.FormMainInstance.toolStripStatusLabelLeft.Text      = String.Format(progressMessageFormat, queriedCount, totalPossibilities);
                                    Program.FormMainInstance.ReportProgress(queriedCount, totalPossibilities);
                                }));
                            });
                        }
                        catch (AggregateException)
                        { }
                        catch (OperationCanceledException)
                        {
                        }

                        if (!bSearchWithAllDNS)
                        {
                            break;
                        }
                    }
                }

                Invoke(new MethodInvoker(delegate
                {
                    Program.FormMainInstance.toolStripProgressBarDownload.Value = 0;
                    Program.FormMainInstance.toolStripStatusLabelLeft.Text      = String.Empty;
                    Program.FormMainInstance.ReportProgress(0, 0);
                }));
                Program.LogThis(new Log(Log.ModuleType.DNSCommonNames, $"DNS dictionary search finished with {queriedCount} queries!", Log.LogType.medium));
            }
            else
            {
                Program.LogThis(new Log(Log.ModuleType.DNSCommonNames, "The domain names file is empty.", Log.LogType.error));
            }
        }
예제 #10
0
        /// <summary>
        /// Devuelve todos los DNS que funcionen para un determinado dominio
        /// </summary>
        /// <param name="r"></param>
        /// <param name="domain"></param>
        /// <param name="NSServer"></param>
        /// <param name="previosNSrecords"></param>
        /// <returns></returns>
        public static ICollection <string> GetNSServer(Resolver r, string domain, string NSServer, ICollection <string> previosNSrecords = null)
        {
            try
            {
                Resolver         currentResolver = r.Clone();
                HashSet <string> ips             = new HashSet <string>(StringComparer.OrdinalIgnoreCase);
                if (previosNSrecords == null)
                {
                    previosNSrecords = new HashSet <string>(StringComparer.OrdinalIgnoreCase);
                }
                previosNSrecords.Add(NSServer);

                currentResolver.DnsServer = NSServer;
                Response response = currentResolver.Query(domain, QType.NS);
                if (response.RecordsNS.Length > 0)
                {
                    HashSet <string> nameservers = new HashSet <string>();
                    //No es autoritativa, volver a preguntar
                    if (!response.header.AA)
                    {
                        nameservers.UnionWith(response.RecordsNS.Where(p => !previosNSrecords.Contains(p.NSDNAME)).Select(p => p.NSDNAME));
                        foreach (string rNS in nameservers)
                        {
                            ips.UnionWith(GetNSServer(currentResolver, domain, rNS, previosNSrecords));
                        }
                    }
                    else
                    {
                        foreach (RecordNS rNS in response.RecordsNS)
                        {
                            nameservers.Add(RemoveLastPoint(rNS.NSDNAME));
                        }
                    }

                    //Resuelve los dominios de los DNS
                    foreach (string ns in nameservers)
                    {
                        foreach (IPAddress ip in DNSUtil.GetHostAddresses(ns))
                        {
                            if (!ips.Contains(ip.ToString()))
                            {
                                if (TestDNS(ip.ToString()))
                                {
                                    ips.Add(ip.ToString());
                                }
                            }
                        }
                    }
                    return(ips);
                }
                //Hay servidores autoritativos para esta petición
                else if (response.Authorities.Count > 0)
                {
                    try
                    {
                        //Se devuelve el servidor DNS autoritativo
                        if (response.Authorities[0].RECORD is RecordSOA recordSOA)
                        {
                            string dns = RemoveLastPoint(recordSOA.MNAME);
                            if (TestDNS(dns))
                            {
                                return(new List <string>()
                                {
                                    dns
                                });
                            }
                        }
                        if (response.Authorities[0].RECORD is RecordNS recordNS)
                        {
                            string dns = RemoveLastPoint(recordNS.NSDNAME);
                            if (TestDNS(dns))
                            {
                                return(new List <string>()
                                {
                                    dns
                                });
                            }
                        }
                    }
                    catch { }
                }
            }
            catch { }
            return(new List <string>());
        }