# DNS Fingerprint ## Announcing FP *The* tool for DNS fingerprinting is [fpdns](https://github.com/kirei/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?). ## 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: `miekg@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; 9. Recursion Available, `ra`; 9. Authenticated Data, `ad`; 9. Checking Disabled, `cd`; 9. Zero, `z`; 9. Question section length, 1 here; 9. Answer section length, 0; 9. Authoritative section length, 0; 9. Additional section length, 0; 9. DNSSEC OK, `DO` (uppercase, thus set); 9. UDP bufsize, set to 4097; 9. NSID, uppercase: request NSID (or NSID was set). If `DO` is not set, the UDP bufsize and NSID aren't used. 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](https://github.com/miekg/godns/tree/master/examples/fp/data/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 need a 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](https://github.com/miekg/godns/tree/master/examples/fp/data), the file `q` holds the fingerprints of the queries to ask. Currently [it](https://github.com/miekg/godns/tree/master/examples/fp/data/q) 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 nameserver 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, this means the reply from the unknown server is an *exact* match with one of the stored fingerprint. 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 # Supplied by on # .,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