| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
# |
|
2
|
|
|
|
|
|
|
# $Id$ |
|
3
|
|
|
|
|
|
|
# |
|
4
|
|
|
|
|
|
|
# network::sinfp3 Brik |
|
5
|
|
|
|
|
|
|
# |
|
6
|
|
|
|
|
|
|
package Metabrik::Network::Sinfp3; |
|
7
|
1
|
|
|
1
|
|
749
|
use strict; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
29
|
|
|
8
|
1
|
|
|
1
|
|
4
|
use warnings; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
27
|
|
|
9
|
|
|
|
|
|
|
|
|
10
|
1
|
|
|
1
|
|
6
|
use base qw(Metabrik); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
3707
|
|
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
sub brik_properties { |
|
13
|
|
|
|
|
|
|
return { |
|
14
|
0
|
|
|
0
|
1
|
|
revision => '$Revision$', |
|
15
|
|
|
|
|
|
|
tags => [ qw(unstable sinfp osfp fingerprint fingerprinting) ], |
|
16
|
|
|
|
|
|
|
author => 'GomoR ', |
|
17
|
|
|
|
|
|
|
license => 'http://opensource.org/licenses/BSD-3-Clause', |
|
18
|
|
|
|
|
|
|
attributes => { |
|
19
|
|
|
|
|
|
|
datadir => [ qw(datadir) ], |
|
20
|
|
|
|
|
|
|
db => [ qw(sinfp3_db) ], |
|
21
|
|
|
|
|
|
|
target => [ qw(target_host) ], |
|
22
|
|
|
|
|
|
|
port => [ qw(tcp_port) ], |
|
23
|
|
|
|
|
|
|
device => [ qw(device) ], |
|
24
|
|
|
|
|
|
|
threshold => [ qw(percent) ], |
|
25
|
|
|
|
|
|
|
best_score_only => [ qw(0|1) ], |
|
26
|
|
|
|
|
|
|
_global => [ qw(INTERNAL) ], |
|
27
|
|
|
|
|
|
|
_update_url => [ qw(INTERNAL) ], |
|
28
|
|
|
|
|
|
|
}, |
|
29
|
|
|
|
|
|
|
attributes_default => { |
|
30
|
|
|
|
|
|
|
port => 80, |
|
31
|
|
|
|
|
|
|
db => 'sinfp3.db', |
|
32
|
|
|
|
|
|
|
threshold => 80, |
|
33
|
|
|
|
|
|
|
best_score_only => 0, |
|
34
|
|
|
|
|
|
|
_update_url => 'https://www.metabrik.org/wp-content/files/sinfp/sinfp3-latest.db', |
|
35
|
|
|
|
|
|
|
}, |
|
36
|
|
|
|
|
|
|
commands => { |
|
37
|
|
|
|
|
|
|
update => [ ], |
|
38
|
|
|
|
|
|
|
active_ipv4 => [ qw(target_host|OPTIONAL target_port|OPTIONAL) ], |
|
39
|
|
|
|
|
|
|
active_ipv6 => [ qw(target_host|OPTIONAL target_port|OPTIONAL) ], |
|
40
|
|
|
|
|
|
|
export_active_db => [ qw(sinfp3_db|OPTIONAL) ], |
|
41
|
|
|
|
|
|
|
save_active_ipv4_fingerprint => [ qw(target_host|OPTIONAL target_port|OPTIONAL) ], |
|
42
|
|
|
|
|
|
|
save_active_ipv6_fingerprint => [ qw(target_host|OPTIONAL target_port|OPTIONAL) ], |
|
43
|
|
|
|
|
|
|
active_ipv4_from_pcap => [ qw(pcap_file) ], |
|
44
|
|
|
|
|
|
|
active_ipv6_from_pcap => [ qw(pcap_file) ], |
|
45
|
|
|
|
|
|
|
to_signature_from_tcp_options => [ qw(options) ], |
|
46
|
|
|
|
|
|
|
to_signature_from_tcp_window_and_options => [ qw(window options) ], |
|
47
|
|
|
|
|
|
|
active_ipv4_from_tcp_window_and_options => [ qw(window options) ], |
|
48
|
|
|
|
|
|
|
active_ipv4_from_tcp_options => [ qw(options) ], |
|
49
|
|
|
|
|
|
|
active_ipv4_from_signature => [ qw(signature) ], |
|
50
|
|
|
|
|
|
|
get_os_list_from_result => [ qw(result) ], |
|
51
|
|
|
|
|
|
|
}, |
|
52
|
|
|
|
|
|
|
require_modules => { |
|
53
|
|
|
|
|
|
|
'File::Copy' => [ qw(move) ], |
|
54
|
|
|
|
|
|
|
'Net::SinFP3' => [ ], |
|
55
|
|
|
|
|
|
|
'Net::SinFP3::Ext::S' => [ ], |
|
56
|
|
|
|
|
|
|
'Net::SinFP3::Log::Console' => [ ], |
|
57
|
|
|
|
|
|
|
'Net::SinFP3::Log::Null' => [ ], |
|
58
|
|
|
|
|
|
|
'Net::SinFP3::Global' => [ ], |
|
59
|
|
|
|
|
|
|
'Net::SinFP3::Input::IpPort' => [ ], |
|
60
|
|
|
|
|
|
|
'Net::SinFP3::Input::Pcap' => [ ], |
|
61
|
|
|
|
|
|
|
'Net::SinFP3::Input::Signature' => [ ], |
|
62
|
|
|
|
|
|
|
'Net::SinFP3::DB::SinFP3' => [ ], |
|
63
|
|
|
|
|
|
|
'Net::SinFP3::Mode::Active' => [ ], |
|
64
|
|
|
|
|
|
|
'Net::SinFP3::Search::Active' => [ ], |
|
65
|
|
|
|
|
|
|
'Net::SinFP3::Search::Null' => [ ], |
|
66
|
|
|
|
|
|
|
'Net::SinFP3::Output::Console' => [ ], |
|
67
|
|
|
|
|
|
|
'Net::SinFP3::Output::Pcap' => [ ], |
|
68
|
|
|
|
|
|
|
'Net::SinFP3::Output::Simple' => [ ], |
|
69
|
|
|
|
|
|
|
'Metabrik::Client::Www' => [ ], |
|
70
|
|
|
|
|
|
|
}, |
|
71
|
|
|
|
|
|
|
}; |
|
72
|
|
|
|
|
|
|
} |
|
73
|
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
sub brik_use_properties { |
|
75
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
|
76
|
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
return { |
|
78
|
0
|
|
0
|
|
|
|
attributes_default => { |
|
79
|
|
|
|
|
|
|
device => defined($self->global) && $self->global->device || 'eth0', |
|
80
|
|
|
|
|
|
|
}, |
|
81
|
|
|
|
|
|
|
}; |
|
82
|
|
|
|
|
|
|
} |
|
83
|
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
sub brik_init { |
|
85
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
|
86
|
|
|
|
|
|
|
|
|
87
|
0
|
|
|
|
|
|
my $datadir = $self->datadir; |
|
88
|
0
|
|
|
|
|
|
my $file = $datadir.'/'.$self->db; |
|
89
|
0
|
|
|
|
|
|
my $threshold = $self->threshold; |
|
90
|
0
|
|
|
|
|
|
my $best_score_only = $self->best_score_only; |
|
91
|
|
|
|
|
|
|
|
|
92
|
0
|
0
|
|
|
|
|
if (! -f $file) { |
|
93
|
0
|
0
|
|
|
|
|
$self->update or return; |
|
94
|
|
|
|
|
|
|
} |
|
95
|
|
|
|
|
|
|
|
|
96
|
0
|
0
|
|
|
|
|
my $log = Net::SinFP3::Log::Null->new( |
|
97
|
|
|
|
|
|
|
level => $self->log->level, |
|
98
|
|
|
|
|
|
|
) or return $self->log->error('brik_init: log::null failed'); |
|
99
|
0
|
|
|
|
|
|
$log->init; |
|
100
|
|
|
|
|
|
|
|
|
101
|
0
|
0
|
|
|
|
|
my $global = Net::SinFP3::Global->new( |
|
102
|
|
|
|
|
|
|
log => $log, |
|
103
|
|
|
|
|
|
|
ipv6 => 0, |
|
104
|
|
|
|
|
|
|
dnsReverse => 0, |
|
105
|
|
|
|
|
|
|
threshold => $threshold, |
|
106
|
|
|
|
|
|
|
bestScore => $best_score_only, |
|
107
|
|
|
|
|
|
|
) or return $self->log->error('brik_init: global failed'); |
|
108
|
|
|
|
|
|
|
|
|
109
|
0
|
0
|
|
|
|
|
my $db = Net::SinFP3::DB::SinFP3->new( |
|
110
|
|
|
|
|
|
|
global => $global, |
|
111
|
|
|
|
|
|
|
file => $file, |
|
112
|
|
|
|
|
|
|
) or return $self->log->error('brik_init: db::sinfp3 failed'); |
|
113
|
0
|
|
|
|
|
|
$db->init; |
|
114
|
0
|
|
|
|
|
|
$global->db($db); |
|
115
|
|
|
|
|
|
|
|
|
116
|
0
|
|
|
|
|
|
$self->_global($global); |
|
117
|
|
|
|
|
|
|
|
|
118
|
0
|
|
|
|
|
|
return $self->SUPER::brik_init(@_); |
|
119
|
|
|
|
|
|
|
} |
|
120
|
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
sub update { |
|
122
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
123
|
|
|
|
|
|
|
|
|
124
|
0
|
|
|
|
|
|
my $db = $self->db; |
|
125
|
0
|
|
|
|
|
|
my $datadir = $self->datadir; |
|
126
|
|
|
|
|
|
|
|
|
127
|
0
|
|
|
|
|
|
my $url = $self->_update_url; |
|
128
|
|
|
|
|
|
|
|
|
129
|
0
|
0
|
|
|
|
|
my $cw = Metabrik::Client::Www->new_from_brik_init($self) or return; |
|
130
|
0
|
0
|
|
|
|
|
my $files = $cw->mirror($url, $db, $datadir) or return; |
|
131
|
0
|
0
|
|
|
|
|
if (@$files > 0) { |
|
132
|
0
|
|
|
|
|
|
$self->log->info("update: $db updated"); |
|
133
|
|
|
|
|
|
|
} |
|
134
|
|
|
|
|
|
|
|
|
135
|
0
|
|
|
|
|
|
return "$datadir/$db"; |
|
136
|
|
|
|
|
|
|
} |
|
137
|
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
sub active_ipv4 { |
|
139
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
140
|
0
|
|
|
|
|
|
my ($target, $port) = @_; |
|
141
|
|
|
|
|
|
|
|
|
142
|
0
|
|
0
|
|
|
|
$target ||= $self->target; |
|
143
|
0
|
|
0
|
|
|
|
$port ||= $self->port; |
|
144
|
0
|
0
|
|
|
|
|
$self->brik_help_run_must_be_root('active_ipv4') or return; |
|
145
|
0
|
0
|
|
|
|
|
$self->brik_help_run_undef_arg('active_ipv4', $target) or return; |
|
146
|
0
|
0
|
|
|
|
|
$self->brik_help_run_undef_arg('active_ipv4', $port) or return; |
|
147
|
|
|
|
|
|
|
|
|
148
|
0
|
|
|
|
|
|
my $device = $self->device; |
|
149
|
0
|
|
|
|
|
|
my $threshold = $self->threshold; |
|
150
|
|
|
|
|
|
|
|
|
151
|
0
|
|
|
|
|
|
my $datadir = $self->datadir; |
|
152
|
0
|
|
|
|
|
|
my $file = $datadir.'/'.$self->db; |
|
153
|
0
|
0
|
|
|
|
|
$self->brik_help_run_file_not_found('active_ipv4', $file) or return; |
|
154
|
|
|
|
|
|
|
|
|
155
|
0
|
|
|
|
|
|
my $log = Net::SinFP3::Log::Console->new( |
|
156
|
|
|
|
|
|
|
level => $self->log->level, |
|
157
|
|
|
|
|
|
|
); |
|
158
|
|
|
|
|
|
|
|
|
159
|
0
|
0
|
|
|
|
|
my $global = Net::SinFP3::Global->new( |
|
160
|
|
|
|
|
|
|
log => $log, |
|
161
|
|
|
|
|
|
|
target => $target, |
|
162
|
|
|
|
|
|
|
port => $port, |
|
163
|
|
|
|
|
|
|
ipv6 => 0, |
|
164
|
|
|
|
|
|
|
dnsReverse => 0, |
|
165
|
|
|
|
|
|
|
worker => 'single', |
|
166
|
|
|
|
|
|
|
device => $device, |
|
167
|
|
|
|
|
|
|
threshold => $threshold, |
|
168
|
|
|
|
|
|
|
) or return $self->log->error("active: global failed"); |
|
169
|
|
|
|
|
|
|
|
|
170
|
0
|
|
|
|
|
|
my $input = Net::SinFP3::Input::IpPort->new( |
|
171
|
|
|
|
|
|
|
global => $global, |
|
172
|
|
|
|
|
|
|
); |
|
173
|
|
|
|
|
|
|
|
|
174
|
0
|
|
|
|
|
|
my $db = Net::SinFP3::DB::SinFP3->new( |
|
175
|
|
|
|
|
|
|
global => $global, |
|
176
|
|
|
|
|
|
|
file => $file, |
|
177
|
|
|
|
|
|
|
); |
|
178
|
|
|
|
|
|
|
|
|
179
|
0
|
|
|
|
|
|
my $mode = Net::SinFP3::Mode::Active->new( |
|
180
|
|
|
|
|
|
|
global => $global, |
|
181
|
|
|
|
|
|
|
doP1 => 1, |
|
182
|
|
|
|
|
|
|
doP2 => 1, |
|
183
|
|
|
|
|
|
|
doP3 => 1, |
|
184
|
|
|
|
|
|
|
); |
|
185
|
|
|
|
|
|
|
|
|
186
|
0
|
|
|
|
|
|
my $search = Net::SinFP3::Search::Active->new( |
|
187
|
|
|
|
|
|
|
global => $global, |
|
188
|
|
|
|
|
|
|
); |
|
189
|
|
|
|
|
|
|
|
|
190
|
0
|
|
|
|
|
|
my $output = Net::SinFP3::Output::Simple->new( |
|
191
|
|
|
|
|
|
|
global => $global, |
|
192
|
|
|
|
|
|
|
); |
|
193
|
|
|
|
|
|
|
|
|
194
|
0
|
|
|
|
|
|
my $sinfp3 = Net::SinFP3->new( |
|
195
|
|
|
|
|
|
|
global => $global, |
|
196
|
|
|
|
|
|
|
input => [ $input ], |
|
197
|
|
|
|
|
|
|
db => [ $db ], |
|
198
|
|
|
|
|
|
|
mode => [ $mode ], |
|
199
|
|
|
|
|
|
|
search => [ $search ], |
|
200
|
|
|
|
|
|
|
output => [ $output ], |
|
201
|
|
|
|
|
|
|
); |
|
202
|
|
|
|
|
|
|
|
|
203
|
0
|
|
|
|
|
|
my $ret = $sinfp3->run; |
|
204
|
|
|
|
|
|
|
|
|
205
|
0
|
|
|
|
|
|
my @result = $global->result; |
|
206
|
|
|
|
|
|
|
|
|
207
|
0
|
|
|
|
|
|
$db->post; |
|
208
|
0
|
|
|
|
|
|
$log->post; |
|
209
|
|
|
|
|
|
|
|
|
210
|
0
|
|
|
|
|
|
return \@result; |
|
211
|
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
# I was quite mad at this time. |
|
213
|
|
|
|
|
|
|
#$global->mode($mode); |
|
214
|
|
|
|
|
|
|
#$mode->init; |
|
215
|
|
|
|
|
|
|
#$mode->run; |
|
216
|
|
|
|
|
|
|
#$db->init; |
|
217
|
|
|
|
|
|
|
#$db->run; |
|
218
|
|
|
|
|
|
|
#$global->db($db); |
|
219
|
|
|
|
|
|
|
#$global->search($search); |
|
220
|
|
|
|
|
|
|
#$search->init; |
|
221
|
|
|
|
|
|
|
#my $result = $search->run; |
|
222
|
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
#return $result; |
|
224
|
|
|
|
|
|
|
} |
|
225
|
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
sub export_active_db { |
|
227
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
228
|
0
|
|
|
|
|
|
my ($db) = @_; |
|
229
|
|
|
|
|
|
|
|
|
230
|
0
|
|
0
|
|
|
|
$db ||= $self->db; |
|
231
|
0
|
0
|
|
|
|
|
$self->brik_help_run_undef_arg('export_active_db', $db) or return; |
|
232
|
0
|
0
|
|
|
|
|
$self->brik_help_run_file_not_found('export_active_db', $db) or return; |
|
233
|
|
|
|
|
|
|
|
|
234
|
0
|
|
|
|
|
|
return 1; |
|
235
|
|
|
|
|
|
|
} |
|
236
|
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
sub save_active_ipv4_fingerprint { |
|
238
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
239
|
0
|
|
|
|
|
|
my ($target_host, $target_port) = @_; |
|
240
|
|
|
|
|
|
|
|
|
241
|
0
|
|
0
|
|
|
|
$target_host ||= $self->target; |
|
242
|
0
|
|
0
|
|
|
|
$target_port ||= $self->port; |
|
243
|
0
|
|
|
|
|
|
my $device = $self->device; |
|
244
|
0
|
0
|
|
|
|
|
$self->brik_help_run_undef_arg('save_active_ipv4_fingerprint', $target_host) or return; |
|
245
|
0
|
0
|
|
|
|
|
$self->brik_help_run_undef_arg('save_active_ipv4_fingerprint', $target_port) or return; |
|
246
|
|
|
|
|
|
|
|
|
247
|
0
|
|
|
|
|
|
my $datadir = $self->datadir; |
|
248
|
0
|
|
|
|
|
|
my $file = $datadir.'/'.$self->db; |
|
249
|
0
|
0
|
|
|
|
|
$self->brik_help_run_file_not_found('save_active_ipv4_fingerprint', $file) or return; |
|
250
|
|
|
|
|
|
|
|
|
251
|
0
|
|
|
|
|
|
my $threshold = $self->threshold; |
|
252
|
|
|
|
|
|
|
|
|
253
|
0
|
|
|
|
|
|
my $log = Net::SinFP3::Log::Console->new( |
|
254
|
|
|
|
|
|
|
level => $self->log->level, |
|
255
|
|
|
|
|
|
|
); |
|
256
|
|
|
|
|
|
|
|
|
257
|
0
|
0
|
|
|
|
|
my $global = Net::SinFP3::Global->new( |
|
258
|
|
|
|
|
|
|
log => $log, |
|
259
|
|
|
|
|
|
|
target => $target_host, |
|
260
|
|
|
|
|
|
|
port => $target_port, |
|
261
|
|
|
|
|
|
|
ipv6 => 0, |
|
262
|
|
|
|
|
|
|
dnsReverse => 0, |
|
263
|
|
|
|
|
|
|
device => $device, |
|
264
|
|
|
|
|
|
|
threshold => $threshold, |
|
265
|
|
|
|
|
|
|
) or return $self->log->error("save_active_ipv4_fingerprint: global failed"); |
|
266
|
|
|
|
|
|
|
|
|
267
|
0
|
|
|
|
|
|
my $input = Net::SinFP3::Input::IpPort->new( |
|
268
|
|
|
|
|
|
|
global => $global, |
|
269
|
|
|
|
|
|
|
); |
|
270
|
|
|
|
|
|
|
|
|
271
|
0
|
|
|
|
|
|
my $db = Net::SinFP3::DB::SinFP3->new( |
|
272
|
|
|
|
|
|
|
global => $global, |
|
273
|
|
|
|
|
|
|
); |
|
274
|
|
|
|
|
|
|
|
|
275
|
0
|
|
|
|
|
|
my $mode = Net::SinFP3::Mode::Active->new( |
|
276
|
|
|
|
|
|
|
global => $global, |
|
277
|
|
|
|
|
|
|
doP1 => 1, |
|
278
|
|
|
|
|
|
|
doP2 => 1, |
|
279
|
|
|
|
|
|
|
doP3 => 1, |
|
280
|
|
|
|
|
|
|
); |
|
281
|
|
|
|
|
|
|
|
|
282
|
0
|
|
|
|
|
|
my $search = Net::SinFP3::Search::Active->new( |
|
283
|
|
|
|
|
|
|
global => $global, |
|
284
|
|
|
|
|
|
|
); |
|
285
|
|
|
|
|
|
|
|
|
286
|
0
|
|
|
|
|
|
my $output = Net::SinFP3::Output::Pcap->new( |
|
287
|
|
|
|
|
|
|
global => $global, |
|
288
|
|
|
|
|
|
|
anonymize => 1, |
|
289
|
|
|
|
|
|
|
); |
|
290
|
|
|
|
|
|
|
|
|
291
|
0
|
|
|
|
|
|
my $sinfp3 = Net::SinFP3->new( |
|
292
|
|
|
|
|
|
|
global => $global, |
|
293
|
|
|
|
|
|
|
input => [ $input ], |
|
294
|
|
|
|
|
|
|
db => [ $db ], |
|
295
|
|
|
|
|
|
|
mode => [ $mode ], |
|
296
|
|
|
|
|
|
|
search => [ $search ], |
|
297
|
|
|
|
|
|
|
output => [ $output ], |
|
298
|
|
|
|
|
|
|
); |
|
299
|
|
|
|
|
|
|
|
|
300
|
0
|
|
|
|
|
|
my $ret = $sinfp3->run; |
|
301
|
|
|
|
|
|
|
|
|
302
|
0
|
|
|
|
|
|
$log->post; |
|
303
|
|
|
|
|
|
|
|
|
304
|
0
|
|
|
|
|
|
my $pcap = 'sinfp4-127.0.0.1-'.$target_port.'.pcap'; |
|
305
|
0
|
0
|
|
|
|
|
if (-f $pcap) { |
|
306
|
0
|
|
|
|
|
|
File::Copy::move($pcap, $datadir); |
|
307
|
|
|
|
|
|
|
} |
|
308
|
|
|
|
|
|
|
|
|
309
|
0
|
|
|
|
|
|
return $datadir."/$pcap"; |
|
310
|
|
|
|
|
|
|
} |
|
311
|
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
sub save_active_ipv6_fingerprint { |
|
313
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
314
|
0
|
|
|
|
|
|
my ($target_host, $target_port) = @_; |
|
315
|
|
|
|
|
|
|
|
|
316
|
0
|
|
0
|
|
|
|
$target_host ||= $self->target; |
|
317
|
0
|
|
0
|
|
|
|
$target_port ||= $self->port; |
|
318
|
0
|
|
|
|
|
|
my $device = $self->device; |
|
319
|
0
|
0
|
|
|
|
|
$self->brik_help_run_undef_arg('save_active_ipv6_fingerprint', $target_host) or return; |
|
320
|
0
|
0
|
|
|
|
|
$self->brik_help_run_undef_arg('save_active_ipv6_fingerprint', $target_port) or return; |
|
321
|
|
|
|
|
|
|
|
|
322
|
0
|
|
|
|
|
|
my $datadir = $self->datadir; |
|
323
|
0
|
|
|
|
|
|
my $file = $datadir.'/'.$self->db; |
|
324
|
0
|
0
|
|
|
|
|
$self->brik_help_run_file_not_found('save_active_ipv6_fingerprint', $file) or return; |
|
325
|
|
|
|
|
|
|
|
|
326
|
0
|
|
|
|
|
|
my $threshold = $self->threshold; |
|
327
|
|
|
|
|
|
|
|
|
328
|
0
|
|
|
|
|
|
my $log = Net::SinFP3::Log::Console->new( |
|
329
|
|
|
|
|
|
|
level => $self->log->level, |
|
330
|
|
|
|
|
|
|
); |
|
331
|
|
|
|
|
|
|
|
|
332
|
0
|
0
|
|
|
|
|
my $global = Net::SinFP3::Global->new( |
|
333
|
|
|
|
|
|
|
log => $log, |
|
334
|
|
|
|
|
|
|
target => $target_host, |
|
335
|
|
|
|
|
|
|
port => $target_port, |
|
336
|
|
|
|
|
|
|
ipv6 => 1, |
|
337
|
|
|
|
|
|
|
dnsReverse => 0, |
|
338
|
|
|
|
|
|
|
device => $device, |
|
339
|
|
|
|
|
|
|
threshold => $threshold, |
|
340
|
|
|
|
|
|
|
) or return $self->log->error("save_active_ipv6_fingerprint: global failed"); |
|
341
|
|
|
|
|
|
|
|
|
342
|
0
|
|
|
|
|
|
my $input = Net::SinFP3::Input::IpPort->new( |
|
343
|
|
|
|
|
|
|
global => $global, |
|
344
|
|
|
|
|
|
|
); |
|
345
|
|
|
|
|
|
|
|
|
346
|
0
|
|
|
|
|
|
my $db = Net::SinFP3::DB::SinFP3->new( |
|
347
|
|
|
|
|
|
|
global => $global, |
|
348
|
|
|
|
|
|
|
file => $file, |
|
349
|
|
|
|
|
|
|
); |
|
350
|
|
|
|
|
|
|
|
|
351
|
0
|
|
|
|
|
|
my $mode = Net::SinFP3::Mode::Active->new( |
|
352
|
|
|
|
|
|
|
global => $global, |
|
353
|
|
|
|
|
|
|
doP1 => 1, |
|
354
|
|
|
|
|
|
|
doP2 => 1, |
|
355
|
|
|
|
|
|
|
doP3 => 1, |
|
356
|
|
|
|
|
|
|
); |
|
357
|
|
|
|
|
|
|
|
|
358
|
0
|
|
|
|
|
|
my $search = Net::SinFP3::Search::Active->new( |
|
359
|
|
|
|
|
|
|
global => $global, |
|
360
|
|
|
|
|
|
|
); |
|
361
|
|
|
|
|
|
|
|
|
362
|
0
|
|
|
|
|
|
my $output = Net::SinFP3::Output::Pcap->new( |
|
363
|
|
|
|
|
|
|
global => $global, |
|
364
|
|
|
|
|
|
|
anonymize => 1, |
|
365
|
|
|
|
|
|
|
); |
|
366
|
|
|
|
|
|
|
|
|
367
|
0
|
|
|
|
|
|
my $sinfp3 = Net::SinFP3->new( |
|
368
|
|
|
|
|
|
|
global => $global, |
|
369
|
|
|
|
|
|
|
input => [ $input ], |
|
370
|
|
|
|
|
|
|
db => [ $db ], |
|
371
|
|
|
|
|
|
|
mode => [ $mode ], |
|
372
|
|
|
|
|
|
|
search => [ $search ], |
|
373
|
|
|
|
|
|
|
output => [ $output ], |
|
374
|
|
|
|
|
|
|
); |
|
375
|
|
|
|
|
|
|
|
|
376
|
0
|
|
|
|
|
|
my $ret = $sinfp3->run; |
|
377
|
|
|
|
|
|
|
|
|
378
|
0
|
|
|
|
|
|
$log->post; |
|
379
|
|
|
|
|
|
|
|
|
380
|
0
|
|
|
|
|
|
my $pcap = 'sinfp6-::1-'.$target_port.'.pcap'; |
|
381
|
0
|
0
|
|
|
|
|
if (-f $pcap) { |
|
382
|
0
|
|
|
|
|
|
File::Copy::move($pcap, $datadir); |
|
383
|
|
|
|
|
|
|
} |
|
384
|
|
|
|
|
|
|
|
|
385
|
0
|
|
|
|
|
|
return $datadir."/$pcap"; |
|
386
|
|
|
|
|
|
|
} |
|
387
|
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
sub active_ipv4_from_pcap { |
|
389
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
390
|
0
|
|
|
|
|
|
my ($pcap_file) = @_; |
|
391
|
|
|
|
|
|
|
|
|
392
|
0
|
|
|
|
|
|
my $device = $self->device; |
|
393
|
0
|
0
|
|
|
|
|
$self->brik_help_run_undef_arg('active_ipv4_from_pcap', $pcap_file) or return; |
|
394
|
0
|
0
|
|
|
|
|
$self->brik_help_run_file_not_found('active_ipv4_from_pcap', $pcap_file) or return; |
|
395
|
|
|
|
|
|
|
|
|
396
|
0
|
|
|
|
|
|
my $datadir = $self->datadir; |
|
397
|
0
|
|
|
|
|
|
my $file = $datadir.'/'.$self->db; |
|
398
|
0
|
0
|
|
|
|
|
$self->brik_help_run_file_not_found('active_ipv4_from_pcap', $file) or return; |
|
399
|
|
|
|
|
|
|
|
|
400
|
0
|
|
|
|
|
|
my $threshold = $self->threshold; |
|
401
|
|
|
|
|
|
|
|
|
402
|
0
|
|
|
|
|
|
my $log = Net::SinFP3::Log::Console->new( |
|
403
|
|
|
|
|
|
|
level => $self->log->level, |
|
404
|
|
|
|
|
|
|
); |
|
405
|
|
|
|
|
|
|
|
|
406
|
0
|
0
|
|
|
|
|
my $global = Net::SinFP3::Global->new( |
|
407
|
|
|
|
|
|
|
log => $log, |
|
408
|
|
|
|
|
|
|
ipv6 => 0, |
|
409
|
|
|
|
|
|
|
dnsReverse => 0, |
|
410
|
|
|
|
|
|
|
device => $device, |
|
411
|
|
|
|
|
|
|
threshold => $threshold, |
|
412
|
|
|
|
|
|
|
) or return $self->log->error("active_ipv4_from_pcap: global failed"); |
|
413
|
|
|
|
|
|
|
|
|
414
|
0
|
|
|
|
|
|
my $input = Net::SinFP3::Input::Pcap->new( |
|
415
|
|
|
|
|
|
|
global => $global, |
|
416
|
|
|
|
|
|
|
file => $pcap_file, |
|
417
|
|
|
|
|
|
|
count => 10, |
|
418
|
|
|
|
|
|
|
); |
|
419
|
|
|
|
|
|
|
|
|
420
|
0
|
|
|
|
|
|
my $db = Net::SinFP3::DB::SinFP3->new( |
|
421
|
|
|
|
|
|
|
global => $global, |
|
422
|
|
|
|
|
|
|
file => $file, |
|
423
|
|
|
|
|
|
|
); |
|
424
|
|
|
|
|
|
|
|
|
425
|
0
|
|
|
|
|
|
my $mode = Net::SinFP3::Mode::Active->new( |
|
426
|
|
|
|
|
|
|
global => $global, |
|
427
|
|
|
|
|
|
|
doP1 => 1, |
|
428
|
|
|
|
|
|
|
doP2 => 1, |
|
429
|
|
|
|
|
|
|
doP3 => 1, |
|
430
|
|
|
|
|
|
|
); |
|
431
|
|
|
|
|
|
|
|
|
432
|
0
|
|
|
|
|
|
my $search = Net::SinFP3::Search::Active->new( |
|
433
|
|
|
|
|
|
|
global => $global, |
|
434
|
|
|
|
|
|
|
); |
|
435
|
|
|
|
|
|
|
|
|
436
|
0
|
|
|
|
|
|
my $output = Net::SinFP3::Output::Console->new( |
|
437
|
|
|
|
|
|
|
global => $global, |
|
438
|
|
|
|
|
|
|
); |
|
439
|
|
|
|
|
|
|
|
|
440
|
0
|
|
|
|
|
|
my $sinfp3 = Net::SinFP3->new( |
|
441
|
|
|
|
|
|
|
global => $global, |
|
442
|
|
|
|
|
|
|
input => [ $input ], |
|
443
|
|
|
|
|
|
|
db => [ $db ], |
|
444
|
|
|
|
|
|
|
mode => [ $mode ], |
|
445
|
|
|
|
|
|
|
search => [ $search ], |
|
446
|
|
|
|
|
|
|
output => [ $output ], |
|
447
|
|
|
|
|
|
|
); |
|
448
|
|
|
|
|
|
|
|
|
449
|
0
|
|
|
|
|
|
my $ret = $sinfp3->run; |
|
450
|
|
|
|
|
|
|
|
|
451
|
0
|
|
|
|
|
|
$log->post; |
|
452
|
|
|
|
|
|
|
|
|
453
|
0
|
|
|
|
|
|
return $ret; |
|
454
|
|
|
|
|
|
|
} |
|
455
|
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
sub active_ipv6_from_pcap { |
|
457
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
458
|
0
|
|
|
|
|
|
my ($pcap_file) = @_; |
|
459
|
|
|
|
|
|
|
|
|
460
|
0
|
|
|
|
|
|
my $device = $self->device; |
|
461
|
0
|
0
|
|
|
|
|
$self->brik_help_run_undef_arg('active_ipv6_from_pcap', $pcap_file) or return; |
|
462
|
0
|
0
|
|
|
|
|
$self->brik_help_run_file_not_found('active_ipv6_from_pcap', $pcap_file) or return; |
|
463
|
|
|
|
|
|
|
|
|
464
|
0
|
|
|
|
|
|
my $datadir = $self->datadir; |
|
465
|
0
|
|
|
|
|
|
my $file = $datadir.'/'.$self->db; |
|
466
|
0
|
0
|
|
|
|
|
$self->brik_help_run_file_not_found('active_ipv6_from_pcap', $file) or return; |
|
467
|
|
|
|
|
|
|
|
|
468
|
0
|
|
|
|
|
|
my $threshold = $self->threshold; |
|
469
|
|
|
|
|
|
|
|
|
470
|
0
|
|
|
|
|
|
my $log = Net::SinFP3::Log::Console->new( |
|
471
|
|
|
|
|
|
|
level => $self->log->level, |
|
472
|
|
|
|
|
|
|
); |
|
473
|
|
|
|
|
|
|
|
|
474
|
0
|
0
|
|
|
|
|
my $global = Net::SinFP3::Global->new( |
|
475
|
|
|
|
|
|
|
log => $log, |
|
476
|
|
|
|
|
|
|
ipv6 => 1, |
|
477
|
|
|
|
|
|
|
dnsReverse => 0, |
|
478
|
|
|
|
|
|
|
device => $device, |
|
479
|
|
|
|
|
|
|
threshold => $threshold, |
|
480
|
|
|
|
|
|
|
) or return $self->log->error("active_ipv6_from_pcap: global failed"); |
|
481
|
|
|
|
|
|
|
|
|
482
|
0
|
|
|
|
|
|
my $input = Net::SinFP3::Input::Pcap->new( |
|
483
|
|
|
|
|
|
|
global => $global, |
|
484
|
|
|
|
|
|
|
file => $pcap_file, |
|
485
|
|
|
|
|
|
|
count => 10, |
|
486
|
|
|
|
|
|
|
); |
|
487
|
|
|
|
|
|
|
|
|
488
|
0
|
|
|
|
|
|
my $db = Net::SinFP3::DB::SinFP3->new( |
|
489
|
|
|
|
|
|
|
global => $global, |
|
490
|
|
|
|
|
|
|
file => $file, |
|
491
|
|
|
|
|
|
|
); |
|
492
|
|
|
|
|
|
|
|
|
493
|
0
|
|
|
|
|
|
my $mode = Net::SinFP3::Mode::Active->new( |
|
494
|
|
|
|
|
|
|
global => $global, |
|
495
|
|
|
|
|
|
|
doP1 => 1, |
|
496
|
|
|
|
|
|
|
doP2 => 1, |
|
497
|
|
|
|
|
|
|
doP3 => 1, |
|
498
|
|
|
|
|
|
|
); |
|
499
|
|
|
|
|
|
|
|
|
500
|
0
|
|
|
|
|
|
my $search = Net::SinFP3::Search::Active->new( |
|
501
|
|
|
|
|
|
|
global => $global, |
|
502
|
|
|
|
|
|
|
); |
|
503
|
|
|
|
|
|
|
|
|
504
|
0
|
|
|
|
|
|
my $output = Net::SinFP3::Output::Console->new( |
|
505
|
|
|
|
|
|
|
global => $global, |
|
506
|
|
|
|
|
|
|
); |
|
507
|
|
|
|
|
|
|
|
|
508
|
0
|
|
|
|
|
|
my $sinfp3 = Net::SinFP3->new( |
|
509
|
|
|
|
|
|
|
global => $global, |
|
510
|
|
|
|
|
|
|
input => [ $input ], |
|
511
|
|
|
|
|
|
|
db => [ $db ], |
|
512
|
|
|
|
|
|
|
mode => [ $mode ], |
|
513
|
|
|
|
|
|
|
search => [ $search ], |
|
514
|
|
|
|
|
|
|
output => [ $output ], |
|
515
|
|
|
|
|
|
|
); |
|
516
|
|
|
|
|
|
|
|
|
517
|
0
|
|
|
|
|
|
my $ret = $sinfp3->run; |
|
518
|
|
|
|
|
|
|
|
|
519
|
0
|
|
|
|
|
|
$log->post; |
|
520
|
|
|
|
|
|
|
|
|
521
|
0
|
|
|
|
|
|
return $ret; |
|
522
|
|
|
|
|
|
|
} |
|
523
|
|
|
|
|
|
|
|
|
524
|
|
|
|
|
|
|
sub _parse_result { |
|
525
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
526
|
0
|
|
|
|
|
|
my ($result) = @_; |
|
527
|
|
|
|
|
|
|
|
|
528
|
0
|
|
|
|
|
|
my @final = (); |
|
529
|
0
|
|
|
|
|
|
for my $r (@$result) { |
|
530
|
0
|
|
|
|
|
|
my $h = { |
|
531
|
|
|
|
|
|
|
id_signature => $r->idSignature, |
|
532
|
|
|
|
|
|
|
ip_version => $r->ipVersion, |
|
533
|
|
|
|
|
|
|
system_class => $r->systemClass, |
|
534
|
|
|
|
|
|
|
vendor => $r->vendor, |
|
535
|
|
|
|
|
|
|
os => $r->os, |
|
536
|
|
|
|
|
|
|
os_version => $r->osVersion, |
|
537
|
|
|
|
|
|
|
os_version_family => $r->osVersionFamily, |
|
538
|
|
|
|
|
|
|
match_type => $r->matchType, |
|
539
|
|
|
|
|
|
|
match_score => $r->matchScore, |
|
540
|
|
|
|
|
|
|
match_mask => $r->matchMask, |
|
541
|
|
|
|
|
|
|
}; |
|
542
|
0
|
|
|
|
|
|
for ($r->osVersionChildrenList) { |
|
543
|
0
|
|
|
|
|
|
push @{$h->{os_version_children}}, $_; |
|
|
0
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
} |
|
545
|
0
|
|
|
|
|
|
push @final, $h; |
|
546
|
|
|
|
|
|
|
} |
|
547
|
|
|
|
|
|
|
|
|
548
|
0
|
|
|
|
|
|
return \@final; |
|
549
|
|
|
|
|
|
|
} |
|
550
|
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
sub _analyze_options { |
|
552
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
553
|
0
|
|
|
|
|
|
my ($opts) = @_; |
|
554
|
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
# Rewrite timestamp values, if > 0 overwrite with ffff, |
|
556
|
|
|
|
|
|
|
# for each timestamp. Same with WScale value |
|
557
|
0
|
|
|
|
|
|
my $mss; |
|
558
|
|
|
|
|
|
|
my $wscale; |
|
559
|
0
|
0
|
|
|
|
|
if ($opts =~ m/^(.*080a)(.{8})(.{8})(.*)/) { |
|
560
|
0
|
|
|
|
|
|
my $head = $1; |
|
561
|
0
|
|
|
|
|
|
my $a = $2; |
|
562
|
0
|
|
|
|
|
|
my $b = $3; |
|
563
|
0
|
|
|
|
|
|
my $tail = $4; |
|
564
|
|
|
|
|
|
|
# Some systems put timestamp values to 00. We keep it for |
|
565
|
|
|
|
|
|
|
# fingerprint matching. If there is no DEAD, it is not a |
|
566
|
|
|
|
|
|
|
# reply to a SinFP3 probe, we strip this value. |
|
567
|
0
|
0
|
0
|
|
|
|
if ($a !~ /00000000/ && $a !~ /44454144/) { |
|
568
|
0
|
|
|
|
|
|
$a = "........"; |
|
569
|
|
|
|
|
|
|
} |
|
570
|
0
|
0
|
0
|
|
|
|
if ($b !~ /00000000/ && $b !~ /44454144/) { |
|
571
|
0
|
|
|
|
|
|
$b = "........"; |
|
572
|
|
|
|
|
|
|
} |
|
573
|
0
|
|
|
|
|
|
$opts = $head.$a.$b.$tail; |
|
574
|
|
|
|
|
|
|
} |
|
575
|
|
|
|
|
|
|
# Move MSS value in its own field |
|
576
|
0
|
0
|
|
|
|
|
if ($opts =~ /0204(....)/) { |
|
577
|
0
|
0
|
|
|
|
|
if ($1) { |
|
578
|
0
|
|
|
|
|
|
$mss = sprintf("%d", hex($1)); |
|
579
|
0
|
|
|
|
|
|
$opts =~ s/0204..../0204ffff/; |
|
580
|
|
|
|
|
|
|
} |
|
581
|
|
|
|
|
|
|
} |
|
582
|
|
|
|
|
|
|
# Move WScale value in its own field |
|
583
|
0
|
0
|
|
|
|
|
if ($opts =~ /0303(..)/) { |
|
584
|
0
|
0
|
|
|
|
|
if ($1) { |
|
585
|
0
|
|
|
|
|
|
$wscale = sprintf("%d", hex($1)); |
|
586
|
0
|
|
|
|
|
|
$opts =~ s/0303../0303ff/; |
|
587
|
|
|
|
|
|
|
} |
|
588
|
|
|
|
|
|
|
} |
|
589
|
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
# We completely ignore payload from original SinFP3 code. |
|
591
|
|
|
|
|
|
|
# If we want it, we have to pad $opts with it. |
|
592
|
|
|
|
|
|
|
#$opts .= unpack('H*', $p->reply->ref->{TCP}->payload) |
|
593
|
|
|
|
|
|
|
#if $p->reply->ref->{TCP}->payload; |
|
594
|
|
|
|
|
|
|
|
|
595
|
0
|
|
0
|
|
|
|
$opts ||= '0'; |
|
596
|
0
|
|
0
|
|
|
|
$mss ||= '0'; |
|
597
|
0
|
|
0
|
|
|
|
$wscale ||= '0'; |
|
598
|
|
|
|
|
|
|
|
|
599
|
0
|
0
|
|
|
|
|
my $opt_len = $opts ? length($opts) / 2 : 0; |
|
600
|
|
|
|
|
|
|
|
|
601
|
0
|
|
|
|
|
|
return [ $opts, $mss, $wscale, $opt_len ]; |
|
602
|
|
|
|
|
|
|
} |
|
603
|
|
|
|
|
|
|
|
|
604
|
|
|
|
|
|
|
sub to_signature_from_tcp_window_and_options { |
|
605
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
606
|
0
|
|
|
|
|
|
my ($window, $options) = @_; |
|
607
|
|
|
|
|
|
|
|
|
608
|
0
|
0
|
|
|
|
|
$self->brik_help_run_undef_arg('to_signature_from_tcp_window_and_options', $window) |
|
609
|
|
|
|
|
|
|
or return; |
|
610
|
0
|
0
|
|
|
|
|
$self->brik_help_run_undef_arg('to_signature_from_tcp_window_and_options', $options) |
|
611
|
|
|
|
|
|
|
or return; |
|
612
|
|
|
|
|
|
|
|
|
613
|
|
|
|
|
|
|
# |
|
614
|
|
|
|
|
|
|
# Example: |
|
615
|
|
|
|
|
|
|
# S2: B11113 F0x12 W65535 O0204ffff010303ff0402080affffffff44454144 M1460 S6 L20 |
|
616
|
|
|
|
|
|
|
# |
|
617
|
|
|
|
|
|
|
# Convert TCP options, extract MSS and Scale values |
|
618
|
0
|
|
|
|
|
|
my $a = $self->_analyze_options($options); |
|
619
|
0
|
|
|
|
|
|
my $tcp_options = $a->[0]; |
|
620
|
0
|
|
|
|
|
|
my $tcp_mss = $a->[1]; |
|
621
|
0
|
|
|
|
|
|
my $tcp_scale = $a->[2]; |
|
622
|
0
|
|
|
|
|
|
my $opt_len = $a->[3]; |
|
623
|
|
|
|
|
|
|
|
|
624
|
|
|
|
|
|
|
return { |
|
625
|
0
|
|
|
|
|
|
B => '.....', # We completly ignore IP header. |
|
626
|
|
|
|
|
|
|
F => '0x12', # We consider it is a SYN|ACK |
|
627
|
|
|
|
|
|
|
W => $window, |
|
628
|
|
|
|
|
|
|
O => $tcp_options, |
|
629
|
|
|
|
|
|
|
M => $tcp_mss, |
|
630
|
|
|
|
|
|
|
S => $tcp_scale, |
|
631
|
|
|
|
|
|
|
L => $opt_len, |
|
632
|
|
|
|
|
|
|
}; |
|
633
|
|
|
|
|
|
|
} |
|
634
|
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
sub to_signature_from_tcp_options { |
|
636
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
637
|
0
|
|
|
|
|
|
my ($options) = @_; |
|
638
|
|
|
|
|
|
|
|
|
639
|
0
|
0
|
|
|
|
|
$self->brik_help_run_undef_arg('to_signature_from_tcp_options', $options) or return; |
|
640
|
|
|
|
|
|
|
|
|
641
|
|
|
|
|
|
|
# |
|
642
|
|
|
|
|
|
|
# Example: |
|
643
|
|
|
|
|
|
|
# S2: B11113 F0x12 W65535 O0204ffff010303ff0402080affffffff44454144 M1460 S6 L20 |
|
644
|
|
|
|
|
|
|
# |
|
645
|
|
|
|
|
|
|
# Convert TCP options, extract MSS and Scale values |
|
646
|
0
|
|
|
|
|
|
my $a = $self->_analyze_options($options); |
|
647
|
0
|
|
|
|
|
|
my $tcp_options = $a->[0]; |
|
648
|
0
|
|
|
|
|
|
my $tcp_mss = $a->[1]; |
|
649
|
0
|
|
|
|
|
|
my $tcp_scale = $a->[2]; |
|
650
|
0
|
|
|
|
|
|
my $opt_len = $a->[3]; |
|
651
|
|
|
|
|
|
|
|
|
652
|
|
|
|
|
|
|
return { |
|
653
|
0
|
|
|
|
|
|
B => '.....', # We completely ignore IP header. |
|
654
|
|
|
|
|
|
|
F => '0x12', # We consider it is a SYN|ACK |
|
655
|
|
|
|
|
|
|
W => '\\d+', # We completely ignore TCP window size. |
|
656
|
|
|
|
|
|
|
O => $tcp_options, |
|
657
|
|
|
|
|
|
|
M => $tcp_mss, |
|
658
|
|
|
|
|
|
|
S => $tcp_scale, |
|
659
|
|
|
|
|
|
|
L => $opt_len, |
|
660
|
|
|
|
|
|
|
}; |
|
661
|
|
|
|
|
|
|
} |
|
662
|
|
|
|
|
|
|
|
|
663
|
|
|
|
|
|
|
sub active_ipv4_from_tcp_window_and_options { |
|
664
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
665
|
0
|
|
|
|
|
|
my ($window, $options) = @_; |
|
666
|
|
|
|
|
|
|
|
|
667
|
0
|
0
|
|
|
|
|
$self->brik_help_run_undef_arg('active_ipv4_from_tcp_window_and_options', $window) |
|
668
|
|
|
|
|
|
|
or return; |
|
669
|
0
|
0
|
|
|
|
|
$self->brik_help_run_undef_arg('active_ipv4_from_tcp_window_and_options', $options) |
|
670
|
|
|
|
|
|
|
or return; |
|
671
|
|
|
|
|
|
|
|
|
672
|
0
|
|
|
|
|
|
my $global = $self->_global; |
|
673
|
|
|
|
|
|
|
|
|
674
|
0
|
0
|
|
|
|
|
my $mode = Net::SinFP3::Mode::Active->new( |
|
675
|
|
|
|
|
|
|
global => $global, |
|
676
|
|
|
|
|
|
|
doP1 => 1, |
|
677
|
|
|
|
|
|
|
doP2 => 1, |
|
678
|
|
|
|
|
|
|
doP3 => 1, |
|
679
|
|
|
|
|
|
|
) or return $self->log->error('active_ipv4_from_tcp_window_and_options: mode::active failed'); |
|
680
|
0
|
|
|
|
|
|
$mode->init; |
|
681
|
0
|
|
|
|
|
|
$global->mode($mode); |
|
682
|
|
|
|
|
|
|
|
|
683
|
0
|
0
|
|
|
|
|
my $s = $self->to_signature_from_tcp_window_and_options($window, $options) or return; |
|
684
|
|
|
|
|
|
|
my $s2 = Net::SinFP3::Ext::S->new( |
|
685
|
|
|
|
|
|
|
B => 'B'.$s->{B}, |
|
686
|
|
|
|
|
|
|
F => 'F'.$s->{F}, |
|
687
|
|
|
|
|
|
|
W => 'W'.$s->{W}, |
|
688
|
|
|
|
|
|
|
O => 'O'.$s->{O}, |
|
689
|
|
|
|
|
|
|
M => 'M'.$s->{M}, |
|
690
|
|
|
|
|
|
|
S => 'S'.$s->{S}, |
|
691
|
|
|
|
|
|
|
L => 'L'.$s->{L}, |
|
692
|
0
|
|
|
|
|
|
); |
|
693
|
0
|
0
|
|
|
|
|
if (! defined($s2)) { |
|
694
|
0
|
|
|
|
|
|
return $self->log->error('active_ipv4_from_tcp_window_and_options: ext::s failed'); |
|
695
|
|
|
|
|
|
|
} |
|
696
|
|
|
|
|
|
|
|
|
697
|
0
|
|
|
|
|
|
my $search = Net::SinFP3::Search::Active->new( |
|
698
|
|
|
|
|
|
|
global => $global, |
|
699
|
|
|
|
|
|
|
#s1 => $s1, |
|
700
|
|
|
|
|
|
|
s2 => $s2, # We only use S2 here. Be sure to have enough TCP options in your reply. |
|
701
|
|
|
|
|
|
|
#s3 => $s3, |
|
702
|
|
|
|
|
|
|
); |
|
703
|
0
|
|
|
|
|
|
$search->init; |
|
704
|
0
|
|
|
|
|
|
$global->search($search); |
|
705
|
|
|
|
|
|
|
|
|
706
|
0
|
|
|
|
|
|
my $r = $search->search; |
|
707
|
|
|
|
|
|
|
|
|
708
|
0
|
|
|
|
|
|
return $self->_parse_result($r); |
|
709
|
|
|
|
|
|
|
} |
|
710
|
|
|
|
|
|
|
|
|
711
|
|
|
|
|
|
|
sub active_ipv4_from_tcp_options { |
|
712
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
713
|
0
|
|
|
|
|
|
my ($options) = @_; |
|
714
|
|
|
|
|
|
|
|
|
715
|
0
|
0
|
|
|
|
|
$self->brik_help_run_undef_arg('active_ipv4_from_tcp_options', $options) or return; |
|
716
|
|
|
|
|
|
|
|
|
717
|
0
|
|
|
|
|
|
my $global = $self->_global; |
|
718
|
|
|
|
|
|
|
|
|
719
|
0
|
0
|
|
|
|
|
my $mode = Net::SinFP3::Mode::Active->new( |
|
720
|
|
|
|
|
|
|
global => $global, |
|
721
|
|
|
|
|
|
|
doP1 => 1, |
|
722
|
|
|
|
|
|
|
doP2 => 1, |
|
723
|
|
|
|
|
|
|
doP3 => 1, |
|
724
|
|
|
|
|
|
|
) or return $self->log->error('active_ipv4_from_tcp_options: mode::active failed'); |
|
725
|
0
|
|
|
|
|
|
$mode->init; |
|
726
|
0
|
|
|
|
|
|
$global->mode($mode); |
|
727
|
|
|
|
|
|
|
|
|
728
|
0
|
0
|
|
|
|
|
my $s = $self->to_signature_from_tcp_options($options) or return; |
|
729
|
|
|
|
|
|
|
my $s2 = Net::SinFP3::Ext::S->new( |
|
730
|
|
|
|
|
|
|
B => 'B'.$s->{B}, |
|
731
|
|
|
|
|
|
|
F => 'F'.$s->{F}, |
|
732
|
|
|
|
|
|
|
W => 'W'.$s->{W}, |
|
733
|
|
|
|
|
|
|
O => 'O'.$s->{O}, |
|
734
|
|
|
|
|
|
|
M => 'M'.$s->{M}, |
|
735
|
|
|
|
|
|
|
S => 'S'.$s->{S}, |
|
736
|
|
|
|
|
|
|
L => 'L'.$s->{L}, |
|
737
|
0
|
|
|
|
|
|
); |
|
738
|
0
|
0
|
|
|
|
|
if (! defined($s2)) { |
|
739
|
0
|
|
|
|
|
|
return $self->log->error('active_ipv4_from_tcp_options: ext::s failed'); |
|
740
|
|
|
|
|
|
|
} |
|
741
|
|
|
|
|
|
|
|
|
742
|
0
|
|
|
|
|
|
my $search = Net::SinFP3::Search::Active->new( |
|
743
|
|
|
|
|
|
|
global => $global, |
|
744
|
|
|
|
|
|
|
#s1 => $s1, |
|
745
|
|
|
|
|
|
|
s2 => $s2, # We only use S2 here. Be sure to have enough TCP options in your reply. |
|
746
|
|
|
|
|
|
|
#s3 => $s3, |
|
747
|
|
|
|
|
|
|
); |
|
748
|
0
|
|
|
|
|
|
$search->init; |
|
749
|
0
|
|
|
|
|
|
$global->search($search); |
|
750
|
|
|
|
|
|
|
|
|
751
|
0
|
|
|
|
|
|
my $r = $search->search; |
|
752
|
|
|
|
|
|
|
|
|
753
|
0
|
|
|
|
|
|
return $self->_parse_result($r); |
|
754
|
|
|
|
|
|
|
} |
|
755
|
|
|
|
|
|
|
|
|
756
|
|
|
|
|
|
|
sub active_ipv4_from_signature { |
|
757
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
758
|
0
|
|
|
|
|
|
my ($signature) = @_; |
|
759
|
|
|
|
|
|
|
|
|
760
|
0
|
0
|
|
|
|
|
$self->brik_help_run_undef_arg('active_ipv4_from_signature', $signature) or return; |
|
761
|
0
|
0
|
|
|
|
|
$self->brik_help_run_invalid_arg('active_ipv4_from_signature', $signature, 'HASH') or return; |
|
762
|
|
|
|
|
|
|
|
|
763
|
0
|
|
|
|
|
|
my $global = $self->_global; |
|
764
|
|
|
|
|
|
|
|
|
765
|
0
|
0
|
|
|
|
|
my $mode = Net::SinFP3::Mode::Active->new( |
|
766
|
|
|
|
|
|
|
global => $global, |
|
767
|
|
|
|
|
|
|
doP1 => 1, |
|
768
|
|
|
|
|
|
|
doP2 => 1, |
|
769
|
|
|
|
|
|
|
doP3 => 1, |
|
770
|
|
|
|
|
|
|
) or return $self->log->error('active_ipv4_from_signature: mode::active failed'); |
|
771
|
0
|
|
|
|
|
|
$mode->init; |
|
772
|
0
|
|
|
|
|
|
$global->mode($mode); |
|
773
|
|
|
|
|
|
|
|
|
774
|
|
|
|
|
|
|
my $s2 = Net::SinFP3::Ext::S->new( |
|
775
|
|
|
|
|
|
|
B => 'B'.$signature->{B}, |
|
776
|
|
|
|
|
|
|
F => 'F'.$signature->{F}, |
|
777
|
|
|
|
|
|
|
W => 'W'.$signature->{W}, |
|
778
|
|
|
|
|
|
|
O => 'O'.$signature->{O}, |
|
779
|
|
|
|
|
|
|
M => 'M'.$signature->{M}, |
|
780
|
|
|
|
|
|
|
S => 'S'.$signature->{S}, |
|
781
|
|
|
|
|
|
|
L => 'L'.$signature->{L}, |
|
782
|
0
|
|
|
|
|
|
); |
|
783
|
0
|
0
|
|
|
|
|
if (! defined($s2)) { |
|
784
|
0
|
|
|
|
|
|
return $self->log->error('active_ipv4_from_signature: ext::s failed'); |
|
785
|
|
|
|
|
|
|
} |
|
786
|
|
|
|
|
|
|
|
|
787
|
0
|
|
|
|
|
|
my $search = Net::SinFP3::Search::Active->new( |
|
788
|
|
|
|
|
|
|
global => $global, |
|
789
|
|
|
|
|
|
|
#s1 => $s1, |
|
790
|
|
|
|
|
|
|
s2 => $s2, # We only use S2 here. Be sure to have enough TCP options in your reply. |
|
791
|
|
|
|
|
|
|
#s3 => $s3, |
|
792
|
|
|
|
|
|
|
); |
|
793
|
0
|
|
|
|
|
|
$search->init; |
|
794
|
0
|
|
|
|
|
|
$global->search($search); |
|
795
|
|
|
|
|
|
|
|
|
796
|
0
|
|
|
|
|
|
my $r = $search->search; |
|
797
|
|
|
|
|
|
|
|
|
798
|
0
|
|
|
|
|
|
return $self->_parse_result($r); |
|
799
|
|
|
|
|
|
|
} |
|
800
|
|
|
|
|
|
|
|
|
801
|
|
|
|
|
|
|
sub get_os_list_from_result { |
|
802
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
803
|
0
|
|
|
|
|
|
my ($result) = @_; |
|
804
|
|
|
|
|
|
|
|
|
805
|
0
|
0
|
|
|
|
|
$self->brik_help_run_undef_arg('get_os_list_from_result', $result) or return; |
|
806
|
0
|
0
|
|
|
|
|
$self->brik_help_run_invalid_arg('get_os_list_from_result', $result, 'ARRAY') or return; |
|
807
|
0
|
0
|
|
|
|
|
$self->brik_help_run_empty_array_arg('get_os_list_from_result', $result) or return; |
|
808
|
|
|
|
|
|
|
|
|
809
|
0
|
|
|
|
|
|
my %os_list = map { $_->{os} => 1 } @$result; |
|
|
0
|
|
|
|
|
|
|
|
810
|
|
|
|
|
|
|
|
|
811
|
0
|
|
|
|
|
|
return [ sort { $a cmp $b } keys %os_list ]; |
|
|
0
|
|
|
|
|
|
|
|
812
|
|
|
|
|
|
|
} |
|
813
|
|
|
|
|
|
|
|
|
814
|
|
|
|
|
|
|
sub brik_fini { |
|
815
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
|
816
|
|
|
|
|
|
|
|
|
817
|
0
|
|
|
|
|
|
my $global = $self->_global; |
|
818
|
0
|
0
|
|
|
|
|
if (defined($global)) { |
|
819
|
0
|
|
|
|
|
|
my $search = $global->search; |
|
820
|
0
|
|
|
|
|
|
my $mode = $global->mode; |
|
821
|
0
|
|
|
|
|
|
my $db = $global->db; |
|
822
|
0
|
|
|
|
|
|
my $log = $global->log; |
|
823
|
|
|
|
|
|
|
|
|
824
|
0
|
0
|
|
|
|
|
if (defined($search)) { |
|
825
|
0
|
|
|
|
|
|
$search->post; |
|
826
|
|
|
|
|
|
|
} |
|
827
|
0
|
0
|
|
|
|
|
if (defined($mode)) { |
|
828
|
0
|
|
|
|
|
|
$mode->post; |
|
829
|
|
|
|
|
|
|
} |
|
830
|
0
|
0
|
|
|
|
|
if (defined($db)) { |
|
831
|
0
|
|
|
|
|
|
$db->post; |
|
832
|
|
|
|
|
|
|
} |
|
833
|
0
|
0
|
|
|
|
|
if (defined($log)) { |
|
834
|
0
|
|
|
|
|
|
$log->post; |
|
835
|
|
|
|
|
|
|
} |
|
836
|
0
|
|
|
|
|
|
$global->search(undef); |
|
837
|
0
|
|
|
|
|
|
$global->mode(undef); |
|
838
|
0
|
|
|
|
|
|
$global->db(undef); |
|
839
|
0
|
|
|
|
|
|
$global->log(undef); |
|
840
|
0
|
|
|
|
|
|
$self->_global(undef); |
|
841
|
|
|
|
|
|
|
|
|
842
|
0
|
|
|
|
|
|
return 1; |
|
843
|
|
|
|
|
|
|
} |
|
844
|
|
|
|
|
|
|
|
|
845
|
0
|
|
|
|
|
|
return 0; |
|
846
|
|
|
|
|
|
|
} |
|
847
|
|
|
|
|
|
|
|
|
848
|
|
|
|
|
|
|
1; |
|
849
|
|
|
|
|
|
|
|
|
850
|
|
|
|
|
|
|
__END__ |