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 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 _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 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 _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 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
# 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)))
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
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
def do_query(self, payload) -> bytes: q = DNSRecord.parse(payload) return q.send(self.resolver(), 53)
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 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
from dnslib.dns import DNSRecord, DNSQuestion, QTYPE import socket from binascii import unhexlify q = DNSRecord( q=DNSQuestion('check.infinite.thecatch.cz', getattr(QTYPE, 'SOA'))) soa = DNSRecord.parse(q.send('8.8.8.8', 53)) print soa.auth[0] dnsserver = str(soa.auth[0].rdata.mname) q = DNSRecord(q=DNSQuestion(dnsserver, getattr(QTYPE, 'A'))) a = DNSRecord.parse(q.send('8.8.8.8', 53)) print a.rr[0] dnsserver_ip = str(a.rr[0].rdata) done = [] code = '' nsl = 'dustoff.infinite.thecatch.cz' while True: q = DNSRecord(q=DNSQuestion(nsl, getattr(QTYPE, 'NS'))) try: a = DNSRecord.parse(q.send(dnsserver_ip, 53, timeout=0.5, tcp=False)) except socket.timeout: continue nsl = str(a.auth[0].rdata) if nsl in done: break done.append(nsl) if nsl.endswith('.'): nsl = nsl[:-1]
def parse(data): record = DNSRecord.parse(data) domain = str(record.q.qname).rstrip('.') record.q.domain = domain return record
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
def sendmsg(m_type, message=""): global MSGerror message = str(message) if len(message) == 0: message = "PING" logging.debug("sendmsg enter") port = 53 timeout = 10 i = 0 part = "" c_msg = "" protohdr = "" dnsresponse = "" # dns params max size definition s_request = 255 # max size of the domain s_section = 127 # max size of the message s_dns_section = 63 # max size of the dns section s_protohdr = 50 # protocol max size headers - hostid + msg m_type + msgid GConfig['msgid'] = GConfig['msgid'] + 1 if m_type == "RG": protohdr = str(GConfig['hostid']) + ";" + str(m_type) + ";" + str(GConfig['msgid']) logging.debug("protohdr: % s " % protohdr) c_protohdr = base64.b64encode(protohdr) logging.debug("base64 protohrd: %s " % c_protohdr) c_msg = base64.b64encode(message) logging.debug("base64 RG message: %s" % c_msg) dnsreq = c_protohdr for i_msg in range(0, (len(c_msg) / s_dns_section) + 1): dnsreq = dnsreq + "." + c_msg[i_msg * (s_dns_section):i_msg * (s_dns_section) + (s_dns_section)] dnsreq = dnsreq + "." + GConfig['domain'] logging.debug("dns req: %s " % dnsreq) # Construct request q = DNSRecord(q=DNSQuestion(dnsreq, getattr(QTYPE, "TXT"))) try: a_pkt = q.send(GConfig['dnsserver'], port, False, timeout) a = DNSRecord.parse(a_pkt).get_a() response = decryptmsg(string.split(str(a))[4]) except: logging.debug("Registration failed!") return(0) logging.debug("response %s" % response) if response == "OK": logging.debug("Registration success!") return(1) else: logging.debug("Registration failed!") return(0) else: if s_request < s_section + s_protohdr + 10 + len(GConfig['domain']): logging.critical("ERROR: domain too long" + str(s_section + s_protohdr + 10 + len(GConfig['domain']))) exit(1) # chunk msq to s_section character pieces msgcount = (len(message) / s_section) + 1 # encrypt every piece of message with protocol header logging.debug("MSGcount: " + str(msgcount)) # proto header for i in range(0, msgcount): time.sleep(GConfig['beacontime']) protohdr = str(GConfig['hostid']) + ";" + str(m_type) + ";" + str(GConfig['msgid']) logging.debug("protohdr: % s " % protohdr) c_protohdr = base64.b64encode(protohdr) logging.debug("base64 protohrd: %s " % c_protohdr) part = (message[i * (s_section):i * (s_section) + (s_section)]) logging.debug("send message: %s " % part) c_msg = cryptmsg(part) logging.debug("enc message: %s" % c_msg) dnsreq = c_protohdr for i_msg in range(0, (len(c_msg) / s_dns_section) + 1): dnsreq = dnsreq + "." + c_msg[i_msg * (s_dns_section):i_msg * (s_dns_section) + (s_dns_section)] dnsreq = dnsreq + "." + GConfig['domain'] logging.debug("dns req: %s " % dnsreq) # Construct request q = DNSRecord(q=DNSQuestion(dnsreq, getattr(QTYPE, "TXT"))) try: a_pkt = q.send(GConfig['dnsserver'], port, False, timeout) a = DNSRecord.parse(a_pkt).get_a() response = decryptmsg(string.split(str(a))[4]) except: logging.debug("Sending request failed!") # pocitani chyb, pak zavolat znovy registraci MSGerror = MSGerror + 1 logging.debug("MSGerror %i" % MSGerror) if MSGerror > GConfig['retry_error']: logging.debug("New registration enforce due to retry error count") MSGerror = 0 registerAgent() return(0) GConfig['msgid'] = GConfig['msgid'] + 1 logging.debug("response %s" % response) logging.debug("sendmsg finish") return response
if args.dnssec: q.add_ar(EDNS0(flags="do",udp_len=4096)) q.header.ad = 1 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: if getstatusoutput("dig -v")[0] != 0: p.error("DiG not found") if args.dnssec: