#!/usr/bin/perl
#
# $Id: Fingerprint.pm,v 1.17 2005/09/05 13:33:36 jakob Exp $
#
# Copyright (c) 2003,2004,2005 Roy Arends & Jakob Schlyter.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. The name of the authors may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
require 5.6.0;
package Net::DNS::Fingerprint;
use strict;
use warnings;
use Net::DNS 0.42;
our $VERSION = "0.9.3";
my %default = (
source => undef,
timeout => 5,
retry => 1,
forcetcp => 0,
debug => 0,
qversion => 0,
qchaos => 0,
);
my $versionlength = 40;
my @qy = ("0,IQUERY,0,0,1,0,0,0,NOERROR,0,0,0,0",
"0,NS_NOTIFY_OP,0,0,0,0,0,0,NOERROR,0,0,0,0",
"0,QUERY,0,0,0,0,0,0,NOERROR,0,0,0,0",
"0,IQUERY,0,0,0,0,1,1,NOERROR,0,0,0,0",
"0,QUERY,0,0,0,0,0,0,NOTIMP,0,0,0,0",
"0,IQUERY,1,0,1,1,1,1,NOERROR,0,0,0,0",
"0,UPDATE,0,0,0,1,0,0,NOERROR,0,0,0,0",
"0,QUERY,1,1,1,1,1,1,NOERROR,0,0,0,0",
"0,QUERY,0,0,0,0,0,1,NOERROR,0,0,0,0",
);
my %initrule = (header => $qy[0], query => ". IN A", );
my @iq = ("1,IQUERY,0,0,1,0,0,0,FORMERR,0,0,0,0", # iq0
"1,IQUERY,0,0,1,0,0,0,FORMERR,1,0,0,0", # iq1
"1,IQUERY,0,0,1,0,0,0,NOTIMP,0,0,0,0", # iq2
"1,IQUERY,0,0,1,0,0,0,NOTIMP,1,0,0,0", # iq3
"1,IQUERY,0,0,1,1,0,0,FORMERR,0,0,0,0", # iq4
"1,IQUERY,0,0,1,1,0,0,NOTIMP,0,0,0,0", # iq5
"1,IQUERY,0,0,1,1,0,0,NOTIMP,1,0,0,0", # iq6
"1,IQUERY,1,0,1,0,0,0,NOTIMP,1,0,0,0", # iq7
"1,QUERY,1,0,1,0,0,0,NOTIMP,1,0,0,0",
"1,QUERY,0,0,0,0,0,0,NOTIMP,0,0,0,0",
"1,IQUERY,0,0,1,1,0,0,FORMERR,1,0,0,0", # iq10
"1,NS_NOTIFY_OP,0,0,0,0,0,0,FORMERR,1,0,0,0",
"1,NS_NOTIFY_OP,0,0,0,0,0,0,NOTIMP,0,0,0,0",
"1,NS_NOTIFY_OP,0,0,0,0,0,0,NOTIMP,1,0,0,0",
"1,NS_NOTIFY_OP,0,0,0,0,0,0,NXDOMAIN,1,0,0,0",
"1,NS_NOTIFY_OP,0,0,0,0,0,0,REFUSED,1,0,0,0",
"1,NS_NOTIFY_OP,0,0,0,0,0,0,SERVFAIL,1,0,0,0",
"1,NS_NOTIFY_OP,0,0,0,1,0,0,FORMERR,1,0,0,0",
"1,NS_NOTIFY_OP,0,0,0,1,0,0,NOTIMP,0,0,0,0",
"1,NS_NOTIFY_OP,0,0,0,1,0,0,NOTIMP,1,0,0,0",
"1,NS_NOTIFY_OP,0,0,0,1,0,0,REFUSED,1,0,0,0", # iq20
"1,NS_NOTIFY_OP,0,0,0,1,0,0,SERVFAIL,1,0,0,0",
"1,NS_NOTIFY_OP,1,0,0,0,0,0,NOTIMP,1,0,0,0",
"1,QUERY,1,0,0,0,0,0,NOTIMP,1,0,0,0",
"1,NS_NOTIFY_OP,1,0,0,0,0,0,SERVFAIL,1,0,0,0",
"1,IQUERY,0,0,0,0,1,1,NOTIMP,0,0,0,0",
"1,IQUERY,0,0,0,0,0,0,NOTIMP,0,0,0,0",
"1,IQUERY,0,0,1,1,1,1,FORMERR,0,0,0,0",
"1,IQUERY,1,0,1,1,1,1,FORMERR,0,0,0,0",
"1,QUERY,.,0,1,.,.,.,NOTIMP,.+,.+,.+,.+",
"1,QUERY,.,0,1,.,.,.,.+,.+,.+,.+,.+", #iq30
"1,QUERY,0,0,.,.,0,0,NXDOMAIN,1,0,0,0",
"1,QUERY,0,0,.,.,0,0,FORMERR,1,0,0,0",
"1,UPDATE,0,0,0,0,0,0,NOTIMP,0,0,0,0",
"1,UPDATE,0,0,0,1,0,0,NOTIMP,0,0,0,0",
"1,QUERY,0,0,1,0,0,0,NOERROR,1,0,0,0",
"1,QUERY,1,1,1,1,1,1,NOTIMP,1,0,0,0",
"1,QUERY,0,0,0,0,0,0,NOERROR,1,0,.+,0",
"1,QUERY,0,0,1,0,0,0,FORMERR,1,0,0,0",
"1,IQUERY,0,0,1,0,1,1,NOTIMP,1,0,0,0",
"1,IQUERY,0,0,0,1,1,1,REFUSED,1,0,0,0", #iq40
"1,UPDATE,0,0,0,1,0,0,REFUSED,1,0,0,0",
"1,IQUERY,0,0,0,1,1,1,FORMERR,0,0,0,0",
"1,IQUERY,0,0,0,1,0,0,NOTIMP,0,0,0,0",
"1,QUERY,1,0,1,0,0,0,FORMERR,1,0,0,0",
"1,UPDATE,0,0,0,0,0,0,FORMERR,1,0,0,0",
"1,UPDATE,0,0,0,0,0,0,FORMERR,0,0,0,0",
"1,QUERY,0,0,1,0,0,0,FORMERR,0,0,0,0",
"1,QUERY,0,0,1,0,0,0,SERVFAIL,1,0,0,0", #iq48
"1,QUERY,1,0,1,0,0,0,NXDOMAIN,1,0,1,0",
"1,QUERY,0,0,1,0,0,0,REFUSED,1,0,0,0", #iq50
"1,QUERY,0,0,1,0,0,0,NOERROR,1,1,0,0",
"1,IQUERY,0,0,1,0,0,0,REFUSED,0,0,0,0",
"1,QUERY,0,0,0,0,0,0,FORMERR,0,0,0,0",
"1,QUERY,0,0,1,1,1,0,NOERROR,1,0,1,0",
"1,QUERY,0,0,1,1,0,0,NOERROR,1,0,1,0",
"1,QUERY,0,0,1,0,1,0,NOERROR,.+,.+,.+,.+",
"1,QUERY,0,0,1,0,0,0,.+,.+,.+,.+,.+",
"1,QUERY,1,0,1,0,0,0,NOERROR,1,1,0,0",
"1,QUERY,0,0,1,1,0,0,SERVFAIL,1,0,0,0",
"1,QUERY,1,0,1,1,0,0,NOERROR,1,1,0,0", #iq60
"1,QUERY,0,0,1,1,0,0,REFUSED,1,0,0,0",
"1,QUERY,0,0,0,0,0,0,NOTIMP,1,0,0,0",
"1,QUERY,1,0,1,1,0,0,NOERROR,1,0,1,0",
"1,IQUERY,0,0,1,1,1,1,NOTIMP,0,0,0,0",
"1,UPDATE,0,0,0,0,0,0,REFUSED,0,0,0,0",
"1,IQUERY,0,0,0,1,1,1,NOTIMP,1,0,0,0",
"1,IQUERY,0,0,0,1,0,0,NOTIMP,1,0,0,0",
"1,QUERY,0,1,1,1,1,1,NOERROR,1,0,.,0",
"1,QUERY,0,1,1,1,0,1,NOERROR,1,0,.,0",
"1,IQUERY,0,0,1,0,0,0,REFUSED,1,0,0,0", #iq70
"1,IQUERY,1,0,1,1,1,1,NOTIMP,1,0,0,0",
"1,IQUERY,0,0,1,0,0,0,NOERROR,1,0,0,0",
"1,QUERY,1,0,1,1,0,0,NOERROR,1,0,0,0",
"1,IQUERY,1,0,1,1,0,0,NXDOMAIN,1,0,0,0",
"1,UPDATE,0,0,0,1,0,0,FORMERR,0,0,0,0",
"1,IQUERY,1,0,1,0,0,0,NXDOMAIN,1,0,0,0",
"1,QUERY,0,0,1,1,0,0,FORMERR,1,0,0,0",
"1,QUERY,0,0,0,1,0,0,SERVFAIL,1,0,0,0",
"1,QUERY,0,0,1,1,0,0,NOERROR,1,1,0,0",
"1,IQUERY,1,0,1,0,0,0,NOERROR,1,0,0,0", #iq80
"1,IQUERY,1,0,1,1,0,0,NOTIMP,1,0,0,0",
"1,QUERY,0,0,1,1,0,0,NOERROR,1,0,0,0",
"1,QUERY,1,0,1,1,0,0,NOERROR,1,1,1,.+",
"1,QUERY,0,0,1,1,0,0,REFUSED,0,0,0,0",
"1,UPDATE,0,0,0,1,0,0,NOTIMP,1,0,0,0",
"1,QUERY,1,0,0,1,0,0,NXDOMAIN,1,0,0,0",
"1,QUERY,0,0,0,1,0,0,NOTIMP,0,0,0,0",
"1,QUERY,0,0,0,0,0,0,REFUSED,1,0,0,0",
"1,QUERY,1,0,1,1,0,0,NXDOMAIN,1,0,0,0",
"1,QUERY,1,0,0,0,0,0,NOERROR,1,1,0,0", #iq90
"1,IQUERY,1,0,1,1,0,1,NOTIMP,1,0,0,0",
"1,QUERY,0,0,0,1,0,0,NOTIMP,1,0,0,0",
"1,QUERY,0,0,1,0,0,1,SERVFAIL,1,0,0,0",
);
my @ruleset = (
{ fingerprint => "query timed out" , header => $qy[0], query => "com. IN A", ruleset => [
{ fingerprint => "query timed out", header => $qy[7], query => ". CH A", ruleset => [
{ fingerprint => "query timed out", header => $qy[6], query => ". IN A", ruleset => [
{ fingerprint => $iq[38], result => { vendor => "Digital Lumber", product => "Oak DNS", version =>"" }, qv => "version.oak",},
{ fingerprint => "query timed out", result => "TIMEOUT",},
{ fingerprint => ".+", state => "q0tq0tq7tq6r?", }, ]
},
{ fingerprint => $iq[35], result => { vendor => "XBILL", product => "jnamed (dnsjava)", version => "" }, },
{ fingerprint => $iq[36], result => { vendor => "menandmice", product => "QuickDNS", version => ""}, },
{ fingerprint => $iq[37], result => { vendor => "unknown", product => "NonSequitur DNS", version => ""}, },
{ fingerprint => ".+", state => "q0tq0tq7r?", }, ]
},
{ fingerprint => $iq[35], result => { vendor => "eNom", product => "eNom DNS", version =>""}, },
{ fingerprint => ".+", state => "q0tq0r?", },]
},
{ fingerprint => $iq[0], header => $qy[1], query=> "jjjjjjjjjjjj IN A", ruleset => [
{ fingerprint => $iq[12], result => { vendor => "ISC", product => "BIND", version => "8.4.1-p1" }, qv => "version.bind",},
{ fingerprint => $iq[13], result => { vendor => "ISC", product => "BIND", version => "8 plus root server modifications"}, qv => "version.bind",},
{ fingerprint => $iq[15], result => { vendor => "Cisco", product => "CNR", version => ""}, },
{ fingerprint => $iq[16], header => $qy[2], query => "hostname.bind CH TXT", ruleset => [
{ fingerprint => $iq[58], result => { vendor => "ISC", product => "BIND", version => "8.3.0-RC1 -- 8.4.4"}, qv => "version.bind",},
{ fingerprint => $iq[50], result => { vendor => "ISC", product => "BIND", version => "8.3.0-RC1 -- 8.4.4"}, qv => "version.bind",},
{ fingerprint => $iq[48], result => { vendor => "ISC", product => "BIND", version => "8.2.2-P3 -- 8.3.0-T2A"}, qv => "version.bind",},
{ fingerprint => ".+", state => "q0r0q1r16q2r?", },]
},
{ fingerprint => ".+", state => "q0r0q1r?", },]
},
{ fingerprint => $iq[1], header => $qy[2], query => ". IN IXFR", ruleset => [
{ fingerprint => $iq[31], result => { vendor => "Microsoft", product => "Windows DNS", version => "2000" }, },
{ fingerprint => $iq[32], result => { vendor => "Microsoft", product => "Windows DNS", version => "NT4" }, },
{ fingerprint => $iq[50], result => { vendor => "Microsoft", product => "Windows DNS", version => "2003"}, },
{ fingerprint => ".+", state => "q0r1q2r?", }, ]
},
{ fingerprint => $iq[2], header => $qy[1], ruleset => [
{ fingerprint => $iq[11], result => { vendor => "ISC", product => "BIND", version => "9.2.3rc1 -- 9.4.0a0" }, qv => "version.bind",},
{ fingerprint => $iq[12], header => $qy[3], ruleset => [
{ fingerprint => $iq[25], header => $qy[6], ruleset => [
{ fingerprint => $iq[33], result => { vendor => "bboy", product => "MyDNS", version => "" },},
{ fingerprint => $iq[34], header => $qy[2], query => "012345678901234567890123456789012345678901234567890123456789012.012345678901234567890123456789012345678901234567890123456789012.012345678901234567890123456789012345678901234567890123456789012.0123456789012345678901234567890123456789012345678901234567890. IN A", ruleset => [
{ fingerprint => $iq[47], result => { vendor => "NLnetLabs", product => "NSD", version => "1.0.3 -- 1.2.1"}, qv => "version.server", },
{ fingerprint => $iq[48], header => $qy[2], query => "hostname.bind CH TXT", ruleset => [
{ fingerprint => $iq[50], result => { vendor => "NLnetLabs", product => "NSD", version => "1.2.2" }, qv => "version.server", },
{ fingerprint => $iq[51], header => $qy[8], query => ". IN A", ruleset => [
{ fingerprint => $iq[93], result => { vendor => "NLnetLabs", product => "NSD", version => "1.2.3 -- 2.1.2" } , qv => "version.server", },
{ fingerprint => $iq[48], result => { vendor => "NLnetLabs", product => "NSD", version => "2.1.3" }, qv => "version.server", },
{ fingerprint => ".+", state => "q0r2q1r12q3r25q6r34q2r48q2r51q8r?", }, ]
},
{ fingerprint => ".+", state => "q0r2q1r12q3r25q6r34q2r48q2r?", }, ]
},
{ fingerprint => $iq[49], header => $qy[2], query => "hostname.bind CH TXT", ruleset => [
{ fingerprint => $iq[50], result => { vendor => "NLnetLabs", product => "NSD", version => "1.2.2 [root]"} , qv => "version.server", },
{ fingerprint => $iq[51], result => { vendor => "NLnetLabs", product => "NSD", version => "1.2.3 [root]"}, qv => "version.server", },
{ fingerprint => ".+", state => "q0r2q1r12q3r25q6r34q2r49q2r?", }, ]
},
{ fingerprint => $iq[53], result => { vendor => "NLnetLabs", product=>"NSD", version => "1.0.2"}, qv => "version.server", },
{ fingerprint => ".+", state => "q0r2q1r12q3r25q6r34q2a?", },]
},
{ fingerprint => ".+", state => "q0r2q1r12q3r25q6r?", },]
},
{ fingerprint => $iq[26], result => { vendor => "VeriSign", product => "ATLAS", version => ""},},
{ fingerprint => ".+", state => "q0r2q1r12q3r?", },]
},
{ fingerprint => $iq[15], header => $qy[6], ruleset => [
{ fingerprint => $iq[45], result => { vendor => "Nominum", product =>"ANS", version =>""}, qv => "version.bind",},
{ fingerprint => $iq[65], result => { vendor => "ISC", product => "BIND", version => "9.2.3rc1 -- 9.4.0a0" }, qv => "version.bind",},
{ fingerprint => $iq[46], header => $qy[7], ruleset => [
{ fingerprint => $iq[56], result => { vendor => "ISC", product => "BIND", version => "9.0.0b5 -- 9.0.1" }, qv => "version.bind",},
{ fingerprint => $iq[57], result => { vendor => "ISC", product => "BIND", version => "9.1.0 -- 9.1.3" }, qv => "version.bind",},
{ fingerprint => ".+", state => "q0r2q1r15q6r46q7r?", }, ]
},
{ fingerprint => ".+", state => "q0r2q1r15q6r?", },]
},
{ fingerprint => $iq[16], header => $qy[4], ruleset => [
{ fingerprint => $iq[29], result => { vendor => "ISC", product => "BIND", version => "9.2.0a1 -- 9.2.0rc3"}, qv => "version.bind",},
{ fingerprint => $iq[30], header => $qy[0], query => ". A CLASS0" , ruleset => [
{ fingerprint => $iq[2], result => { vendor=>"ISC", product => "BIND", version =>"9.2.0rc7 -- 9.2.2-P3"}, qv => "version.bind", },
{ fingerprint => $iq[0], result => { vendor=>"ISC", product => "BIND", version =>"9.2.0rc4 -- 9.2.0rc6"}, qv => "version.bind", },
{ fingerprint => ".+", result => { vendor => "ISC", product => "BIND", version =>"9.2.0rc4 -- 9.2.2-P3"}, qv => "version.bind", }, ]
},
{ fingerprint => ".+", state => "q0r2q1r16q4r?", },]
},
{ fingerprint => ".+", state => "q0r2q1r?", }, ]
},
{ fingerprint => $iq[3], header => $qy[1], ruleset => [
{ fingerprint => "query timed out", header => $qy[5], ruleset => [
{ fingerprint => $iq[3], result => { vendor => "sourceforge", product =>"Dents", version =>""}, qv => "version.bind", },
{ fingerprint => $iq[81], result => { vendor => "Microsoft", product => "Windows DNS", version => "2003" },},
{ fingerprint => $iq[91], result => { vendor => "Microsoft", product => "Windows DNS", version => "2003" },},
{ fingerprint => ".+", state => "q0r3q1tq5r?", }, ]
},
{ fingerprint => $iq[14], result => { vendor => "UltraDNS", product => "", version =>"v2.7.0.2 -- 2.7.3"}, qv => "version.bind", },
{ fingerprint => $iq[13], header => $qy[5], ruleset => [
{ fingerprint => $iq[39], result => { vendor => "pliant", product => "DNS Server", version =>""},},
{ fingerprint => $iq[7], result => { vendor => "JHSOFT", product => "simple DNS plus", version =>""}, },
{ fingerprint => $iq[71], header => $qy[6], ruleset => [
{ fingerprint => $iq[41], result => { vendor =>"Netnumber", product =>"ENUM server", version =>""}, },
{ fingerprint => $iq[85], result => { vendor =>"Raiden", product => "DNSD", version => ""}, }, ]
},
{ fingerprint => ".+", state => "q0r3q1r13q5r?", }, ]
},
{ fingerprint => ".+", state => "q0r3q1r?", }, ]
},
{ fingerprint => $iq[4], header => $qy[1], query=> "jjjjjjjjjjjj IN A", ruleset => [
{ fingerprint => $iq[17], result => { vendor => "ISC", product => "BIND", version =>"9.0.0b5 -- 9.0.1 [rcursion enabled]"},qv => "version.bind", },
{ fingerprint => $iq[18], header => $qy[5], query=> ". IN A" , ruleset => [
{ fingerprint => $iq[27], result => { vendor => "ISC", product => "BIND", version => "4.9.3 -- 4.9.11"}, qv => "version.bind", },
{ fingerprint => $iq[28], result => { vendor => "ISC", product => "BIND", version => "4.8 -- 4.8.3"}, },
{ fingerprint => ".+", state => "q0r4q1r18q5r?", }, ]
},
{ fingerprint => $iq[19], result => {vendor => "ISC", product =>"BIND", version => "8.2.1 [recursion enabled]"}, qv => "version.bind", },
{ fingerprint => $iq[20], header => $qy[3], query=> ". IN A", ruleset => [
{ fingerprint => $iq[42], result => {vendor => "ISC", product =>"BIND", version =>"8.1-REL -- 8.2.1-T4B [recursion enabled]"}, qv => "version.bind", },
{ fingerprint => ".+", state => "q0r4q1r20q3r?", },]
},
{ fingerprint => $iq[21], header => $qy[2], query => "hostname.bind CH TXT", ruleset => [
{ fingerprint => $iq[60], result => {vendor =>"ISC", product => "BIND", version => "8.3.0-RC1 -- 8.4.4 [recursion enabled]"}, qv => "version.bind",},
{ fingerprint => $iq[59], header => $qy[7], query=> ". IN A", ruleset => [
{ fingerprint => $iq[68], result => {vendor =>"ISC", product => "BIND", version => "8.1-REL -- 8.2.1-T4B [recursion enabled]"}, qv => "version.bind", },
{ fingerprint => $iq[69], result => {vendor =>"ISC", product => "BIND", version => "8.2.2-P3 -- 8.3.0-T2A [recursion enabled]"}, qv => "version.bind",},
{ fingerprint => "connection failed", result => { vendor =>"Runtop", product => "dsl/cable", version =>""},},
{ fingerprint => ".+", state => "q0r4q1r21q2r59q7r?", },]
},
{ fingerprint => $iq[58], result => {vendor => "ISC", product =>"BIND", version => "8.3.0-RC1 -- 8.4.4 [recursion local]"}, qv => "version.bind",},
{ fingerprint => $iq[50], result => {vendor => "ISC", product =>"BIND", version => "8.3.0-RC1 -- 8.4.4 [recursion local]"}, qv => "version.bind",},
{ fingerprint => $iq[61], result => {vendor => "ISC", product =>"BIND", version => "8.3.0-RC1 -- 8.4.4 [recursion local]"}, qv => "version.bind",},
{ fingerprint => $iq[48], result => {vendor => "ISC", product =>"BIND", version => "8.2.2-P3 -- 8.3.0-T2A [recursion local]"}, qv => "version.bind",},
{ fingerprint => ".+", state => "q0r4q1r21q2r?", },]
},
{ fingerprint => ".+", state => "q0r4q1r?", }, ]
},
{ fingerprint => $iq[5], header => $qy[1], ruleset => [
{ fingerprint => $iq[11], result => { vendor => "ISC", product => "BIND", version => "9.2.3rc1 -- 9.4.0a0", option => "recursion enabled,split view" }, qv => "version.bind",},
{ fingerprint => $iq[17], result => {vendor => "ISC", product =>"BIND", version => "9.2.3rc1 -- 9.4.0a0 [recursion enabled]"}, qv => "version.bind",},
{ fingerprint => $iq[18], header => $qy[5], ruleset => [
{ fingerprint => $iq[5], header => $qy[7], query => ". IN A", ruleset => [
{ fingerprint => $iq[84], result => {vendor => "Nominum", product =>"CNS", version => ""}, qv => "version.bind",},
{ fingerprint => $iq[59], result => {vendor => "Mikrotik", product =>"dsl/cable", version => ""}, },
{ fingerprint => $iq[82], result => {vendor => "Mikrotik", product =>"dsl/cable", version => ""}, },
{ fingerprint => ".+", state => "q0r5q1r18q5r5q7r?", }, ]
},
{ fingerprint => $iq[64], result => "unknown, smells like old BIND 4", },
{ fingerprint => ".+", state => "q0r5q1r18q5r?", }, ]
},
{ fingerprint => $iq[20], header => $qy[7], ruleset => [
{ fingerprint => $iq[54], result => {vendor => "ISC", product =>"BIND", version => "9.0.0b5 -- 9.0.1 [recursion enabled]"}, qv => "version.bind",},
{ fingerprint => $iq[55], result => {vendor => "ISC", product =>"BIND", version => "9.1.0 -- 9.1.3 [recursion enabled]"}, qv => "version.bind",},
{ fingerprint => $iq[63], result => {vendor => "ISC", product =>"BIND", version => "4.9.3 -- 4.9.11 [recursion enabled]"}, qv => "version.bind",},
{ fingerprint => $iq[61], result => {vendor => "ISC", product =>"BIND", version => "9.0.0b5 -- 9.1.3 [recursion local]"}, qv => "version.bind",},
{ fingerprint => ".+", state => "q0r5q1r20q7r?", }, ]
},
{ fingerprint => $iq[21], header => $qy[4], ruleset => [
{ fingerprint => "query timed out", result => {vendor => "ISC", product =>"BIND", version => "9.2.0a1 -- 9.2.2-P3 [recursion enabled]"}, qv => "version.bind", },
{ fingerprint => $iq[29], result => {vendor => "ISC", product =>"BIND", version => "9.2.0a1 -- 9.2.0rc3 [recursion enabled]"}, qv => "version.bind", },
{ fingerprint => $iq[61], header => $qy[0], query => ". A CLASS0" , ruleset => [
{ fingerprint => $iq[2], result => {vendor => "ISC", product =>"BIND", version => "9.2.0rc7 -- 9.2.2-P3 [recursion local]"}, qv => "version.bind", },
{ fingerprint => $iq[0], result => {vendor => "ISC", product =>"BIND", version => "9.2.0a1 -- 9.2.0rc6 [recursion local]"}, qv => "version.bind", },
{ fingerprint => ".+", result => {vendor => "ISC", product =>"BIND", version => "9.2.0a1 -- 9.2.2-P3 [recursion local]"}, qv => "version.bind", }, ]
},
{ fingerprint => $iq[30], header => $qy[0], query => ". A CLASS0" , ruleset => [
{ fingerprint => $iq[2], result => {vendor => "ISC", product =>"BIND", version => "9.2.0rc7 -- 9.2.2-P3 [recursion enabled]"}, qv => "version.bind", },
{ fingerprint => $iq[0], result => {vendor => "ISC", product =>"BIND", version => "9.2.0rc4 -- 9.2.0rc6 [recursion enabled]"}, qv => "version.bind", },
{ fingerprint => ".+", result => {vendor => "ISC", product =>"BIND", version => "9.2.0rc4 -- 9.2.2-P3 [recursion enabled]"}, qv => "version.bind", }, ]
},
{ fingerprint => ".+", state => "q0r5q1r21q4r?", }, ]
},
{ fingerprint => ".+", state => "q0r5q1r?", }, ]
},
{ fingerprint => $iq[6], header => $qy[1], ruleset => [
{ fingerprint => $iq[15], result => {vendor => "incognito", product =>"DNS commander", version => "v2.3.1.1 -- 4.0.5.1"}, qv => "version.bind", },
{ fingerprint => $iq[19], header => $qy[3], ruleset => [
{ fingerprint => $iq[66], result => {vendor => "vermicelli", product =>"totd", version => ""}, },
{ fingerprint => $iq[67], result => {vendor => "JHSOFT", product =>"simple DNS plus", version => "[recursion enabled]"}, },
{ fingerprint => ".+", state => "q0r6q1r19q3r?", }, ]
},
{ fingerprint => ".+", state => "q0r6q1r?", }, ]
},
{ fingerprint => $iq[7], header => $qy[1], ruleset => [
{ fingerprint => $iq[22], result => {vendor => "PowerDNS", product =>"PowerDNS", version => "2.9.4 -- 2.9.11"}, qv => "version.bind", },
{ fingerprint => $iq[24], result => {vendor => "PowerDNS", product =>"PowerDNS", version => "2.8 -- 2.9.3"}, qv => "version.bind", },
{ fingerprint => ".+", state => "q0r7q1r?", }, ]
},
{ fingerprint => $iq[8], header => $qy[1], ruleset => [
{ fingerprint => $iq[23], header => $qy[2] , query => ". CH A", ruleset => [
{ fingerprint => "query timed out", result => { vendor => "DJ Bernstein", product => "TinyDNS", version => "1.04"} ,},
{ fingerprint => $iq[32], result => {vendor => "DJ Bernstein", product => "TinyDNS", version => "1.05"} ,},
{ fingerprint => ".+", state => "q0r8q1r23q2r?",},]
},
{ fingerprint => ".+", state => "q0r8q1r?", }, ]
},
{ fingerprint => $iq[9], header => $qy[1], ruleset => [
{ fingerprint => $iq[9], result => { vendor => "Sam Trenholme", product =>"MaraDNS", version => ""}, qv => "erre-con-erre-cigarro.maradns.org"},
{ fingerprint => ".+", state => "q0r9q1r?", }, ]
},
{ fingerprint => $iq[10], result => { vendor => "Microsoft", product =>"?", version => ""}, },
{ fingerprint => $iq[26], result => { vendor => "Meilof Veeningen", product =>"Posadis", version =>""}, },
{ fingerprint => $iq[43], header => $qy[6], ruleset => [
{ fingerprint => $iq[34], result => { vendor => "Paul Rombouts", product =>"pdnsd", version =>""}, },
{ fingerprint => $iq[75], result => { vendor => "antirez", product =>"Yaku-NS", version =>""}, },
{ fingerprint => ".+", state => "q0r43q6r?", }, ]
},
{ fingerprint => $iq[44], result => { vendor =>"cpan", product=>"Net::DNS Nameserver", version =>""}, qv => "version.bind", },
{ fingerprint => $iq[52], result => { vendor =>"NLnetLabs", product=>"NSD", version => "1.0 alpha"}, },
{ fingerprint => $iq[55], result => { vendor =>"robtex", product=>"Viking DNS module", version=>""}, },
{ fingerprint => $iq[59], result => { vendor =>"Max Feoktistov", product=>"small HTTP server [recursion enabled]", version =>""}, },
{ fingerprint => $iq[60], result => { vendor =>"Axis", product=>"video server", version =>""}, },
{ fingerprint => $iq[62], header => $qy[7], query => "1.0.0.127.in-addr.arpa. IN PTR", ruleset => [
{ fingerprint => $iq[62], result => { vendor =>"Michael Tokarev", product=>"rbldnsd",version=>""}, qv => "version.bind", },
{ fingerprint => $iq[79], result => { vendor =>"4D", product=>"WebSTAR", version=>""}, },
{ fingerprint => $iq[83], result => { vendor =>"Netopia", product =>"dsl/cable", version => ""},},
{ fingerprint => $iq[90], result => { vendor =>"TZO", product=>"Tzolkin DNS",version=>""}, },
{ fingerprint => "query timed out", result => { vendor =>"Netopia", product =>"dsl/cable", version=>""},},
{ fingerprint => ".+", state => "q0r62q7r?", }, ]
},
{ fingerprint => $iq[70], result => { vendor =>"Yutaka Sato", product=>"DeleGate DNS", version=>""},},
{ fingerprint => $iq[72], result => { vendor =>"", product =>"sheerdns", version=>""}, },
{ fingerprint => $iq[73], result => { vendor =>"Matthew Pratt", product=>"dproxy", version=>""}, },
{ fingerprint => $iq[74], result => { vendor =>"Brad Garcia", product=>"dnrd",version=>""}, },
{ fingerprint => $iq[76], result => { vendor =>"Sourceforge", product=>"JDNSS",version=>""}, },
{ fingerprint => $iq[77], result => { vendor =>"Dan Kaminsky", product=>"nomde DNS tunnel",version=>""}, },
{ fingerprint => $iq[78], result => { vendor =>"Max Feoktistov", product=>"small HTTP server", version =>""}, },
{ fingerprint => $iq[79], result => { vendor =>"robtex", product=>"Viking DNS module", version=>""}, },
{ fingerprint => $iq[80], result => { vendor =>"Fasthosts", product=>"Envisage DNS server", version=>""}, },
{ fingerprint => $iq[81], result => { vendor =>"WinGate", product=>"Wingate DNS", version=>""},},
{ fingerprint => $iq[82], result => { vendor =>"Ascenvision", product=>"SwiftDNS", version=>""},},
{ fingerprint => $iq[86], result => { vendor =>"Nortel Networks", product=>"Instant Internet",version=>""}, },
{ fingerprint => $iq[87], result => { vendor =>"ATOS", product=>"Stargate ADSL", version=>""},},
{ fingerprint => $iq[88], result => { vendor =>"3Com", product=>"Office Connect Remote", version=>""},},
{ fingerprint => $iq[89], result => { vendor =>"Alteon", product=>"ACEswitch", version=>""},},
{ fingerprint => $iq[90], result => { vendor =>"javaprofessionals", product=>"javadns/jdns", version=>""},},
{ fingerprint => $iq[92], result => { vendor =>"Beehive", product=>"CoDoNS",version=>""}, },
{ fingerprint => ".+", state => "q0r?", },
);
######################################################################
sub new
{
my $proto = shift;
my $class = ref($proto) || $proto;
my $self = {};
my %config = @_;
foreach my $k (keys %default) {
if (defined $config{$k}) {
$self->{$k} = $config{$k};
} else {
$self->{$k} = $default{$k};
}
}
bless $self, $class;
return $self;
}
sub hash
{
my $self = shift;
my $addr = shift;
my $port = shift;
$port = 53 unless($port);
return $self->init($addr, $port);
}
sub string
{
my $self = shift;
my $addr = shift;
my $port = shift;
$port = 53 unless($port);
my %r = $self->hash($addr, $port);
my @s = ();
if (defined $r{error}) {
push @s, $r{error};
} elsif (defined $r{result}) {
push @s, $r{result};
} else {
push @s, $r{vendor} if(defined $r{vendor});
push @s, $r{product} if(defined $r{product});
push @s, $r{version} if(defined $r{version});
push @s, "[$r{option}]" if(defined $r{option});
}
push @s, $r{vstring} if(defined $r{vstring});
push @s, "($r{state};$r{id})" if($self->{debug});
return join(" ", @s);
}
sub query_version
{
my $self = shift;
my $qserver = shift;
my $qport = shift;
my $ident = shift;
my $rrset = " id: ";
my $resolver = Net::DNS::Resolver->new;
$resolver->nameservers($qserver);
$resolver->port($qport);
$resolver->srcaddr($self->{source});
$resolver->retry($self->{retry});
$resolver->retrans($self->{timeout});
$resolver->usevc($self->{forcetcp});
my $query = $resolver->query($ident, 'TXT', 'CH');
if ($query && $query->header->ancount > 0) {
foreach my $rr ($query->answer) {
($rrset = $rrset . "\"" . $rr->txtdata . "\" ") if ($rr->type eq "TXT");
}
$rrset =~ s/\n/\" \"/g;
if (length($rrset) > $versionlength) {
$rrset = substr($rrset,0,$versionlength)."..."
}
return $rrset;
}
return " id unavailable (".$resolver->errorstring.")";
}
sub init
{
my $self = shift;
my $qserver = shift;
my $qport = shift;
return $self->process($qserver, $qport,
$initrule{header}, $initrule{query}, \@ruleset);
}
sub process
{
my $self = shift;
my $qserver = shift;
my $qport = shift;
my $qheader = shift;
my $qstring = shift;
my $ruleref = shift;
my $ver;
my $id;
my %ret;
if ($self->{debug}) {
print STDERR "==> PROCESS $qserver:$qport $qheader $qstring\n";
print STDERR "\n";
}
my ($answer, $ress) = $self->probe($qserver, $qport,
$qheader, $qstring);
if ($answer) {
$id = header2fp($answer->header);
} else {
$id = $ress;
}
print STDERR "==> \"$id\"\n" if ($self->{debug});
for my $rule (@$ruleref) {
$ver = " ";
# we must have a fingerprint
die "missing fingerprint" unless (defined $rule->{fingerprint});
# skip to next rule unless we have a matching fingerprint
next unless ($id =~ /$rule->{fingerprint}/);
# return if we have a result
if (defined $rule->{result}) {
if (defined $rule->{qv}) {
$ver = $self->query_version($qserver, $qport,
$rule->{qv}) if $self->{qversion};
}
if ($self->{qchaos}) {
$ver = $self->query_version($qserver, $qport,
"version.bind");
}
$ret{vstring} = $ver if($ver);
if (ref($rule->{result})) {
$ret{vendor} = $rule->{result}{vendor};
$ret{product} = $rule->{result}{product};
$ret{version} = $rule->{result}{version};
$ret{option} = $rule->{result}{option};
} else {
$ret{result} = $rule->{result};
}
return %ret;
}
# print state if no matches
if (defined $rule->{state}) {
$ver = $self->query_version($qserver, $qport,
"hostname.bind") if $self->{qversion};
$ret{vstring} = $ver if($ver);
$ret{error} = "No match found";
$ret{state} = $rule->{state};
$ret{id} = $id;
return %ret;
}
# update query if defined
if (defined $rule->{query}) {
$qstring = $rule->{query};
}
# recurse if we have a new header and a new ruleset
if (defined $rule->{header} && defined $rule->{ruleset}) {
return $self->process($qserver, $qport,
$rule->{header}, $qstring, $rule->{ruleset});
}
die "syntax error";
}
return %ret;
}
sub header2fp
{
my $header = shift;
my @list = ($header->qr,
$header->opcode,
$header->aa,
$header->tc,
$header->rd,
$header->ra,
$header->ad,
$header->cd,
$header->rcode,
$header->qdcount,
$header->ancount,
$header->nscount,
$header->arcount);
return join(",", @list);
}
sub fp2header
{
my @list = split(/,/, shift);
my $header = Net::DNS::Header->new;
$header->qr(shift @list);
$header->opcode(shift @list);
$header->aa(shift @list);
$header->tc(shift @list);
$header->rd(shift @list);
$header->ra(shift @list);
$header->ad(shift @list);
$header->cd(shift @list);
$header->rcode(shift @list);
$header->qdcount(shift @list);
$header->ancount(shift @list);
$header->nscount(shift @list);
$header->arcount(shift @list);
return $header;
}
sub probe
{
my $self = shift;
my $qserver = shift;
my $qport = shift;
my $qheader = shift;
my @qstring = split(/ /, shift);
my $header = fp2header($qheader);
my $packet = Net::DNS::Packet->new(\$header->data);
$packet->push("question", Net::DNS::Question->new(@qstring));
if ($self->{debug}) {
print STDERR "==> QUERY BEGIN\n";
print STDERR $packet->print, "\n";
print STDERR "==> QUERY END\n";
print STDERR "\n";
}
my $resolver = Net::DNS::Resolver->new;
$resolver->nameservers($qserver);
$resolver->port($qport);
$resolver->srcaddr($self->{source});
$resolver->retry($self->{retry});
$resolver->retrans($self->{timeout});
$resolver->usevc($self->{forcetcp});
my $answer = $resolver->send($packet);
if ($answer && $self->{debug}) {
print STDERR "==> ANSWER BEGIN\n";
print STDERR $answer->string, "\n";
print STDERR "==> ANSWER END\n";
print STDERR "\n";
}
return ($answer, $resolver->errorstring);
}
sub version
{
return $VERSION;
}
1;
syntax highlighted by Code2HTML, v. 0.9.1