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
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]))
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]))
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
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
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)
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
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)
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)
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))]
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)
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)
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
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
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
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)
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)
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
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
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()
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
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
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
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
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
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
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))
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
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
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])
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])
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
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 ] })
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")
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])
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
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
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:
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:
def parse(data): record = DNSRecord.parse(data) domain = str(record.q.qname).rstrip('.') record.q.domain = domain return record
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
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