예제 #1
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]))
예제 #2
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
예제 #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]))
예제 #4
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
예제 #5
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)
예제 #6
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)
예제 #7
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)
예제 #8
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)
예제 #9
0
    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:
예제 #10
0
파일: client.py 프로젝트: Liljhon241/MITMf
                   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: