Exemple #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
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
Exemple #3
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)
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
Exemple #5
0
    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: