Пример #1
0
#!/usr/bin/python
# -*- coding: utf-8 -*-
'''
    python dnslookup.py www.telpin.com.ar www.lanacion.com.ar
    www.telpin.com.ar : 201.219.64.50
    www.lanacion.com.ar : 23.21.247.181
'''

from dnslookup import lookup
import sys

domain = sys.argv[1:]

for x in domain:
    dns = lookup(x)
    print "{0} : {1}".format(x, dns)
Пример #2
0
    def dns_server(self):
        # If dns override is not specified
        dns_servers = []
        if not self.args.dns:
            ns_record = lookup(self.domain, 'NS',
                               self.config['config']['dns_fallback'],
                               self.protocol, self.timeout)
            if not ns_record:
                ns_record = lookup(".".join(self.domain.split('.')[-2:]), 'NS',
                                   self.config['config']['dns_fallback'],
                                   self.protocol, self.timeout)
                # TODO very ugly way of doing it, https://publicsuffix.org/list/public_suffix_list.dat is on the to-do list
                # currently doesn't handle target domain inputs like subdomain.domain.co.uk or similar domains very well yet.
                if not ns_record:  # Exit early if ns_record is not found.
                    self.log.fatal('Unable to lookup NS server', False)
                    return False
            nameservers = [x for x in ns_record if x.rdtype == 2]
            if nameservers:
                self.log.normal('Name Servers:', True)
                # For every NS record found
                for y in nameservers[0]:
                    dns_server_name = y.target.to_text()
                    # get DNS server IP
                    try:
                        dns_servers.append([
                            lookup(dns_server_name, 'A',
                                   self.config['config']['dns_fallback'],
                                   self.protocol,
                                   self.timeout)[0].items[0].to_text(),
                            y.target.to_text()
                        ])
                    except:
                        self.log.fatal(
                            self.f4.format(dns_server_name) + '{:15}'.format(
                                'Unable to resolv DNS server - Likely due to unstable network connection'
                            ), False)
                        sys.exit()
            else:
                self.log.warn('No Name Servers found for %s' % self.domain,
                              True)
                return False
        else:
            dns_servers.append([self.args.dns, self.args.dns])
        # Zone transfer
        for dns_server in dns_servers:
            if self.zone:
                try:
                    z = dns.zone.from_xfr(
                        dns.query.xfr(dns_server[0],
                                      self.domain,
                                      timeout=10,
                                      lifetime=10))
                    self.log.good(
                        self.f4.format(dns_server[1]) +
                        '{:15}'.format(dns_server[0]) +
                        ' - Zone Transfer allowed.', True)
                    names = z.nodes.keys()
                    for n in names:
                        self.log.normal(z[n].to_text(n), True)
                except:
                    self.log.warn(
                        self.f4.format(dns_server[1]) +
                        '{:15}'.format(dns_server[0]) +
                        ' - Zone Transfer not allowed.', True)
            else:
                self.log.neutral(
                    self.f4.format(dns_server[1]) +
                    '{:15}'.format(dns_server[0]), True)

            # Testing for open TCP and UDP ports for DNS servers, and what type of records are permitted.
            # TCP - ANY
            dns_result = []
            start = time.time()
            tany = lookup(self.domain, 'ANY', dns_server[0], 'TCP',
                          self.timeout)
            end = time.time()
            if tany:
                if [
                        x for x in tany if x.rdtype == 1 or x.rdtype == 28
                        or x.rdtype == 5 or x.rdtype == 15 or x.rdtype == 16
                ]:
                    dns_result.append(
                        ['TCP', dns_server[0], 'ANY', end - start])
            # TCP - A
            start = time.time()
            ta = lookup(self.domain, 'A', dns_server[0], 'TCP', self.timeout)
            end = time.time()
            if ta:
                if [x for x in ta if x.rdtype == 1]:
                    dns_result.append(['TCP', dns_server[0], 'A', end - start])
            # UDP - ANY
            start = time.time()
            uany = lookup(self.domain, 'ANY', dns_server[0], 'UDP',
                          self.timeout)
            end = time.time()
            if uany:
                if [
                        x for x in uany if x.rdtype == 1 or x.rdtype == 28
                        or x.rdtype == 5 or x.rdtype == 15 or x.rdtype == 16
                ]:
                    dns_result.append(
                        ['UDP', dns_server[0], 'ANY', end - start])
            # UDP - A
            start = time.time()
            ua = lookup(self.domain, 'A', dns_server[0], 'UDP', self.timeout)
            end = time.time()
            if ua:
                if [x for x in ua if x.rdtype == 1]:
                    dns_result.append(['UDP', dns_server[0], 'A', end - start])

        # Figure out the best combination to use
        dns_result = sorted(dns_result, key=lambda x: (x[3], x[1], x[0], x[2]))
        a = [i for i in dns_result if i[0] == 'UDP' and i[2] == 'ANY']
        b = [i for i in dns_result if i[0] == 'TCP' and i[2] == 'ANY']
        c = [i for i in dns_result if i[0] == 'UDP' and i[2] == 'A']
        d = [i for i in dns_result if i[0] == 'TCP' and i[2] == 'A']

        if a:  # ANY + UDP
            self.dns, self.protocol, self.record, delay = a[0][1], a[0][0], a[
                0][2], a[0][3]
        elif b:  # ANY + TCP
            self.dns, self.protocol, self.record, delay = b[0][1], b[0][0], b[
                0][2], b[0][3]
        elif c:  # A + UDP
            self.dns, self.protocol, self.record, delay = c[0][1], c[0][0], c[
                0][2], c[0][3]
        elif d:  # A + TCP
            self.dns, self.protocol, self.record, delay = d[0][1], d[0][0], d[
                0][2], d[0][3]
        else:  #fallback
            self.dns, self.protocol, self.record, delay = self.config[
                'config']['dns_fallback'], self.config['config'][
                    'dns_fallback_protocol'], self.config['config'][
                        'dns_fallback_record'], 0
            self.log.warn(
                'Unable to find information about %s, falling back to DNS %s, Proto %s, Type %s '
                % (self.domain, self.dns, self.protocol, self.record), True)

        # Compensate for override
        override_dns = self.args.dns
        override_record = self.args.record
        override_protocol = self.args.protocol
        if override_record: self.record = override_record
        if override_dns: self.dns = override_dns
        if override_protocol: self.protocol = override_protocol
        self.log.neutral(
            'Using nameserver %s, query type %s over %s with RTT of %.4f seconds'
            % (self.dns, self.record, self.protocol, delay), True)
        return True
Пример #3
0
 def scan_worker(self):
     while True:
         if self.handler.SIGINT:
             return
         self.mutex.acquire()
         try:
             if self.record is 'PTR':
                 tests = ['PTR']
                 subdomain = self.sl.ptr_unscanned_ip.pop(0)
                 self.sl.ptr_scanned += 1
             else:
                 subdomain = self.sl.unscanned.pop(0)
                 if self.args.record: tests = [self.record]
                 elif self.record is 'A':
                     if subdomain == '': tests = ['A', 'TXT', 'MX']
                     else: tests = ['A']
                 else: tests = ['ANY']
         except:
             if len(self.sl.unscanned) is 0:
                 return
         finally:
             self.mutex.release()
         time.sleep(self.throttle)
         # if domain already has been scanned (remove duplicates)
         # else, add domain to "scanned" list.
         if subdomain in self.sl.scanned:
             continue
         else:
             self.sl.scanned.append(subdomain)
         for t in tests:
             if self.record is 'PTR':
                 d = subdomain
             else:
                 d = (subdomain + u'.' + self.domain).lower().lstrip('.')
             try:
                 ans = lookup(d.encode('utf-8'), t, self.dns, self.protocol,
                              self.timeout)
                 if ans:
                     wildcard = self.parse_record(ans, d)
                     if ans and not wildcard and d != self.domain and self.record is not 'PTR':
                         self.new_targets(d)
                         self.sl.found.append(d)
                 elif ans == False and self.record is not 'PTR':
                     hit = [
                         x for x in self.sl.scan_failed if x[0] == subdomain
                     ]
                     if hit:
                         z = self.sl.scan_failed.index(hit[0])
                         self.sl.scan_failed[z][1] += 1
                         if hit[0][1] > self.retry:
                             self.sl.failcounter += 1
                             if self.args.verbose:
                                 self.log.status(
                                     'Failed lookup on %s' % d + ' ' * 20,
                                     False)
                             self.log.error_queue.append(
                                 'Failed lookup on %s' % d)
                             continue
                     else:
                         self.sl.scan_failed.append([subdomain, 1])
                     self.sl.scanned.remove(subdomain)
                     self.sl.unscanned.insert(0, subdomain)
                 if ans != False and self.record is not 'PTR' and (
                     (t == 'ANY' or t == 'A') or t == self.args.record):
                     # basically don't count queries that's TXT or MX if querying a server doesn't respond to ANY
                     self.sl.n_scanned += 1
                     self.sl.n_unscanned -= 1
             except Exception as e:
                 try:
                     self.log.fatal(('Domain Query failed on %s.' % d),
                                    False)
                 except:
                     pass
                 print(e)
Пример #4
0
    def check_wildcard(self, domain_addr):
        try:
            wildcard = ''.join(
                random.choice(string.ascii_lowercase) for _ in range(15))
            ans = lookup((wildcard + '.' + domain_addr.encode('utf-8')),
                         self.record, self.dns, self.protocol, self.timeout)
            if ans:
                wc = False
                d = domain_addr.encode('utf-8')
                for r in ans:
                    if r.rdtype == 1:  # A RECORD
                        item = []
                        for x in r.items:
                            item.append(x.to_text())
                        self.a_wildcard += item
                        self.log.warn(
                            self.f1.format("Wildcard A record found for %s: " %
                                           d) + ", ".join(item), True)
                        wc = True

                    if r.rdtype == 5:  # CNAME RECORD
                        item = []
                        for x in r.items:
                            item.append(x.to_text())
                        self.cname_wildcard += item
                        self.log.warn(
                            self.f1.format(
                                "Wildcard CNAME record found for %s: " % d) +
                            ", ".join(item), True)
                        wc = True

                    if r.rdtype == 16:  # TXT RECORD
                        item = []
                        for x in r.items:
                            item.append(x.to_text())
                        self.txt_wildcard += item
                        self.log.warn(
                            self.f1.format(
                                "Wildcard TXT record found for %s: " % d) +
                            ", ".join(item), True)
                        wc = True

                    if r.rdtype == 28:  # AAAA RECORD
                        item = []
                        for x in r.items:
                            item.append(x.to_text())
                        self.aaaa_wildcard += item
                        self.log.warn(
                            self.f1.format(
                                "Wildcard AAAA record found for %s: " % d) +
                            ", ".join(item), True)
                        wc = True

                    if r.rdtype == 15:  # MX RECORD
                        item = []
                        for x in r.items:
                            item.append(x.to_text())
                        self.mx_wildcard += item
                        self.log.warn(
                            self.f1.format(
                                "Wildcard MX record found for %s: " % d) +
                            ", ".join(item), True)
                        wc = True
                    if wc == True: return True
                #if not wc:
                #    return False
        except Exception as e:
            self.log.fatal(('Wildcard check on %s.' % domain_addr), False)
            print(e)
        return False
Пример #5
0
    def dns_server(self):
        ns_record = lookup(self.domain, 'NS',
                           self.config['config']['dns_fallback'],
                           self.protocol, self.timeout)
        if not ns_record:
            ns_record = lookup(".".join(self.domain.split('.')[-2:]), 'NS',
                               self.config['config']['dns_fallback'],
                               self.protocol, self.timeout)
            # TODO very ugly way of doing it, https://publicsuffix.org/list/public_suffix_list.dat is on the to-do list
            # currently doesn't handle target domain inputs like subdomain.domain.co.uk or similar domains very well yet.
        # Grab NS record data
        # rdtype 2=NS
        nameservers = [x for x in ns_record if x.rdtype == 2]
        dns_servers = []
        self.log.normal('Name Servers:', True)
        if nameservers:
            # For every NS record found
            for y in nameservers[0]:
                dns_server_name = y.target.to_text()
                # get DNS server IP
                dns_server = lookup(dns_server_name, 'A',
                                    self.config['config']['dns_fallback'],
                                    self.protocol,
                                    self.timeout)[0].items[0].to_text()
                # Zone transfer
                if self.zone:
                    try:
                        z = dns.zone.from_xfr(
                            dns.query.xfr(dns_server,
                                          self.domain,
                                          timeout=10,
                                          lifetime=10))
                        self.log.good(
                            self.f4.format(dns_server_name) +
                            '{:15}'.format(dns_server) +
                            ' - Zone Transfer allowed.', True)
                        names = z.nodes.keys()
                        for n in names:
                            self.log.normal(z[n].to_text(n), True)
                    except:
                        self.log.warn(
                            self.f4.format(dns_server_name) +
                            '{:15}'.format(dns_server) +
                            ' - Zone Transfer not allowed.', True)
                else:
                    self.log.neutral(
                        self.f4.format(dns_server_name) +
                        '{:15}'.format(dns_server), True)
                # Testing for open TCP and UDP ports for DNS servers, and what type of records are permitted.
                # TCP
                tans = lookup(self.domain, 'ANY', dns_server, 'TCP',
                              self.timeout)
                if tans:
                    if [
                            x for x in tans
                            if x.rdtype == 1 or x.rdtype == 28 or x.rdtype == 5
                            or x.rdtype == 15 or x.rdtype == 16
                    ]:
                        dns_servers.append(['TCP', dns_server, 'ANY'])
                    else:
                        dns_servers.append(['TCP', dns_server, 'A'])
                # UDP
                uans = lookup(self.domain, 'ANY', dns_server, 'UDP',
                              self.timeout)
                if uans:
                    if [
                            x for x in uans
                            if x.rdtype == 1 or x.rdtype == 28 or x.rdtype == 5
                            or x.rdtype == 15 or x.rdtype == 16
                    ]:
                        dns_servers.append(['UDP', dns_server, 'ANY'])
                    else:
                        dns_servers.append(['UDP', dns_server, 'A'])

            # pick the best type of nameserver and record combination
            if not self.args.dns and dns_servers:
                a = [i for i in dns_servers if i[0] == 'UDP' and i[2] == 'ANY']
                b = [i for i in dns_servers if i[0] == 'TCP' and i[2] == 'ANY']
                c = [i for i in dns_servers if i[0] == 'UDP' and i[2] == 'A']
                d = [i for i in dns_servers if i[0] == 'TCP' and i[2] == 'A']
                if a:  # ANY + UDP
                    self.dns, self.protocol, self.record = a[0][1], a[0][0], a[
                        0][2]
                elif b:  # ANY + TCP
                    self.dns, self.protocol, self.record = b[0][1], b[0][0], b[
                        0][2]
                elif c:  # A + UDP
                    self.dns, self.protocol, self.record = c[0][1], c[0][0], c[
                        0][2]
                elif d:  # A + TCP
                    self.dns, self.protocol, self.record = d[0][1], d[0][0], d[
                        0][2]

        override_dns = self.args.dns
        override_record = self.args.record
        override_protocol = self.args.protocol
        if override_record: self.record = override_record
        if override_dns: self.dns = override_dns
        if override_protocol: self.protocol = override_protocol
        self.log.neutral(
            'Using nameserver %s, query type %s over %s' %
            (self.dns, self.record, self.protocol), True)
Пример #6
0
 def scan_worker(self):
     while True:
         if self.handler.SIGINT:
             return
         self.mutex.acquire()
         try:
             if self.record is 'PTR':
                 tests = ['PTR']
                 self.sl.ptr_scanned += 1
                 subdomain = self.sl.ptr_unscanned_ip.pop(0)
             else:
                 if self.args.record: tests = [self.record]
                 elif self.record is 'A': tests = ['A', 'TXT', 'MX']
                 else: tests = ['ANY']
                 self.sl.n_scanned += 1
                 self.sl.n_unscanned -= 1
                 subdomain = self.sl.unscanned.pop(0)
         except:
             if len(self.sl.unscanned) is 0:
                 return
         finally:
             self.mutex.release()
         time.sleep(self.throttle)
         # if domain already has been scanned (remove duplicates)
         # else, add domain to "scanned" list.
         if subdomain in self.sl.scanned:
             continue
         else:
             self.sl.scanned.append(subdomain)
         for t in tests:
             if self.record is 'PTR':
                 d = subdomain
             else:
                 d = (subdomain + u'.' + self.domain).lower().lstrip('.')
             try:
                 ans = lookup(d.encode('utf-8'), t, self.dns, self.protocol,
                              self.timeout)
                 if ans:
                     wildcard = self.parse_record(ans, d)
                     if ans and not wildcard and d != self.domain and self.record is not 'PTR':
                         self.new_targets(d)
                         self.sl.found.append(d)
                 elif ans == False and self.record is not 'PTR':
                     hit = [
                         x for x in self.sl.scan_failed if x[0] == subdomain
                     ]
                     if hit:
                         z = self.sl.scan_failed.index(hit[0])
                         self.sl.scan_failed[z][1] += 1
                         if hit[0][1] > self.retry:
                             continue
                     else:
                         self.sl.scan_failed.append([subdomain, 1])
                     self.sl.unscanned.insert(0, subdomain)
             except Exception as e:
                 try:
                     self.log.fatal(('Domain Query failed on %s.' % d),
                                    False)
                 except:
                     self.log.fatal(
                         ('Domain Query failed on %s. (HEX ENCODED)' %
                          d.encode('hex')), False)
                     # added to in an attempt to resolve a bug related to invalid UTF-8 characters
                 print(e)