Exemplo n.º 1
0
    def _query(self, server, queries=None, sleep=0.05):
        _udp = random.choice([True, False])
        _queries = list()

        if queries:
            for q in queries:
                query = dns.message.make_query(q[0], q[1], "IN")
                query.want_dnssec()
                _queries.append(query)
        else:
            for z in random.sample(list(server.zones), min(len(server.zones), 2)):
                query = dns.message.make_query(z, "SOA", "IN")
                query.want_dnssec()
                _queries.append(query)

        while self.active:
            try:
                for q in _queries:
                    if _udp:
                        dns.query.udp(q, server.addr, port=server.port,
                                      timeout=0.02)
                    else:
                        dns.query.tcp(q, server.addr, port=server.port,
                                      timeout=0.05)
            except:
                pass

            time.sleep(sleep)
Exemplo n.º 2
0
    def _query(self, server, queries=None, sleep=0.05):
        _udp = random.choice([True, False])
        _queries = list()

        if queries:
            for q in queries:
                query = dns.message.make_query(q[0], q[1], "IN")
                query.want_dnssec()
                _queries.append(query)
        else:
            for z in random.sample(list(server.zones),
                                   min(len(server.zones), 2)):
                query = dns.message.make_query(z, "SOA", "IN")
                query.want_dnssec()
                _queries.append(query)

        while self.active:
            try:
                for q in _queries:
                    if _udp:
                        dns.query.udp(q,
                                      server.addr,
                                      port=server.port,
                                      timeout=0.02)
                    else:
                        dns.query.tcp(q,
                                      server.addr,
                                      port=server.port,
                                      timeout=0.05)
            except:
                pass

            time.sleep(sleep)
Exemplo n.º 3
0
def get_a_answer(target, ns, timeout):
    query = dns.message.make_query(target, dns.rdatatype.A, dns.rdataclass.IN)
    query.flags += dns.flags.CD
    query.use_edns(edns=True, payload=4096)
    query.want_dnssec(True)
    answer = dns.query.udp(query, ns, timeout)
    return answer
Exemplo n.º 4
0
def get_a_answer(res, target, ns, timeout):
    query = dns.message.make_query(target, dns.rdatatype.A, dns.rdataclass.IN)
    query.flags += dns.flags.CD
    query.use_edns(edns=True, payload=4096)
    query.want_dnssec(True)
    answer = res.query(query, ns, timeout)
    return answer
Exemplo n.º 5
0
def get_ds_answer_old(target, ns, timeout):
    query = dns.message.make_query(target, dns.rdatatype.DS, dns.rdataclass.IN)
    query.flags += dns.flags.CD
    query.use_edns(edns=True, payload=4096)
    query.find_rrset(query.additional, dns.name.root, 65535,
                   dns.rdatatype.OPT, create=True, force_unique=True)
    query.want_dnssec(True)
    answer = dns.query.udp(query, ns, timeout)
    return answer
Exemplo n.º 6
0
def get_rr(zone, rrtype, ns_address, handler=None):
    """ rrtype must be a character _string_. handler is a function
    which will be called for each rrset (and receives it as a
    parameter). See display_target for an example of handker (it is
    suitable for a NS rrtype)."""
    mytype = dns.rdatatype.from_text(rrtype)
    query = dns.message.make_query(zone, rrtype)
    query.use_edns(edns=True, payload=edns_size)
    query.want_dnssec(True)
    tests = 0
    while tests < max_tests:
        try:
            response = dns.query.udp(query, ns_address, timeout=2)
            break
        except dns.exception.Timeout:
            tests += 1
            time.sleep(mytimeout * generator.randint(1, 3))
    if tests >= max_tests:
        # TODO: try with TCP, even without truncation? It seems to
        # work with Afilias servers
        default_log.warning("Timeout on %s query for %s on %s" % (rrtype, zone, address))
        sys.exit(1)
    if response.flags & dns.flags.TC: # We were truncated
        response = dns.query.tcp(query, address, timeout=2*mytimeout)
        # TODO: handle the case where the nameserver is broken enough to
        # truncate responses *and* to refuse TCP
    record_found = False
    cursor.execute("BEGIN IMMEDIATE TRANSACTION;"); 
    for rrset in response.answer:
        if rrset.rdtype == mytype:
            record_found = True
            if handler:
                handler(rrset)
        elif rrset.rdtype == dns.rdatatype.RRSIG:
            for thesig in rrset:
                if mytype != dns.rdatatype.DNSKEY and thesig.key_tag not in key_tags:
                     default_log.error("Signed with %s which is not in the key set" % \
                                   thesig.key_tag)
                sig_value = base64.b64encode(thesig.signature)
                cursor.execute("SELECT last_seen FROM Signatures WHERE signature=?;", (sig_value,))
                tuple = cursor.fetchone()
                if tuple is None:   
                    # TODO: store inception and expiration as actual times, not integers
                    cursor.execute("INSERT INTO Signatures (first_seen, last_seen, type, name, ttl, key_tag, algorithm, inception, expiration, signature) VALUES (datetime('now'), datetime('now'), ?, ?, ?, ?, ?, ?, ?, ?);", \
                                   (mytype, zone, rrset.ttl, thesig.key_tag,
                                    thesig.algorithm, thesig.inception, thesig.expiration, sig_value))
                else:
                    cursor.execute("UPDATE Signatures SET last_seen=datetime('now') WHERE signature=?;",
                                   (sig_value,))
    if not record_found:
        default_log.error("No %s at %s" % (rrtype, zone))
        sys.exit(1)
    database.commit()
Exemplo n.º 7
0
    def query_response_time(self):
        answer = ""
        try:
            query = dns.message.make_query(self.domain, dns.rdatatype.DS, dns.rdataclass.IN)
            query.flags += dns.flags.CD
            query.use_edns(edns=True, payload=4096)
            print(bcolor.YELLOW + "DNSSEC : " + str(query.want_dnssec(True)))

            print(bcolor.RED + "************Validación de disponibilidad de server DNS **************" + bcolor.GREEN)
            i=1
            for data in self.ns:
                print(bcolor.RED + "************ DNS Sever # {0} **************".format(i) + bcolor.GREEN)
                answer = dns.query.udp(query, socket.gethostbyname(data), self.timeout)
                print(bcolor.YELLOW + "Server: " + bcolor.WHITE + format(data) + bcolor.YELLOW + " IP : " + bcolor.WHITE + socket.gethostbyname(data) + bcolor.YELLOW + " Estado : " +  bcolor.WHITE + "Operativo" )
                print(bcolor.YELLOW + "Timeout : " + bcolor.WHITE)
                self.ping(socket.gethostbyname(data))
                print(bcolor.YELLOW + "Tamaño de carga util EDNS (payload) : " + bcolor.WHITE + str(answer.payload))
                print(bcolor.YELLOW + "Flags del mensaje: " + bcolor.WHITE + str(answer.flags))
                scan = NmapScan(str(socket.gethostbyname(data)))
                print("Sistema Operativo : " + scan.os)
                self.transfer_zone(socket.gethostbyname(data))
                i += 1
        except dns.exception.Timeout:
            print(bcolor.RED + " Advertencia!! -> Tiempo de espera superado al tratar de llegar al servidor DNS en {0} segundos ".format(self.timeout))
        except Exception as e:
            raise
Exemplo n.º 8
0
def query_ds(res, target, ns, timeout=5.0):
    """
    Function for performing DS Record queries. Returns answer object. Since a
    timeout will break the DS NSEC chain of a zone walk it will exit if a timeout
    happens.
    """
    try:
        query = dns.message.make_query(target, dns.rdatatype.DS, dns.rdataclass.IN)
        query.flags += dns.flags.CD
        query.use_edns(edns=True, payload=4096)
        query.want_dnssec(True)
        answer = res.query(query, ns, timeout)
    except dns.exception.Timeout:
        print_error("A timeout error occurred please make sure you can reach the target DNS Servers")
        print_error(
            "directly and requests are not being filtered. Increase the timeout from {0} second".format(timeout))
        print_error("to a higher number with --lifetime <time> option.")
        sys.exit(1)
    except Exception:
        print("Unexpected error: {0}".format(sys.exc_info()[0]))
        raise
    return answer
Exemplo n.º 9
0
    def dig(self, rname, rtype, rclass="IN", udp=None, serial=None,
            timeout=None, tries=3, flags="", bufsize=None, edns=None,
            nsid=False, dnssec=False, log_no_sep=False):
        key_params = self.tsig_test.key_params if self.tsig_test else dict()

        # Convert one item zone list to zone name.
        if isinstance(rname, list):
            if len(rname) != 1:
                raise Failed("One zone required")
            rname = rname[0].name

        rtype_str = rtype.upper()

        # Set port type.
        if rtype.upper() == "AXFR":
            # Always use TCP.
            udp = False
        elif rtype.upper() == "IXFR":
            # Use TCP if not specified.
            udp = udp if udp != None else False
            rtype_str += "=%i" % int(serial)
        else:
            # Use TCP or UDP at random if not specified.
            udp = udp if udp != None else random.choice([True, False])

        if udp:
            dig_flags = "+notcp"
        else:
            dig_flags = "+tcp"

        dig_flags += " +retry=%i" % (tries - 1)

        # Set timeout.
        if timeout is None:
            timeout = self.DIG_TIMEOUT
        dig_flags += " +time=%i" % timeout

        # Prepare query (useless for XFR).
        query = dns.message.make_query(rname, rtype, rclass)

        # Remove implicit RD flag.
        query.flags &= ~dns.flags.RD

        # Set packet flags.
        flag_names = flags.split()
        for flag in flag_names:
            if flag == "AA":
                query.flags |= dns.flags.AA
                dig_flags += " +aa"
            elif flag == "TC":
                query.flags |= dns.flags.TC
                dig_flags += " +tc"
            elif flag == "RD":
                query.flags |= dns.flags.RD
                dig_flags += " +rd"
            elif flag == "RA":
                query.flags |= dns.flags.RA
                dig_flags += " +ra"
            elif flag == "AD":
                query.flags |= dns.flags.AD
                dig_flags += " +ad"
            elif flag == "CD":
                query.flags |= dns.flags.CD
                dig_flags += " +cd"

        # Set EDNS.
        if edns != None or bufsize or nsid:
            class NsidFix(object):
                '''Current pythondns doesn't implement NSID option.'''
                def __init__(self):
                    self.otype = dns.edns.NSID
                def to_wire(self, file=None):
                    pass

            if edns:
                edns = int(edns)
            else:
                edns = 0
            dig_flags += " +edns=%i" % edns

            if bufsize:
                payload = int(bufsize)
            else:
                payload = 1280
            dig_flags += " +bufsize=%i" % payload

            if nsid:
                options = [NsidFix()]
                dig_flags += " +nsid"
            else:
                options = None

            query.use_edns(edns=edns, payload=payload, options=options)

        # Set DO flag.
        if dnssec:
            query.want_dnssec()
            dig_flags += " +dnssec +bufsize=%i" % query.payload

        # Store function arguments for possible comparation.
        args = dict()
        params = inspect.getargvalues(inspect.currentframe())
        for param in params.args:
            if param != "self":
                args[param] = params.locals[param]

        check_log("DIG %s %s %s @%s -p %i %s" %
                  (rname, rtype_str, rclass, self.addr, self.port, dig_flags))
        if key_params:
            detail_log("%s:%s:%s" %
                (self.tsig_test.alg, self.tsig_test.name, self.tsig_test.key))

        for t in range(tries):
            try:
                if rtype.upper() == "AXFR":
                    resp = dns.query.xfr(self.addr, rname, rtype, rclass,
                                         port=self.port, lifetime=timeout,
                                         use_udp=udp, **key_params)
                elif rtype.upper() == "IXFR":
                    resp = dns.query.xfr(self.addr, rname, rtype, rclass,
                                         port=self.port, lifetime=timeout,
                                         use_udp=udp, serial=int(serial),
                                         **key_params)
                elif udp:
                    resp = dns.query.udp(query, self.addr, port=self.port,
                                         timeout=timeout)
                else:
                    resp = dns.query.tcp(query, self.addr, port=self.port,
                                         timeout=timeout)

                if not log_no_sep:
                    detail_log(SEP)

                return dnstest.response.Response(self, resp, query, args)
            except dns.exception.Timeout:
                pass
            except:
                time.sleep(timeout)

        raise Failed("Can't query server='%s' for '%s %s %s'" % \
                     (self.name, rname, rclass, rtype))
Exemplo n.º 10
0
    def dig(self,
            rname,
            rtype,
            rclass="IN",
            udp=None,
            serial=None,
            timeout=None,
            tries=3,
            flags="",
            bufsize=None,
            edns=None,
            nsid=False,
            dnssec=False,
            log_no_sep=False):
        key_params = self.tsig_test.key_params if self.tsig_test else dict()

        # Convert one item zone list to zone name.
        if isinstance(rname, list):
            if len(rname) != 1:
                raise Failed("One zone required")
            rname = rname[0].name

        rtype_str = rtype.upper()

        # Set port type.
        if rtype.upper() == "AXFR":
            # Always use TCP.
            udp = False
        elif rtype.upper() == "IXFR":
            # Use TCP if not specified.
            udp = udp if udp != None else False
            rtype_str += "=%i" % int(serial)
        else:
            # Use TCP or UDP at random if not specified.
            udp = udp if udp != None else random.choice([True, False])

        if udp:
            dig_flags = "+notcp"
        else:
            dig_flags = "+tcp"

        dig_flags += " +retry=%i" % (tries - 1)

        # Set timeout.
        if timeout is None:
            timeout = self.DIG_TIMEOUT
        dig_flags += " +time=%i" % timeout

        # Prepare query (useless for XFR).
        query = dns.message.make_query(rname, rtype, rclass)

        # Remove implicit RD flag.
        query.flags &= ~dns.flags.RD

        # Set packet flags.
        flag_names = flags.split()
        for flag in flag_names:
            if flag == "AA":
                query.flags |= dns.flags.AA
                dig_flags += " +aa"
            elif flag == "TC":
                query.flags |= dns.flags.TC
                dig_flags += " +tc"
            elif flag == "RD":
                query.flags |= dns.flags.RD
                dig_flags += " +rd"
            elif flag == "RA":
                query.flags |= dns.flags.RA
                dig_flags += " +ra"
            elif flag == "AD":
                query.flags |= dns.flags.AD
                dig_flags += " +ad"
            elif flag == "CD":
                query.flags |= dns.flags.CD
                dig_flags += " +cd"

        # Set EDNS.
        if edns != None or bufsize or nsid:

            class NsidFix(object):
                '''Current pythondns doesn't implement NSID option.'''
                def __init__(self):
                    self.otype = dns.edns.NSID

                def to_wire(self, file=None):
                    pass

            if edns:
                edns = int(edns)
            else:
                edns = 0
            dig_flags += " +edns=%i" % edns

            if bufsize:
                payload = int(bufsize)
            else:
                payload = 1280
            dig_flags += " +bufsize=%i" % payload

            if nsid:
                options = [NsidFix()]
                dig_flags += " +nsid"
            else:
                options = None

            query.use_edns(edns=edns, payload=payload, options=options)

        # Set DO flag.
        if dnssec:
            query.want_dnssec()
            dig_flags += " +dnssec +bufsize=%i" % query.payload

        # Store function arguments for possible comparation.
        args = dict()
        params = inspect.getargvalues(inspect.currentframe())
        for param in params.args:
            if param != "self":
                args[param] = params.locals[param]

        check_log("DIG %s %s %s @%s -p %i %s" %
                  (rname, rtype_str, rclass, self.addr, self.port, dig_flags))
        if key_params:
            detail_log(
                "%s:%s:%s" %
                (self.tsig_test.alg, self.tsig_test.name, self.tsig_test.key))

        for t in range(tries):
            try:
                if rtype.upper() == "AXFR":
                    resp = dns.query.xfr(self.addr,
                                         rname,
                                         rtype,
                                         rclass,
                                         port=self.port,
                                         lifetime=timeout,
                                         use_udp=udp,
                                         **key_params)
                elif rtype.upper() == "IXFR":
                    resp = dns.query.xfr(self.addr,
                                         rname,
                                         rtype,
                                         rclass,
                                         port=self.port,
                                         lifetime=timeout,
                                         use_udp=udp,
                                         serial=int(serial),
                                         **key_params)
                elif udp:
                    resp = dns.query.udp(query,
                                         self.addr,
                                         port=self.port,
                                         timeout=timeout)
                else:
                    resp = dns.query.tcp(query,
                                         self.addr,
                                         port=self.port,
                                         timeout=timeout)

                if not log_no_sep:
                    detail_log(SEP)

                return dnstest.response.Response(self, resp, query, args)
            except dns.exception.Timeout:
                pass
            except:
                time.sleep(timeout)

        raise Failed("Can't query server='%s' for '%s %s %s'" % \
                     (self.name, rname, rclass, rtype))