Merge pull request #56 from wuruilong01/master
[prads.git] / tools / snortifyprads.pl
blobc87e4b22e3d7827e888e5529fb7a909b56245b3d
1 #!/usr/bin/perl -w
3 # Convert PRADS db to SNORT host-attribute table
5 # Usage:
6 #
7 # Work-in-progress: services!
8 # XXX:
9 # - figure out how to filter client ports (not a "service" per se
10 # - what is confidence and how does it affect the resulting rules?
11 # - why oh why attribute maps?
13 # Copyright 2010 Kacper Wysocki <kwy@redpill-linpro.com>
15 use strict;
16 use warnings;
18 use DBI;
20 our $DATABASE = 'dbi:SQLite:dbname=prads.db';
21 our $DB_USERNAME;
22 our $DB_PASSWORD;
23 our $DB_TABLE = 'asset';
24 our $DBH;
26 our $SQL_IP = 'ipaddress';
27 our $SQL_FP = 'os_fingerprint';
28 our $SQL_MAC = 'mac_address';
29 our $SQL_DETAILS = 'os_details';
30 our $SQL_HOSTNAME = 'hostname';
31 our $SQL_TIME = 'timestamp';
33 our $SW = 4;
34 our $IL = 0;
36 # start attributes at this number
37 our $ATTR_NUM = 1337;
38 our %attr;
40 sub tab {
41 $IL++;
43 sub bat {
44 $IL--;
47 sub out_hat {
48 out ('<SNORT_ATTRIBUTES>');
49 tab;
50 db_suck($DATABASE,$DB_USERNAME,$DB_PASSWORD,$DB_TABLE);
51 bat;
52 out ('</SNORT_ATTRIBUTES>');
55 sub out {
56 print " " x ($SW * $IL);
57 for (@_){
58 print;
60 print "\n";
63 sub out_tag {
64 my ($tag, $value) = @_;
65 out ("<$tag>$value</$tag>");
68 sub out_ai {
69 my ($value) = @_;
70 out_tag ('ATTRIBUTE_ID', $value);
72 sub out_av {
73 my ($value) = @_;
74 out_tag ('ATTRIBUTE_VALUE', $value);
76 sub db_suck {
77 my ($db, $user, $pass, $table) = @_;
78 $DBH = DBI->connect($db, $user, $pass);
81 if ($db =~ /dbi:sqlite/i) {
82 $SQL_IP = 'ip';
83 $SQL_FP = 'fingerprint';
84 $SQL_MAC = 'mac';
85 $SQL_TIME = 'time';
86 $SQL_DETAILS = 'details';
87 $SQL_HOSTNAME = 'reporting';
90 # do attribute map
91 out ('<ATTRIBUTE_TABLE>');
92 out_hosts($table);
93 out ('</ATTRIBUTE_TABLE>');
94 out_attribute_map();
97 sub out_hosts {
98 my ($table) = @_;
99 #todo : should be uniq'ed somehhow!
100 #my $sql = "SELECT $SQL_IP,$SQL_TIME, service, $SQL_MAC, os, $SQL_DETAILS FROM $table WHERE service = 'SYN' OR service = 'SYNACK'";
101 my $sql = "SELECT DISTINCT $SQL_IP,$SQL_TIME, service, $SQL_MAC, os, $SQL_DETAILS FROM $table WHERE service = 'SYN' OR service = 'SYNACK' OR service = 'UDP' OR service = 'ICMP'";
103 my $sth = $DBH->prepare_cached($sql);
104 $sth->execute();
105 my ($ip, $time, $service, $mac, $os, $details);
106 #meh
107 #while ( ($ip, $time, $service, $mac, $os, $details) = $sth->fetchrow_array()) {
108 # print "$ip $time $service $mac $os $details\n";
111 my $ref;
112 while ($ref = $sth->fetchrow_hashref()) {
113 out ('<HOST>');
114 tab;
115 out_tag('IP', $ref->{'ip'});
116 tab;
117 out ('<OPERATING_SYSTEM>');
118 tab;
119 out_os($ref);
120 bat;
121 out ('</OPERATING_SYSTEM>');
122 out ('<SERVICES>');
123 tab;
124 out_services($ref->{'ip'});
125 bat;
126 out ('</SERVICES>');
127 bat;
128 out ('</HOST>');
129 bat;
133 sub out_os {
134 my ($ref) = @_;
135 out ('<NAME>');
136 tab;
137 out_ai(gen_attribute_id($ref->{'os'}));
138 bat;
139 out ('</NAME>');
140 out ('<VENDOR>');
141 tab;
142 out_av (gen_vendor($ref->{'os'}));
143 bat;
144 out ('</VENDOR>');
145 out ('<VERSION>');
146 tab;
147 out_av (gen_version($ref->{'os'}, $ref->{$SQL_DETAILS}));
148 bat;
149 out ('</VERSION>');
150 out_tag('FRAG_POLICY', gen_fragpolicy($ref->{'os'}, $ref->{$SQL_DETAILS}));
151 out_tag('STREAM_POLICY', gen_streampolicy($ref->{'os'}, $ref->{$SQL_DETAILS}));
154 sub out_attribute_map {
155 out('<ATTRIBUTE_MAP>');
156 for (keys %attr){
157 out('<ENTRY>');
158 out_tag('ID', $attr{$_});
159 out_tag('VALUE', $_);
160 out('</ENTRY>');
162 out('</ATTRIBUTE_MAP>');
166 sub gen_attribute_id {
167 ($_) = @_;
168 my $name;
169 /SSH/i and $name = 'ssh' or
170 $name = $_;
171 if(not defined $attr{$name}){
172 $attr{$name} = $ATTR_NUM++;
175 return $attr{$name};
179 sub gen_vendor {
180 my ($os) = @_;
181 $_ = $os;
182 /windows/i and return "Microsoft" or
183 /linux/i and return "Linux" or
184 return ucfirst $os;
186 sub gen_version {
187 my ($os, $details) = @_;
188 return $details;
190 sub gen_fragpolicy {
191 my ($os, $details) = @_;
192 /windows/i and return 'windows' or
193 /linux/i and return 'linux' or
194 /openbsd/i and return 'linux' or
195 /bsd/i and return 'BSD' or
196 /jetdirect/i and return 'BSD-right' or
197 /hp-ux/i and $details =~ /11/ and return 'First' or
198 /hp/i and return 'BSD' or
199 /mac/i and return 'First' or
200 /irix/i and return 'BSD' or
201 /aix/i and return 'BSD' or
202 /cisco/i and return 'Last' or
203 /vms/i and return 'BSD' or
204 /os\/2/i and return 'BSD' or
205 /osf/i and return 'BSD' or
206 /sun/i and $details =~ /4/ and return 'BSD' or
207 /sun/i and return 'First' or
208 /tru64/i and return 'BSD' or
209 /vms|vax/i and return 'BSD' or
210 return 'last';
213 sub gen_streampolicy {
214 my ($os, $details) = @_;
215 gen_fragpolicy($os, $details);
218 # generate PORT IPPROTO PROTOCOL (CONFIDENCE) APPLICATION (VERSION)_
219 sub out_services {
220 my ($ip) = @_;
221 my $sql = "SELECT $SQL_IP,$SQL_TIME, fingerprint, service, $SQL_MAC, os, $SQL_DETAILS FROM $DB_TABLE WHERE service LIKE 'SERVICE_%' AND $SQL_IP = ?";
223 my $sth = $DBH->prepare($sql);
224 $sth->execute($ip);
226 my ($ref, $port, $t, $proto, @r);
227 while ($ref = $sth->fetchrow_hashref()) {
228 out('<SERVICE>');
229 tab;
230 ($t, $port, @r) = split /:/, $ref->{'fingerprint'};
231 $ref->{'service'} =~ s/SERVICE_//;
232 $proto = lc $ref->{'service'};
233 if($port){
234 out('<PORT>');
235 tab;
236 out_av($port);
237 bat;
238 out('</PORT>');
240 out ("<!-- service $ref->{'service'} with fp $ref->{'fingerprint'} for $ref->{'ip'} are forthcoming: -->");
241 out ("<!-- $ref->{$SQL_MAC} $ref->{'os'}, '$ref->{$SQL_DETAILS}' -->");
242 out('<IPPROTO>');
243 tab;
244 out_av($proto);
245 bat;
246 out('</IPPROTO>');
248 if(defined $ref->{'os'}){
249 out('<APPLICATION>');
250 tab;
251 out_av($ref->{'os'});
252 if(defined $ref->{$SQL_DETAILS}){
253 out('<VERSION>');
254 tab;
255 out_av($ref->{$SQL_DETAILS});
256 bat;
257 out('</VERSION>');
259 bat;
260 out('</APPLICATION>');
263 bat;
264 out('</SERVICE>');
270 # extract <operating_system>ip, os Vendor, Version, frag_policy, stream_policy,
271 # & all services:
272 # <services><service><port><attribute_value/>
273 # IPPROTO, PROTOCOL <Confidence>
275 if(@ARGV){
276 $DATABASE = $ARGV[0];
278 out_hat;