DNS Fingerprinting

January 28, 2012

programming

Announcing FP

The tool for DNS fingerprinting is fpdns, which is Perl based. In recent times development seems to have picked up, but a little competition never hurt anyone, so I wrote fp in Go. Fp is also a fingerprint program for DNS servers. Its aim is to be more readable then fpdns is (was?). And make it more easy to add new server types.

Help needed!

Do you have some old(er) nameserver laying around that can be queried? Does your (sick) mind know of a few extra evil queries that can be sent to nameservers? If so, please contact me: query@evilquery.nl. I want to get to a point where fp sends about 10 queries that can be used to identify a server.

Fingerprint

A fingerprint in fp looks like this:

.,CH,TXT,QUERY,NOERROR,qr,aa,tc,RD,ra,ad,cd,z,1,0,0,0,DO,4097,NSID

It has 20 fields, which are:

  1. Domain name, . in this example;
  2. Class, CH here;
  3. Type, TXT here;
  4. Opcode, QUERY;
  5. Rcode, NOERROR;
  6. Query response, qr, lowercase means false (not set), uppercase means true;
  7. Authoritative, aa, lowercase. Thus not set here;
  8. Truncated, tc, not set;
  9. Recursion Desired, RD, uppercase, thus set;
  10. Recursion Available, ra;
  11. Authenticated Data, ad;
  12. Checking Disabled, cd;
  13. Zero, z;
  14. Question section length, 1 here;
  15. Answer section length, 0;
  16. Authoritative section length, 0;
  17. Additional section length, 0;
  18. DNSSEC OK, DO (uppercase, thus set);
  19. UDP bufsize, set to 4097;
  20. NSID, uppercase: request NSID (or NSID was set).

These fingerprints are also used in creating the DNS queries that are send to nameserver(s) being tested.

A full nameserver fingerprint consists out of multiple of these fingerprints. Right now fp fires off 3 queries to test a server, so each nameserver fingerprint must also consist out of 3 fingerprints. The nameserver fingerprint of BIND9 looks like:

# BIND9 fingerprints
.,CH,TXT,QUERY,REFUSED,QR,aa,tc,RD,ra,ad,cd,z,1,0,0,1,DO,4096,NSID
auThoRs.bInD.,CH,TXT,QUERY,NOERROR,QR,AA,tc,rd,ra,ad,cd,z,1,15,1,0,do,0,nsid
bind.,NONE,SOA,NOTIFY,REFUSED,QR,aa,tc,RD,ra,ad,cd,z,1,0,0,0,do,0,nsid

When fp is extended with an extra fingerprint, this BIND9 fingerprint also needs to get an extra fingerprint.

Trying it yourself

As said, Currently fp only uses three queries, but this is expected to be increased in the near future. In the data directory, the file q holds the fingerprints of the queries to ask. Currently it looks like this:

# These are the queries that we ask the nameserver being identified
#
# The order is important, as the data files of the known nameservers are compared
# in this order.
.,CH,TXT,QUERY,NOERROR,qr,aa,tc,RD,ra,ad,cd,z,1,0,0,0,DO,4097,NSID
auThoRs.bInD.,CH,TXT,QUERY,NOERROR,qr,aa,tc,rd,ra,ad,cd,z,1,0,0,0,do,0,nsid
bind.,NONE,SOA,NOTIFY,NOERROR,qr,AA,tc,RD,ra,ad,cd,Z,1,0,0,0,do,0,nsid

A local run looks like this (this is abbreviated):

% ./fp @localhost
Server type     Diffs       Fingerprint         Recevied
Bind9   0 .,CH,TXT,QUERY,REFUSED,QR,aa,tc,RD,ra,ad,cd,z,1,0,0,1,DO,4096,NSID .,CH,TXT,QUERY,REFUSED,QR,aa,tc,RD,ra,ad,cd,z,1,0,0,1,DO,4096,NSID
Bind9   0 auThoRs.bInD.,CH,TXT,QUERY,NOERROR,QR,AA,tc,rd,ra,ad,cd,z,1,15,1,0,do,0,nsid auThoRs.bInD.,CH,TXT,QUERY,NOERROR,QR,AA,tc,rd,ra,ad,cd,z,1,15,1,0,do,0,nsid
Bind9   0 bind.,NONE,SOA,NOTIFY,REFUSED,QR,aa,tc,RD,ra,ad,cd,z,1,0,0,0,do,0,nsid bind.,NONE,SOA,NOTIFY,REFUSED,QR,aa,tc,RD,ra,ad,cd,z,1,0,0,0,do,0,nsid
        =
Differences:    0

Nsd3    2 .,CH,TXT,QUERY,NOERROR,QR,aa,tc,RD,ra,ad,cd,z,1,0,0,1,DO,4096,nsid .,CH,TXT,QUERY,REFUSED,QR,aa,tc,RD,ra,ad,cd,z,1,0,0,1,DO,4096,NSID
Nsd3    3 auThoRs.bInD.,CH,TXT,QUERY,NOERROR,QR,aa,tc,rd,ra,ad,cd,z,1,0,0,0,do,0,nsid auThoRs.bInD.,CH,TXT,QUERY,NOERROR,QR,AA,tc,rd,ra,ad,cd,z,1,15,1,0,do,0,nsid
Nsd3    6 .,CLASS0,TYPE0,NOTIFY,NXDOMAIN,QR,AA,tc,RD,ra,ad,cd,z,0,0,0,0,do,0,nsid bind.,NONE,SOA,NOTIFY,REFUSED,QR,aa,tc,RD,ra,ad,cd,z,1,0,0,0,do,0,nsid
            =
Differences:    11

What do you see here? On the left the nameserver type we’re testing, then a number. This number represent the number of differences with the stored fingerprint for this server. When this number is zero, it means the reply from the unknown server is an exact match with one of the stored fingerprints. In general, the lower the number, the more exact the hit was. For bind9 in the example above, the accumulated number of differences is zero. This indicates the server is probably a BIND9 server.

For nsd3 the story is completely different. The accumulated number of differences is 11, so this server probably isn’t a NSD3 server.

Report

With, -report fp will just show the fingerprint of a nameserver. If the server is positively identified, the finger print can be added to fp:

% ./fp -report @localhost
# Fingerprint of <Nameserver> <version>
# Supplied by <Name> on <Date>
#
.,CH,TXT,QUERY,REFUSED,QR,aa,tc,RD,ra,ad,cd,z,1,0,0,1,DO,4096,NSID
auThoRs.bInD.,CH,TXT,QUERY,NOERROR,QR,AA,tc,rd,ra,ad,cd,z,1,15,1,0,do,0,nsid
bind.,NONE,SOA,NOTIFY,REFUSED,QR,aa,tc,RD,ra,ad,cd,z,1,0,0,0,do,0,nsid
Golang