📄 sinfp.pl
字号:
#!/usr/bin/perl## $Id: sinfp.pl,v 1.1.2.14.2.27 2006/10/29 20:55:16 gomor Exp $#use strict;use warnings;use FindBin qw($Bin);use lib "$Bin/../lib";use Getopt::Std;my %opts;getopts('d:i:I:p:r:t:f:v46m:M:PF:HOVs:k123aA:C', \%opts);require Net::SinFP;use Net::SinFP::Consts qw(:matchMask);die("\n -- SinFP - $Net::SinFP::VERSION --\n". "\n". " o Information about signature database updates, and more:\n". " o https://lists.sourceforge.net/lists/listinfo/sinfp-discuss\n". "\n". "Usage: $0 -i <targetIp> -p <openTcpPort>\n". "\n". " o Common parameters:\n". " -i <ip> target IP\n". " -p <port> target open TCP port (default: 80)\n". " -d <dev> network device to use\n". " -I <ip> source IP address to use\n". " -3 run all probes (default)\n". " -2 run only probes P1 and P2 (stealthier)\n". " -1 run only probe P2 (even stealthier)\n". " -v be verbose\n". " -s <file> signature file to use\n". " -C print complete information about target operating system\n". " -O print only operating system\n". " -V print only operating system and its version family\n". " -H use HEURISTIC2 masks to match signatures (advanced users)\n". " -A <mask1,mask2,...>\n". " use a custom list of matching masks (advanced users)\n". "\n". " o Online mode specific parameters:\n". " -k keep generated pcap file\n". " -a do not generate an anonymized pcap file trace\n". "\n". " o Offline mode specific parameters:\n". " -f <file> name of pcap file to analyze\n". "\n". " o IPv6 specific parameters:\n". " -6 use IPv6 fingerprinting, instead of IPv4\n". " -M <mac> source MAC address to use\n". " -m <mac> target MAC address to use\n". " -4 if no IPv6 signature matches, try against IPv4 ones\n". "\n". " o Active mode specific parameters:\n". " -r <N> number of tries to perform for a probe (default: 3)\n". " -t <N> timeout before considering a packet to be lost (default: 3)\n". "\n". " o Passive mode specific parameters:\n". " -P passive fingerprinting\n". " -F <filter> pcap filter\n". "") unless (($opts{i} && !$opts{6}) || ($opts{i} && $opts{6} && $opts{m}) || ($opts{f}) || ($opts{P}));$opts{p} = 80 unless $opts{p};if (! $opts{1} && ! $opts{2} && ! $opts{3}) { $opts{3} = 1;}my $dbFile;if ($opts{s}) { $dbFile = $opts{s};}else { for ("$Bin/../db/", "$Bin/") { $dbFile = $_.'sinfp.db'; last if -f $dbFile; }}print "DEBUG: using db: $dbFile\n" if $opts{v};die("Unable to find $dbFile\n") unless -f $dbFile;use Net::Packet::Env qw($Env);require Net::Packet::Target;$Env->updateDevInfo($opts{i}) unless $opts{6};$Env->dev($opts{d}) if $opts{d};$Env->ip ($opts{I}) if $opts{I} && ! $opts{6};$Env->ip6($opts{I}) if $opts{I} && $opts{6};$Env->mac($opts{M}) if $opts{M};$Env->debug(3) if $opts{v};require Net::SinFP::DB;my $db = Net::SinFP::DB->new( db => $dbFile, passiveMode => $opts{P} ? 1 : 0, ipv6 => $opts{6} ? 1 : 0,);$db->loadSignatures;my $sinfp = Net::SinFP->new( db => $db, ipv6 => $opts{6} ? 1 : 0, ipv6UseIpv4 => $opts{4} ? 1 : 0,);$sinfp->passive ($opts{P} ? 1 : 0);$sinfp->verbose ($opts{v} ? 1 : 0);$sinfp->retry ($opts{r} ? $opts{r} : 3);$sinfp->wait ($opts{t} ? $opts{t} : 3);$sinfp->offline ($opts{f} ? 1 : 0);$sinfp->h2Match ($opts{H} ? 1 : 0);$sinfp->keepFile($opts{k} ? 1 : 0);$sinfp->filter ($opts{F}) if $opts{F};$sinfp->file ($opts{f}) if $opts{f};if ($opts{3}) { $sinfp->doP1(1); $sinfp->doP2(1); $sinfp->doP3(1);}elsif ($opts{2}) { $sinfp->doP1(1); $sinfp->doP2(1); $sinfp->doP3(0);}elsif ($opts{1}) { $sinfp->doP1(0); $sinfp->doP2(1); $sinfp->doP3(0);}my $target = Net::Packet::Target->new;$target->ip ($opts{i}) if ! $opts{6};$target->ip6($opts{i}) if $opts{6};$target->mac($opts{m}) if $opts{m};$target->port($opts{p});$sinfp->target($target);$sinfp->passiveMatchCallback(sub { displayPassiveResult($sinfp) });$sinfp->start; # Passive online mode will block here # Passive offline mode will exit here$sinfp->analyzeResponses;$opts{A} ? $sinfp->matchOsfps([ split(',', $opts{A}) ]) : $sinfp->matchOsfps;my $nok = displayWarningAboutClosedPort($sinfp);unless ($nok) { displayResults($sinfp); createAnonymizedPcapFile($sinfp) if (! $opts{a} && ! $opts{f});}$sinfp->clean;$db->close;exit(0);sub noReplyForP1 { my $sinfp = shift; return 1 if ! $sinfp->doP1 || ! $sinfp->pktP1; if (($sinfp->pktP1->reply && $sinfp->pktP1->reply->l4->haveFlagRst) || (! $sinfp->pktP1->reply)) { return 1; } undef;}sub noReplyForP2 { my $sinfp = shift; return 1 if ! $sinfp->doP2 || ! $sinfp->pktP2; if (($sinfp->pktP2->reply && $sinfp->pktP2->reply->l4->haveFlagRst) || (! $sinfp->pktP2->reply)) { return 1; } undef;}sub displayWarningAboutClosedPort { my $sinfp = shift; if (noReplyForP1($sinfp) && noReplyForP2($sinfp)) { print "*** Cannot fingerprint a closed or filtered port\n"; return 1; } undef;}sub _displayResultsOnlyOs { my $sinfp = shift; my $buf; my $ipVersion = $sinfp->getIpVersion; my %os = map { $_->os => '' } $sinfp->resultList; for (keys %os) { $buf .= $ipVersion.': '.$_."\n"; } $buf;}sub _displayResultsOnlyOsAndVersionFamily { my $sinfp = shift; my %os; $os{$_->os}->{$_->osVersionFamily} = '' for $sinfp->resultList; my $buf; for (keys %os) { $buf .= $sinfp->getIpVersion.': '.$_.' '; $buf .= $_.', ' for sort keys %{$os{$_}}; $buf =~ s/, $//; $buf .= "\n"; } $buf;}sub _displayResultsAll { my $sinfp = shift; my $buf; for ($sinfp->resultList) { $buf .= $_->ipVersion; $buf .= '['.$_->idSignature.']' if $opts{v}; $buf .= ': '.$_->matchMask.'/'.$_->matchType. ': '.$_->systemClass. ': '.$_->vendor. ': '.$_->os. ': '.$_->osVersion ; if ($_->osVersionChildrenList) { my $buf2 = ''; $buf2 .= $_.', ' for $_->osVersionChildrenList; $buf2 =~ s/, $//; $buf .= " ($buf2)"; } $buf .= "\n"; } $buf;}sub _displayResultsShort { my $sinfp = shift; my $buf; my %os; for ($sinfp->resultList) { $os{$_->os.':'.$_->osVersion} = $_; } for (sort keys %os) { $buf .= $os{$_}->ipVersion; $buf .= ': '.$os{$_}->matchMask.'/'.$os{$_}->matchType. ': '.$os{$_}->systemClass. ': '.$os{$_}->os. ': '.$os{$_}->osVersion ; $buf .= "\n"; } $buf;}sub displayResults { my $sinfp = shift; my $buf = ''; $buf .= 'P1: '.$sinfp->sigP1AsString."\n" if $sinfp->doP1; $buf .= 'P2: '.$sinfp->sigP2AsString."\n" if $sinfp->doP2; $buf .= 'P3: '.$sinfp->sigP3AsString."\n" if $sinfp->doP3; return print $buf.$sinfp->getIpVersion.": unknown\n" unless $sinfp->found; my $s2 = $sinfp->sigP2; if ($s2 && length($s2->{O}) <= 9) { for ($sinfp->resultList) { if ($_->matchMask ne NS_MATCH_MASK_HEURISTIC0) { print '*** WARNING: not enough TCP options for P2 reply, result '. 'may be false'."\n"; last; } } } if ($opts{O}) { $buf .= _displayResultsOnlyOs($sinfp); } elsif ($opts{V}) { $buf .= _displayResultsOnlyOsAndVersionFamily($sinfp); } elsif ($opts{C}) { $buf .= _displayResultsAll($sinfp); } else { $buf .= _displayResultsShort($sinfp); } print $buf;}sub displayPassiveResult { my $sinfp = shift; my $frame = $sinfp->passiveFrame; print $frame->l3->src.':'.$frame->l4->src.' > '. $frame->l3->dst.':'.$frame->l4->dst; $frame->l4->haveFlagAck ? print " [SYN|ACK]\n" : print " [SYN]\n"; $sinfp->analyzeResponses; $opts{A} ? $sinfp->matchOsfps($opts{A}) : $sinfp->matchOsfps; displayResults($sinfp);}sub createAnonymizedPcapFile { my $sinfp = shift; use Net::Packet::Consts qw(:dump); $Env->noDumpAutoSet(1); require Net::Packet::Dump; my $in = Net::Packet::Dump->new( file => $sinfp->_dump->file, overwrite => 0, mode => NP_DUMP_MODE_OFFLINE, ); $in->start; $in->nextAll; $in->stop; my @new; my $src = ($in->frames)[0]->l3->src; for ($in->frames) { if ($_->l3->src eq $src) { $_->l3->src('127.0.0.1'); $_->l3->dst('127.0.0.2'); $_->l3->checksum(666); $_->l4->checksum(666); } else { $_->l3->src('127.0.0.2'); $_->l3->dst('127.0.0.1'); $_->l3->checksum(666); $_->l4->checksum(666); } $_->noPadding(1); $_->pack; push @new, $_; } my $anon = $sinfp->_dump->file; $anon =~ s/\.pcap$/.anon.pcap/; $anon =~ s/^(sinfp\d\-)\d+\.\d+\.\d+\.\d+\.\d+(\..*)$/${1}127.0.0.1${2}/; my $out = Net::Packet::Dump->new( file => $anon, overwrite => 1, mode => NP_DUMP_MODE_WRITER, ); $out->start; $out->write($_) for @new; $out->stop; print "\n*** File [$anon] generation done.". "\n*** Please send it to sinfp\@gomor.org if you think this is not ". "\n*** the good identification, or if it is a new signature.". "\n*** In this last case, please specify `uname -a' (or equivalent) ". "\n*** from the target host.\n";}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -