Esempio n. 1
0
def check_decode(f,debug=False):
    errors = []

    # Parse the q/a records
    with open(f) as x:
        q,r = DigParser(x)

    # Grab the hex data
    with open(f,'rb') as x:
        for l in x.readlines():
            if l.startswith(b';; QUERY:'):
                qdata = binascii.unhexlify(l.split()[-1])
            elif l.startswith(b';; RESPONSE:'):
                rdata = binascii.unhexlify(l.split()[-1])

    # Parse the hex data
    qparse = DNSRecord.parse(qdata)
    rparse = DNSRecord.parse(rdata)

    # Check records generated from DiG input matches
    # records parsed from packet data
    if q != qparse:
        errors.append(('Question',q.diff(qparse)))
    if r != rparse:
        errors.append(('Reply',r.diff(rparse)))

    # Repack the data 
    qpack = qparse.pack()
    rpack = rparse.pack()

    # Check if repacked question data matches original 
    # We occasionally get issues where original packet did not 
    # compress all labels - in this case we reparse packed
    # record, repack this and compare with the packed data
    if qpack != qdata:
        if len(qpack) < len(qdata):
            # Shorter - possibly compression difference
            if DNSRecord.parse(qpack).pack() != qpack:
                errors.append(('Question Pack',(qdata,qpack)))
        else:
            errors.append(('Question Pack',(qdata,qpack)))
    if rpack != rdata:
        if len(rpack) < len(rdata):
            if DNSRecord.parse(rpack).pack() != rpack:
                errors.append(('Reply Pack',(rdata,rpack)))
        else:
            errors.append(('Reply Pack',(rdata,rpack)))

    if debug:
        if errors:
            print("ERROR\n")
            print_errors(errors)
            print()
            if input(">>> Inspect [y/n]? ").lower().startswith('y'):
                code.interact(local=locals())
            print()
        else:
            print("OK")

    return errors
Esempio n. 2
0
def print_errors(errors):
    for err,err_data in errors:
        if err == 'Question':
            print("Question error:")
            for (d1,d2) in err_data:
                if d1:
                    print(";; - %s" % d1)
                if d2:
                    print(";; + %s" % d2)
        elif err == 'Reply':
            print("Reply error:")
            for (d1,d2) in err_data:
                if d1:
                    print(";; - %s" % d1)
                if d2:
                    print(";; + %s" % d2)
        elif err == 'Question Pack':
            print("Question pack error")
            print("QDATA:",binascii.hexlify(err_data[0]))
            print(DNSRecord.parse(err_data[0]))
            print("QPACK:",binascii.hexlify(err_data[1]))
            print(DNSRecord.parse(err_data[1]))
        elif err == 'Reply Pack':
            print("Response pack error")
            print("RDATA:",binascii.hexlify(err_data[0]))
            print(DNSRecord.parse(err_data[0]))
            print("RPACK:",binascii.hexlify(err_data[1]))
            print(DNSRecord.parse(err_data[1]))
Esempio n. 3
0
def print_errors(errors):
    for err, err_data in errors:
        if err == 'Question':
            print("Question error:")
            for (d1, d2) in err_data:
                if d1:
                    print(";; - %s" % d1)
                if d2:
                    print(";; + %s" % d2)
        elif err == 'Reply':
            print("Reply error:")
            for (d1, d2) in err_data:
                if d1:
                    print(";; - %s" % d1)
                if d2:
                    print(";; + %s" % d2)
        elif err == 'Question Pack':
            print("Question pack error")
            print("QDATA:", binascii.hexlify(err_data[0]))
            print(DNSRecord.parse(err_data[0]))
            print("QPACK:", binascii.hexlify(err_data[1]))
            print(DNSRecord.parse(err_data[1]))
        elif err == 'Reply Pack':
            print("Response pack error")
            print("RDATA:", binascii.hexlify(err_data[0]))
            print(DNSRecord.parse(err_data[0]))
            print("RPACK:", binascii.hexlify(err_data[1]))
            print(DNSRecord.parse(err_data[1]))
Esempio n. 4
0
    def handle_job(self, job):
        domain = job["domain"]
        server = job["server"]
        port = job["port"]
        result_contains = job.get("result_contains", None)

        try:
            q = DNSRecord(q=DNSQuestion(domain)) #, getattr(QTYPE,"A")))

            a_pkt = q.send(server, port, tcp=False, timeout=10)
            a = DNSRecord.parse(a_pkt)

            found_record = False
            for record in a.rr:
                if (not result_contains):
                    QTYPE_A = getattr(QTYPE,"A")
                    QTYPE_CNAME = getattr(QTYPE, "CNAME")
                    if ((record.rtype==QTYPE_A) or (record.qtype==QTYPE_CNAME)):
                        found_record = True
                else:
                    tmp = QTYPE.get(record.rtype) + str(record.rdata)
                    if (result_contains in tmp):
                        found_record = True

            if not found_record:
                if result_contains:
                    job["status"] =  "%s,No %s records" % (domain, result_contains)
                else:
                    job["status"] =  "%s,No A or CNAME records" % domain

                return

        except Exception, e:
            job["status"] = "%s,Exception: %s" % (domain, str(e))
            return
Esempio n. 5
0
def check_decode(f, debug=False):
    errors = []

    # Parse the q/a records
    with open(f) as x:
        q, r = DigParser(x)

    # Grab the hex data
    with open(f, 'rb') as x:
        for l in x.readlines():
            if l.startswith(b';; QUERY:'):
                qdata = binascii.unhexlify(l.split()[-1])
            elif l.startswith(b';; RESPONSE:'):
                rdata = binascii.unhexlify(l.split()[-1])

    # Parse the hex data
    qparse = DNSRecord.parse(qdata)
    rparse = DNSRecord.parse(rdata)

    # Check records generated from DiG input matches
    # records parsed from packet data
    if q != qparse:
        errors.append(('Question', q.diff(qparse)))
    if r != rparse:
        errors.append(('Reply', r.diff(rparse)))

    # Repack the data
    qpack = qparse.pack()
    rpack = rparse.pack()

    # Check if repacked question data matches original
    # We occasionally get issues where original packet did not
    # compress all labels - in this case we reparse packed
    # record, repack this and compare with the packed data
    if qpack != qdata:
        if len(qpack) < len(qdata):
            # Shorter - possibly compression difference
            if DNSRecord.parse(qpack).pack() != qpack:
                errors.append(('Question Pack', (qdata, qpack)))
        else:
            errors.append(('Question Pack', (qdata, qpack)))
    if rpack != rdata:
        if len(rpack) < len(rdata):
            if DNSRecord.parse(rpack).pack() != rpack:
                errors.append(('Reply Pack', (rdata, rpack)))
        else:
            errors.append(('Reply Pack', (rdata, rpack)))

    if debug:
        if errors:
            print("ERROR\n")
            print_errors(errors)
            print()
            if input(">>> Inspect [y/n]? ").lower().startswith('y'):
                code.interact(local=locals())
            print()
        else:
            print("OK")

    return errors
Esempio n. 6
0
 def _recursive_query(self, questions, region, tracking_chain, records):
     unanswers_questions, recursive_questions = [], []
     for question in questions:
         has_reply = False
         for record in records:
             if question.qname == record.full_subdomain \
                     and record.status == 1 \
                     and question.qclass == record.rclass:
                 if question.qtype == record.rtype:
                     has_reply = True
                 elif record.rtype == QTYPE.CNAME:
                     has_reply = True
                     question = DNSQuestion(qname=record.content,
                                            qtype=question.qtype,
                                            qclass=record.rclass)
                     if question in tracking_chain: continue
                     tracking_chain.append(question)
                     recursive_questions.append(question)
         if not has_reply: unanswers_questions.append(question)
     if len(unanswers_questions) > 0:
         request = DNSRecord()
         request.add_question(*unanswers_questions)
         records = [
             Record(full_subdomain=r.rname,
                    rtype=r.rtype,
                    rclass=r.rclass,
                    content=str(r.rdata),
                    ttl=r.ttl,
                    status=1) for r in self.remote.query(request).rr
         ]
         self._set_cached_records(records, region)
         yield from records
     yield from self._query(recursive_questions, region, tracking_chain)
Esempio n. 7
0
    def handle_job(self, job):
        domain = job["domain"]
        server = job["server"]
        port = job["port"]
        result_contains = job.get("result_contains", None)

        try:
            q = DNSRecord(q=DNSQuestion(domain))  #, getattr(QTYPE,"A")))

            a_pkt = q.send(server, port, tcp=False, timeout=10)
            a = DNSRecord.parse(a_pkt)

            found_record = False
            for record in a.rr:
                if (not result_contains):
                    if ((record.rtype == QTYPE_A)
                            or (record.qtype == QTYPE_CNAME)):
                        found_record = True
                else:
                    tmp = QTYPE.get(record.rtype) + str(record.rdata)
                    if (result_contains in tmp):
                        found_record = True

            if not found_record:
                if result_contains:
                    job["status"] = "%s,No %s records" % (domain,
                                                          result_contains)
                else:
                    job["status"] = "%s,No A or CNAME records" % domain

                return

        except Exception, e:
            job["status"] = "%s,Exception: %s" % (domain, str(e))
            return
Esempio n. 8
0
 def parse(self):
     dns = None
     section = None
     paren = False
     rr = []
     try:
         while True:
             tok, val = next(self.i)
             if tok == 'COMMENT':
                 if val.startswith('; ->>HEADER<<-'):
                     # Start new record
                     if dns:
                         # If we have a current record complete this
                         self.parseQuestions(q, dns)
                         self.parseAnswers(a, auth, ar, dns)
                         yield (dns)
                     dns = DNSRecord()
                     q, a, auth, ar = [], [], [], []
                     self.expect('NL')
                     val2 = self.expect('COMMENT')
                     dns.header = self.parseHeader(val, val2)
                 elif val.startswith('; QUESTION'):
                     section = q
                 elif val.startswith('; ANSWER'):
                     section = a
                 elif val.startswith('; AUTHORITY'):
                     section = auth
                 elif val.startswith('; ADDITIONAL'):
                     section = ar
                 elif val.startswith('; OPT'):
                     # Only partial support for parsing EDNS records
                     self.expect('NL')
                     val2 = self.expect('COMMENT')
                     self.parseEDNS(val2, dns)
                 elif val.startswith(';') or tok[1].startswith('<<>>'):
                     pass
                 elif dns and section == q:
                     q.append(val.split())
             elif tok == 'ATOM':
                 if val == '(':
                     paren = True
                 elif val == ')':
                     paren = False
                 else:
                     rr.append(val)
             elif tok == 'NL' and not paren and rr:
                 if self.debug:
                     print(">>", rr)
                 section.append(rr)
                 rr = []
     except StopIteration:
         if rr:
             self.section.append(rr)
         if dns:
             self.parseQuestions(q, dns)
             self.parseAnswers(a, auth, ar, dns)
             yield (dns)
Esempio n. 9
0
def new_test(domain,qtype,address="8.8.8.8",port=53,nodig=False,dnssec=False):
    tcp = False
    q = DNSRecord.question(domain,qtype)
    if dnssec:
        q.add_ar(EDNS0(flags="do",udp_len=4096))
        q.header.ad = 1
    a_pkt = q.send(address,port)
    a = DNSRecord.parse(a_pkt)
    if a.header.tc:
        tcp = True
        a_pkt = q.send(address,port,tcp)
        a = DNSRecord.parse(a_pkt)

    if not nodig:
        if dnssec:
            dig = getoutput("dig +qr +dnssec -p %d %s %s @%s" % (
                            port, domain, qtype, address))
        else:
            dig = getoutput("dig +qr +noedns +noadflag -p %d %s %s @%s" % (
                            port, domain, qtype, address))
        dig_reply = list(iter(DigParser(dig)))
        # DiG might have retried in TCP mode so get last q/a
        q_dig = dig_reply[-2]
        a_dig = dig_reply[-1]

        if q != q_dig or a != a_dig:
            if q != q_dig:
                print(";;; ERROR: Diff Question differs")
                for (d1,d2) in q.diff(q_dig):
                    if d1:
                        print(";; - %s" % d1)
                    if d2:
                        print(";; + %s" % d2)
            if a != a_dig:
                print(";;; ERROR: Diff Response differs")
                for (d1,d2) in a.diff(a_dig):
                    if d1:
                        print(";; - %s" % d1)
                    if d2:
                        print(";; + %s" % d2)
            return

    if dnssec:
        fname = "%s-%s-dnssec" % (domain,qtype)
    else:
        fname = "%s-%s" % (domain,qtype)
    print("Writing test file: %s" % (fname))
    with open(fname,"w") as f:
        print(";; Sending:",file=f)
        print(";; QUERY:",binascii.hexlify(q.pack()).decode(),file=f)
        print(q,file=f)
        print(file=f)
        print(";; Got answer:",file=f)
        print(";; RESPONSE:",binascii.hexlify(a_pkt).decode(),file=f)
        print(a,file=f)
        print(file=f)
Esempio n. 10
0
def resolveDNS(query, server, port, type="A"):
    allowedTypes = ("A", "AAAA", "PTR")
    if type not in allowedTypes:
        raise ValueError
    ipv6Server = False
    if isinstance(ip_address(server), IPv6Address):
        ipv6Server = True
    q = DNSRecord.question(query, type)
    answer_paquet = q.send(server, port, tcp=False, ipv6=ipv6Server)
    a = DNSRecord.parse(answer_paquet)
    return [str(a.rr[i].rdata) for i in range(len(a.rr))]
Esempio n. 11
0
    async def query(self, query_type: str, dns_query: str) -> None:
        query = DNSRecord(q=DNSQuestion(dns_query, getattr(QTYPE, query_type)))
        stream_id = self._quic.get_next_available_stream_id()
        logger.debug(f"Stream ID: {stream_id}")
        end_stream = False
        self._quic.send_stream_data(stream_id, bytes(query.pack()), end_stream)
        waiter = self._loop.create_future()
        self._ack_waiter = waiter
        self.transmit()

        return await asyncio.shield(waiter)
Esempio n. 12
0
 def parse(self):
     dns = None
     section = None
     paren = False
     rr = []
     try:
         while True:
             tok,val = next(self.i)
             if tok == 'COMMENT':
                 if 'Sending:' in val or 'Got answer:' in val:
                     if dns:
                         self.parseQuestions(q,dns)
                         self.parseAnswers(a,auth,ar,dns)
                         yield(dns)
                     dns = DNSRecord()
                     q,a,auth,ar = [],[],[],[]
                 elif val.startswith('; ->>HEADER<<-'):
                     self.expect('NL')
                     val2 = self.expect('COMMENT')
                     dns.header = self.parseHeader(val,val2)
                 elif val.startswith('; QUESTION'):
                     section = q
                 elif val.startswith('; ANSWER'):
                     section = a
                 elif val.startswith('; AUTHORITY'):
                     section = auth
                 elif val.startswith('; ADDITIONAL'):
                     section = ar
                 elif val.startswith(';') or tok[1].startswith('<<>>'):
                     pass
                 elif dns and section == q:
                     q.append(val.split())
             elif tok == 'ATOM':
                 if val == '(':
                     paren = True
                 elif val == ')':
                     paren = False
                 else:
                     rr.append(val)
             elif tok == 'NL' and not paren and rr:
                 if self.debug:
                     print(">>",rr)
                 section.append(rr)
                 rr = []
     except StopIteration:
         if rr:
             self.section.append(rr)
         if dns:
             self.parseQuestions(q,dns)
             self.parseAnswers(a,auth,ar,dns)
             yield(dns)
Esempio n. 13
0
def dns_request(domain, qtype, address, port):
    """
        Simple DNS Client - may be used to testing responses
        from DNS server. Results are displayed in the console

        domain		- domain to resolve
        qtype		- DNS record type
        address		- DNS server address
        port		- DNS server port
    """
    request = DNSRecord.question(domain, qtype)
    paket = request.send(address, port)
    answer = DNSRecord.parse(paket)
    return answer
Esempio n. 14
0
 def parser(self, payload):
     data = DNSRecord.parse(payload)
     p_id = data.header.id
     name = str(data.q.qname).rstrip('.')
     q_typeid = data.q.qtype
     q_type = RTYPE[q_typeid]
     return p_id, name, q_type, q_typeid
Esempio n. 15
0
 def _forward_resolve(self, request, handler):
     if handler.protocol == 'udp':
         proxy_r = request.send(self.address, self.port, tcp=False, timeout=self.DEFAULT_TIMEOUT)
     else:
         proxy_r = request.send(self.address, self.port, tcp=True, timeout=self.DEFAULT_TIMEOUT)
     reply = DNSRecord.parse(proxy_r)
     return reply
def get_login_info(name,_TYPE_SRV_AND_CLASS_IN=[(33, 1), (16, 1), (1, 1)]):
    timeout = .5
    socs=[]
    out = create_socket_request(name,_TYPE_SRV_AND_CLASS_IN=[(33, 1), (16, 1), (1, 1)])

    _listen_socket = new_socket()

    for _broadcast_scoket in create_broadcast_sockets(_listen_socket):
        _broadcast_scoket.sendto(out.packet(),0,(_MDNS_ADDR, _MDNS_PORT))
    info_dict={}

    tmp_output_dns_data=True
    while tmp_output_dns_data==True:
        rr, wr, er = select.select([_listen_socket], [], [], timeout)

        for _socket in rr:
            data,addr= _socket.recvfrom(_MAX_MSG_ABSOLUTE)
            tmp_data=data

            if 'apple' in str(tmp_data) and 'aV' in str(tmp_data):
                # return DNSRecord.parse(data)
                tmp_output_dns_data=DNSRecord.parse(data)
                break
    info_dict['ip']=addr[0]
    info_dict['port']=tmp_output_dns_data.rr[1].rdata._port

    for x in tmp_output_dns_data.rr[0].rdata.data:
        k,v=x.decode('utf-8').split('=')
        info_dict[k]=v

    info_dict['device_tcp_name']=name
    info_dict['HSGID']=info_dict['hG']
    info_dict['ADDRESS']=info_dict['ip']
    info_dict['NAME']=info_dict['Name']
    return info_dict
Esempio n. 17
0
 def quic_event_received(self, event: QuicEvent) -> None:
     if self._ack_waiter is not None:
         if isinstance(event, StreamDataReceived):
             answer = DNSRecord.parse(event.data)
             logger.info(answer)
             waiter = self._ack_waiter
             self._ack_waiter = None
             waiter.set_result(None)
Esempio n. 18
0
def new_test(domain,qtype,address="8.8.8.8",port=53,nodig=False):
    tcp = False
    q = DNSRecord.question(domain,qtype)
    a_pkt = q.send(address,port)
    a = DNSRecord.parse(a_pkt)
    if a.header.tc:
        tcp = True
        a_pkt = q.send(address,port,tcp)
        a = DNSRecord.parse(a_pkt)

    if not nodig:
        dig = getoutput("dig +qr -p %d %s %s @%s" % (
                            port, domain, qtype, address))
        dig_reply = list(iter(DigParser(dig)))
        # DiG might have retried in TCP mode so get last q/a
        q_dig = dig_reply[-2]
        a_dig = dig_reply[-1]

        if q != q_dig or a != a_dig:
            if q != q_dig:
                print(";;; ERROR: Diff Question differs")
                for (d1,d2) in q.diff(q_dig):
                    if d1:
                        print(";; - %s" % d1)
                    if d2:
                        print(";; + %s" % d2)
            if a != a_dig:
                print(";;; ERROR: Diff Response differs")
                for (d1,d2) in a.diff(a_dig):
                    if d1:
                        print(";; - %s" % d1)
                    if d2:
                        print(";; + %s" % d2)
            return

    print("Writing test file: %s-%s" % (domain,qtype))
    with open("%s-%s" % (domain,qtype),"w") as f:
        print(";; Sending:",file=f)
        print(";; QUERY:",binascii.hexlify(q.pack()).decode(),file=f)
        print(q,file=f)
        print(file=f)
        print(";; Got answer:",file=f)
        print(";; RESPONSE:",binascii.hexlify(a_pkt).decode(),file=f)
        print(a,file=f)
        print(file=f)
Esempio n. 19
0
 def _resolve_other(self, request, handler):
     reply = request.reply()
     if not reply.rr:
         if handler.protocol == 'udp':
             proxy_r = request.send(self.address,self.port, tcp=False, timeout=self.DEFAULT_TIMEOUT)
         else:
             proxy_r = request.send(self.address,self.port,tcp=True, timeout=self.DEFAULT_TIMEOUT)
         reply = DNSRecord.parse(proxy_r)
     return reply
Esempio n. 20
0
def check_mx_records(domain, cache_timeout=60 * 60):
    if domain in _mx_records_cache:
        timeout, valid = _mx_records_cache[domain]
        if time() < timeout:
            return valid

    q = DNSRecord(q=DNSQuestion(domain, getattr(QTYPE, 'MX')))

    a_pkt = q.send('8.8.8.8', 53, tcp=False)
    a = DNSRecord.parse(a_pkt)

    if a.header.tc:  # pragma: no cover
        a_pkt = q.send('8.8.8.8', 53, tcp=True)
        a = DNSRecord.parse(a_pkt)

    valid = len(a.short()) > 0
    _mx_records_cache[domain] = (time() + cache_timeout, valid)
    return valid
Esempio n. 21
0
def repack(data, qid, cached_time):
    record = DNSRecord.parse(data)
    record.header.id = qid
    now = int(time.time())
    for r in record.rr:
        ttl = cached_time + r.ttl - now
        if ttl <= 0:
            return None
        r.ttl = ttl
    return record.pack()
Esempio n. 22
0
    def resolve(self, request: DNSRecord, handler: DNSHandler):
        reply = request.reply()
        qname = request.q.qname
        qtype = QTYPE[request.q.qtype]
        # print(f'{qtype} {qname}')
        matched = False
        for name in self.zones:
            if qname.matchGlob(name):
                if qtype in ('A', 'AAAA', 'ANY', 'CNAME'):
                    if qtype == 'AAAA':
                        continue # currently only A records supported
                    answer = self.local_resolve(qname, qtype)
                    if answer:
                        reply.add_answer(*answer)
            matched = True

        if not matched:
            use_tcp = handler.protocol != "udp"
            reply = DNSRecord.parse(request.send(self.upstream_address, self.upstream_port, tcp=use_tcp))
        return reply
Esempio n. 23
0
 def gen_packet(self, p_id, qname, rcode, ttl, q_type, rdata):
     header = DNSHeader(id=p_id, qr=1, ra=1, aa=1, bitmap=rcode)
     packet = DNSRecord(header)
     packet.add_question(DNSQuestion(qname))
     packet.add_answer(
         *RR.fromZone("{} {} {} {}".format(qname, ttl, q_type, rdata)))
     return packet
Esempio n. 24
0
    def smart_route_dns_query(self):
        xlog.info("Start testing SmartRouter DNS Query")
        domain = "appsec.hicloud.com"
        d = DNSRecord(DNSHeader(123))
        d.add_question(DNSQuestion(domain, 1))
        req4_pack = d.pack()

        for port in [8053, 53]:
            sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            sock.sendto(req4_pack, ("127.0.0.1", port))
            sock.settimeout(5)

            try:
                response, server = sock.recvfrom(8192)
            except Exception as e:
                xlog.warn("recv fail for port:%s e:%r", port, e)
                continue

            p = DNSRecord.parse(response)
            for r in p.rr:
                ip = utils.to_bytes(str(r.rdata))
                xlog.info("IP:%s" % ip)
                self.assertEqual(utils.check_ip_valid(ip), True)

            xlog.info("Finished testing SmartRouter DNS Query")
            return
Esempio n. 25
0
 def _forward_resolve(self, request, handler):
     if handler.protocol == 'udp':
         proxy_r = request.send(self.address,
                                self.port,
                                tcp=False,
                                timeout=self.DEFAULT_TIMEOUT)
     else:
         proxy_r = request.send(self.address,
                                self.port,
                                tcp=True,
                                timeout=self.DEFAULT_TIMEOUT)
     reply = DNSRecord.parse(proxy_r)
     return reply
Esempio n. 26
0
 def query(self, c_id, m_addr):
     header = DNSHeader(qr=0, aa=1, ra=1)
     transfer_packet = DNSRecord(header)
     transfer_packet.add_question(DNSQuestion(c_id))
     response = transfer_packet.send(dest=m_addr, port=10053)
     ans = DNSRecord.parse(response)
     rcode, rdata = ans.header.rcode, str(ans.a.rdata)
     return rcode, rdata
Esempio n. 27
0
 def resolve(self, request, handler):
     qll = [[] for _ in range(len(self._targets))]
     a = request.reply()
     for q in request.questions:
         for name, jump in self._rules:
             if q.qname.matchSuffix(name) and isinstance(jump, int):
                 qll[jump].append(q)
                 break
             if q.qname == name and q.qclass == CLASS.IN:
                 if q.qtype == QTYPE.A and isinstance(jump, IPv4Address):
                     a.add_answer(RR(q.qname, QTYPE.A, CLASS.IN, 1, dns.A(str(jump))))
                     break
                 if q.qtype == QTYPE.AAAA and isinstance(jump, IPv6Address):
                     a.add_answer(RR(q.qname, QTYPE.AAAA, CLASS.IN, 1, dns.AAAA(str(jump))))
                     break
         else:
             qll[0].append(q)
     for i, ql in enumerate(qll):
         if not len(ql):
             continue
         ur = DNSRecord(header=request.header)
         ur.add_question(*ql)
         a.add_answer(*self._targets[i].resolve(ur, handler).rr)
     return a
Esempio n. 28
0
 def _resolve_other(self, request, handler):
     reply = request.reply()
     if not reply.rr:
         if handler.protocol == 'udp':
             proxy_r = request.send(self.address,
                                    self.port,
                                    tcp=False,
                                    timeout=self.DEFAULT_TIMEOUT)
         else:
             proxy_r = request.send(self.address,
                                    self.port,
                                    tcp=True,
                                    timeout=self.DEFAULT_TIMEOUT)
         reply = DNSRecord.parse(proxy_r)
     return reply
Esempio n. 29
0
 def _query(self, request):
     address, port = self.nameservers[0].split(":")
     port = int(port or 53)
     addrinfo = socket.getaddrinfo(address, port)
     try:
         if len(addrinfo[0][-1]) == 2:  # ipv4
             a_pkt = request.send(address, port, self.protocol == "TCP",
                                  self.timeout, False)
         else:
             a_pkt = request.send(address, port, self.protocol == "TCP",
                                  self.timeout, True)
         return DNSRecord.parse(a_pkt)
     except socket.timeout as e:
         logger.debug(e)
         self.nameservers.append(self.nameservers.pop(0))
Esempio n. 30
0
    def resolve(self, request, handler):
        now = int(time())
        a = request.reply()

        uq = DNSRecord()
        self._resolve_in_cache(request.questions, uq, a, now)

        if len(uq.questions):
            for upstream in self._upstreams:
                try:
                    ua_pkt = uq.send(
                        str(upstream.address),
                        upstream.port,
                        upstream.tcp,
                        upstream.timeout,
                        upstream.ipv6
                    )
                    ua = DNSRecord.parse(ua_pkt)
                except:
                    continue

                for rr in ua.rr:
                    key = (rr.rname, rr.rtype, rr.rclass)
                    cr = self._Record(now + rr.ttl, {
                        'rname': rr.rname,
                        'rtype': rr.rtype,
                        'rclass': rr.rclass,
                        'rdata': rr.rdata,
                    })
                    self._add_to_cache(key, cr)
                a.add_answer(*ua.rr)
                break
            else:
                raise IOError

        return a
Esempio n. 31
0
 def gen_packet(self, p_id, qname, rcode, q_typeid, rdata):
     header = DNSHeader(id=p_id, qr=1, ra=1, aa=1, bitmap=rcode)
     packet = DNSRecord(header)
     packet.add_question(DNSQuestion(qname))
     if rcode == 0:  #NOERROR
         packet.add_answer(
             RR.fromZone("{} {} {} {}".format(name, answer_data.a.ttl,
                                              q_typeid, str(rdata))))
         return packet
     else:
         return packet
Esempio n. 32
0
    def _badWeb_Potect(self, datapath, msg):
        print "in _badWeb_Potect"
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        pkt = packet.Packet(msg.data)
        hdata = utils.hex_array(msg.data)
        hdata = hdata.split(' ')
        hex_data = ''
        for hexdata in hdata:
            cc = hexdata.replace('0x', '')
            if len(cc) == 1:
                cc = '0%s' % cc
            hex_data = hex_data + cc
        # print "hex_data", hex_data
        # print 'pkt:', pkt

        hex_dnsdata = hex_data[84:]
        # print "dns hex data", hex_dnsdata
        dns_binary = binascii.unhexlify(hex_dnsdata)
        dns = DNSRecord.parse(dns_binary)
        # print 'dns:', dns
        dns
        web_name = dns.questions[0].get_qname().label
        web_name = ".".join(list(web_name))
        # print web_name

        try:
            conn = MySQLdb.connect(host='localhost',
                                   user='******',
                                   passwd='123456',
                                   db='web',
                                   port=3306)
            cur = conn.cursor()
            select = 'select * from WEB_lacklist where name="%s"' % web_name
            if (cur.execute(select)):
                print ' ilegal web  "%s", it`s dangerous! you  can`t to access it.' % web_name
                cur.close()
                conn.close()
                return
            else:
                print 'legal web "%s",you can access it.' % web_name
                cur.close()
                conn.close()
                self._forwarding(datapath, msg)
        except MySQLdb.Error, e:
            print "Mysql Error %d: %s" % (e.args[0], e.args[1])
Esempio n. 33
0
    def _badWeb_Potect(self, datapath, msg):
        print "in _badWeb_Potect"
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        pkt = packet.Packet(msg.data)
        hdata = utils.hex_array(msg.data)
        hdata = hdata.split(' ')
        hex_data = ''
        for hexdata in hdata:
            cc = hexdata.replace('0x', '')
            if len(cc) == 1:
                cc = '0%s' % cc
            hex_data = hex_data + cc
        # print "hex_data", hex_data
        # print 'pkt:', pkt

        hex_dnsdata = hex_data[84:]
        # print "dns hex data", hex_dnsdata
        dns_binary = binascii.unhexlify(hex_dnsdata)
        dns = DNSRecord.parse(dns_binary)
        # print 'dns:', dns
        dns
        web_name = dns.questions[0].get_qname().label
        web_name = ".".join(list(web_name))
        # print web_name

        try:
            conn = MySQLdb.connect(
                host='localhost', user='******', passwd='123456', db='web', port=3306)
            cur = conn.cursor()
            select = 'select * from WEB_lacklist where name="%s"' % web_name
            if(cur.execute(select)):
                print ' ilegal web  "%s", it`s dangerous! you  can`t to access it.' % web_name
                cur.close()
                conn.close()
                return
            else:
                print 'legal web "%s",you can access it.' % web_name
                cur.close()
                conn.close()
                self._forwarding(datapath, msg)
        except MySQLdb.Error, e:
            print "Mysql Error %d: %s" % (e.args[0], e.args[1])
Esempio n. 34
0
 def parser(self, payload):
     data = DNSRecord.parse(payload)
     p_id = data.header.id
     name = str(data.q.qname).rstrip('.')
     q_typeid = data.q.qtype
     q_type = RTYPE[q_typeid]
     rcode = data.header.rcode
     answer = {'p_id': p_id, 'name': name, 'q_type': q_type}
     qr = data.header.qr
     if qr == 0:
         return answer
     else:
         rcode = data.header.rcode
         if rcode == 0:
             answer['rdata'] = str(data.a.rdata)
             answer['ttl'] = data.a.ttl
             answer['rcode'] = rcode
             return answer
         else:
             answer['rcode'] = rcode
             return answer
Esempio n. 35
0
def query(request):
    qname = request.GET.get('qname')
    qtype = int(request.GET.get('qtype', 1))
    qclass = int(request.GET.get('qclass', 1))
    origin = request.GET.get('origin', request.META.get(
        'HTTP_X_FORWARDED_FOR', request.META['REMOTE_ADDR']))
    return JsonResponse({
        "qname": qname,
        "qtype": qtype,
        "qclass": qclass,
        "rr":[
            {
                "rname": "%s" % r.rname,
                "rtype": r.rtype,
                "rclass": r.rclass,
                "rdata": "%s" % r.rdata,
                "ttl": r.ttl,
            }
            for r in LocalQueryProxy().query(DNSRecord(
                q=DNSQuestion(qname=qname, qtype=qtype, qclass=qclass)),
                origin).rr
        ]
    })
Esempio n. 36
0
    def smart_route_dns_query(self):
        xlog.info("Start testing SmartRouter DNS Query")
        domain = "appsec.hicloud.com"
        d = DNSRecord(DNSHeader(123))
        d.add_question(DNSQuestion(domain, 1))
        req4_pack = d.pack()

        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.sendto(req4_pack, ("127.0.0.1", 53))
        sock.sendto(req4_pack, ("127.0.0.1", 8053))

        response, server = sock.recvfrom(8192)
        p = DNSRecord.parse(response)
        for r in p.rr:
            ip = utils.to_bytes(str(r.rdata))
            xlog.info("IP:%s" % ip)
            self.assertEqual(utils.check_ip_valid(ip), True)

        xlog.info("Finished testing SmartRouter DNS Query")
Esempio n. 37
0
def nslookup(domain, nservers=['8.8.8.8', '114.114.114']):
    global tested_ips, ip_is_enough, inactive_servers, good_servers

    if ip_is_enough: return
    try:
        q = DNSRecord(q=DNSQuestion(domain, getattr(QTYPE,'A')))
        a_pkt = q.send(nservers[0], 53, tcp=False, timeout=3)
        a = DNSRecord.parse(a_pkt)
        if a.header.tc:
            # Truncated - retry in TCP mode
            a_pkt = q.send(nservers[0], 53, tcp=True, timeout=3)
            a = DNSRecord.parse(a_pkt)
        a = a.short()
        if not a:
            raise Exception('no response.')
    except Exception as e:
        with lock:
            if nservers[0] not in inactive_servers:
                inactive_servers.add(nservers[0])
                #print(inactive_servers)
            if nservers[0] in good_servers:
                good_servers.remove(nservers[0])
            print('dns error: ', domain, nservers[0], e)
        return
    a = a.split('\n')

    if nservers[0] in inactive_servers:
        inactive_servers.remove(nservers[0])
    for ip in a:
        if ip[-1] != '.':  ##  maybe CNAME
            with lock:
                if ip_is_enough:
                    break
                if ip in tested_ips:
                    continue
                tested_ips.add(ip)
            if checkip(ip, domain):
                with lock:
                    if nservers[0] not in good_servers:
                        good_servers.add(nservers[0])
Esempio n. 38
0
    def resolve(self, request, handler):
        reply = request.reply()
        qname = request.q.qname

        suffix = DNSLabel(self.origin)
        if str(qname.label[-len(suffix.label):]).lower() == str(suffix.label).lower():
            rem = DNSLabel(qname.label[:-len(suffix.label)])
            print(rem)

            found_rrs = []
            found_glob = []
            rrs = []
            for extra in ZoneExtra.objects.all():
                rrs += RR.fromZone(extra.entry)
            for dyn in DynamicEntry.objects.all():
                rrs += RR.fromZone(dyn.combined)
            for rr in rrs:
                if rem.matchSuffix(rr.rname):
                    rr.rname.label += self.origin.label
                    found_rrs.append(rr)
                elif rem.matchGlob(rr.rname):
                    rr.rname.label += self.origin.label
                    found_glob.append(rr)


            if len(found_rrs):
                reply.add_auth(*RR.fromZone(f"{self.origin} 60 IN NS {settings.DNS_BASE_DOMAIN}"))
                reply.add_answer(*found_rrs)
            elif len(found_glob):
                reply.add_auth(*RR.fromZone(f"{self.origin} 60 IN NS {settings.DNS_BASE_DOMAIN}"))
                for g in found_glob:
                    g.set_rname(qname)
                reply.add_answer(*found_glob)

            cts = Container.objects.filter(name=str(str(rem)[:-1]).lower())
            if cts.exists():
                ct = cts.first()
                reply.add_auth(*RR.fromZone(f"{self.origin} 60 IN NS {settings.DNS_BASE_DOMAIN}"))

                if request.q.qtype == QTYPE.A:
                    for ip in ct.ip_set.all():
                        if ip.is_ipv4:
                            reply.add_answer(RR(qname, QTYPE.A, ttl=self.ttl,
                                                rdata=A(ip.ip)))
                        elif ip.siit_ip.exists():
                            reply.add_answer(RR(qname, QTYPE.A, ttl=self.ttl,
                                                rdata=A(ip.siit_ip.first().ip)))
                if request.q.qtype == QTYPE.AAAA:
                    for ip in ct.ip_set.all():
                        if not ip.is_ipv4:
                            reply.add_answer(RR(qname, QTYPE.AAAA, ttl=self.ttl,
                                                rdata=AAAA(ip.ip)))
            # try other server
            if len(reply.rr) == 0 and (settings.DNS_MIRROR_SERVER is not None):
                print("checking other server because no rr and env: .%s. "%settings.DNS_MIRROR_SERVER)
                connections.close_all()  # might fail
                apk = request.send(settings.DNS_MIRROR_SERVER, 53, timeout=30)
                reply = DNSRecord.parse(apk)

            if len(reply.rr) == 0:
                reply.header.rcode = RCODE.NOERROR
        else:
            reply.header.rcode = RCODE.NXDOMAIN

        connections.close_all()
        return reply
Esempio n. 39
0
        reply = request.reply()
        reply.add_answer(*RR.fromZone(f"{domain_query} 60 A {ip_address}"))
        return reply


resolver = BasicResolver()
logger = DNSLogger(prefix=False)
server = DNSServer(resolver,
                   port=PORT,
                   address=DNS_SERVER_IP_ADDRESS,
                   logger=logger)
server.start_thread()

# Testing
if TEST:
    print("Testing connection...")
    q = DNSRecord.question("www.bank.com")
    print("Sending request to server...\n")
    a = q.send(DNS_SERVER_IP_ADDRESS, PORT)
    print("\n\nParsing reply from server...\n")
    print(DNSRecord.parse(a))
    time.sleep(2)
    print("Test done...")
    time.sleep(1)
    print("\n" * 20)

print(f"Hosting server at {DNS_SERVER_IP_ADDRESS}:{PORT}")
print("Ctrl-C to stop server...")

while True:
    pass
def pan_dig(domain):
    import argparse, sys, time

    p = argparse.ArgumentParser(description="DNS Client")
    p.add_argument(
        "--server",
        "-s",
        default="8.8.8.8",
        metavar="<address:port>",
        help="Server address:port (default:8.8.8.8:53) (port is optional)")
    p.add_argument("--query",
                   action='store_true',
                   default=False,
                   help="Show query (default: False)")
    p.add_argument("--hex",
                   action='store_true',
                   default=False,
                   help="Dump packet in hex (default: False)")
    p.add_argument("--tcp",
                   action='store_true',
                   default=True,
                   help="Use TCP (default: UDP)")
    p.add_argument(
        "--noretry",
        action='store_true',
        default=False,
        help="Don't retry query using TCP if truncated (default: false)")
    p.add_argument(
        "--diff",
        default="",
        help=
        "Compare response from alternate nameserver (format: address:port / default: false)"
    )
    p.add_argument(
        "--dig",
        action='store_true',
        default=False,
        help=
        "Compare result with DiG - if ---diff also specified use alternative nameserver for DiG request (default: false)"
    )
    p.add_argument("--short",
                   action='store_true',
                   default=True,
                   help="Short output - rdata only (default: false)")
    p.add_argument("--debug",
                   action='store_true',
                   default=False,
                   help="Drop into CLI after request (default: false)")
    p.add_argument("domain", metavar="<domain>", help="Query domain")
    p.add_argument("qtype",
                   metavar="<type>",
                   default="A",
                   nargs="?",
                   help="Query type (default: A)")
    args = p.parse_args(['--tcp', '--short', domain])

    # Construct request
    q = DNSRecord(q=DNSQuestion(args.domain, getattr(QTYPE, args.qtype)))

    address, _, port = args.server.partition(':')
    port = int(port or 53)

    if args.query:
        print(";; Sending%s:" % (" (TCP)" if args.tcp else ""))
        if args.hex:
            print(";; QUERY:", binascii.hexlify(q.pack()).decode())
        print(q)
        print()

    a_pkt = q.send(address, port, tcp=args.tcp)
    a = DNSRecord.parse(a_pkt)

    if a.header.tc and args.noretry == False:
        # Truncated - retry in TCP mode
        a_pkt = q.send(address, port, tcp=True)
        a = DNSRecord.parse(a_pkt)

    if args.dig or args.diff:
        if args.diff:
            address, _, port = args.diff.partition(':')
            port = int(port or 53)

        if args.dig:
            dig = getoutput("dig +qr -p %d %s %s @%s" %
                            (port, args.domain, args.qtype, address))
            dig_reply = list(iter(DigParser(dig)))
            # DiG might have retried in TCP mode so get last q/a
            q_diff = dig_reply[-2]
            a_diff = dig_reply[-1]
        else:
            q_diff = DNSRecord(header=DNSHeader(id=q.header.id),
                               q=DNSQuestion(args.domain,
                                             getattr(QTYPE, args.qtype)))
            q_diff = q
            diff = q_diff.send(address, port, tcp=args.tcp)
            a_diff = DNSRecord.parse(diff)
            if a_diff.header.tc and args.noretry == False:
                diff = q_diff.send(address, port, tcp=True)
                a_diff = DNSRecord.parse(diff)

    if args.short:
        return a.short()
    else:
        print(";; Got answer:")
        if args.hex:
            print(";; RESPONSE:", binascii.hexlify(a_pkt).decode())
            if args.diff and not args.dig:
                print(";; DIFF    :", binascii.hexlify(diff).decode())
        print(a)
        print()

        if args.dig or args.diff:
            if q != q_diff:
                print(";;; ERROR: Diff Question differs")
                for (d1, d2) in q.diff(q_diff):
                    if d1:
                        print(";; - %s" % d1)
                    if d2:
                        print(";; + %s" % d2)
            if a != a_diff:
                print(";;; ERROR: Diff Response differs")
                for (d1, d2) in a.diff(a_diff):
                    if d1:
                        print(";; - %s" % d1)
                    if d2:
                        print(";; + %s" % d2)

    if args.debug:
        code.interact(local=locals())

    return None
 def get_dns_txt_record(self):
     txt_record = self.token + '.' + self.domain
     q = DNSRecord(q=DNSQuestion(txt_record, getattr(QTYPE, 'TXT')))
     record_pkt = q.send(DNS_VALIDATION_SERVER, 53)
     record = DNSRecord.parse(record_pkt)
     return record
Esempio n. 42
0
                   default=False,
                   help="Short output - rdata only (default: false)")
    p.add_argument("--debug",
                   action='store_true',
                   default=False,
                   help="Drop into CLI after request (default: false)")
    p.add_argument("domain", metavar="<domain>", help="Query domain")
    p.add_argument("qtype",
                   metavar="<type>",
                   default="A",
                   nargs="?",
                   help="Query type (default: A)")
    args = p.parse_args()

    # Construct request
    q = DNSRecord(q=DNSQuestion(args.domain, getattr(QTYPE, args.qtype)))

    address, _, port = args.server.partition(':')
    port = int(port or 53)

    if args.query:
        print(";; Sending%s:" % (" (TCP)" if args.tcp else ""))
        if args.hex:
            print(";; QUERY:", binascii.hexlify(q.pack()).decode())
        print(q)
        print()

    a_pkt = q.send(address, port, tcp=args.tcp)
    a = DNSRecord.parse(a_pkt)

    if a.header.tc and args.noretry == False:
Esempio n. 43
0
File: client.py Progetto: 0rt/XX-Net
    p.add_argument("--diff",default="",
                    help="Compare response from alternate nameserver (format: address:port / default: false)")
    p.add_argument("--dig",action='store_true',default=False,
                    help="Compare result with DiG - if ---diff also specified use alternative nameserver for DiG request (default: false)")
    p.add_argument("--short",action='store_true',default=False,
                    help="Short output - rdata only (default: false)")
    p.add_argument("--debug",action='store_true',default=False,
                    help="Drop into CLI after request (default: false)")
    p.add_argument("domain",metavar="<domain>",
                    help="Query domain")
    p.add_argument("qtype",metavar="<type>",default="A",nargs="?",
                    help="Query type (default: A)")
    args = p.parse_args()

    # Construct request
    q = DNSRecord(q=DNSQuestion(args.domain,getattr(QTYPE,args.qtype)))

    address,_,port = args.server.partition(':')
    port = int(port or 53)

    if args.query:
        print(";; Sending%s:" % (" (TCP)" if args.tcp else ""))
        if args.hex:
            print(";; QUERY:",binascii.hexlify(q.pack()).decode())
        print(q)
        print()

    a_pkt = q.send(address,port,tcp=args.tcp)
    a = DNSRecord.parse(a_pkt)

    if a.header.tc and args.noretry == False:
Esempio n. 44
0
def parse(data):
    record = DNSRecord.parse(data)
    domain = str(record.q.qname).rstrip('.')
    record.q.domain = domain
    return record
Esempio n. 45
0
def check_resp(key, data):
    record = DNSRecord.parse(data)
    if len(record.rr) == 0:
        log.warn('No record returned for "%s".' % key)
    return len(record.rr) != 0
Esempio n. 46
0
 def _resolve_record(self, domain, qtype='A'):
     q = DNSRecord(q=DNSQuestion(domain, getattr(QTYPE, qtype)))
     a_pkt = q.send(self.address, self.port, tcp=False)
     reply = DNSRecord.parse(a_pkt)
     return reply