return(0,"Cannot connect to database! ".DBI->errstr);
}
}
sub update_procedures{
my$procRef=shift;
my@procedures=@{$procRef};
my$dbh;
# connect to DB
my($rc,$err)=connect_to_DB(\$dbh);
if(!$rc){
return(0,'update_procedures can\'t connect do DB: '.$err);
}
foreachmy$proc(@procedures){
$dbh->do($proc);
}
# disconnect to DB
$dbh->disconnect;
return1;
}
sub send_query{
my$configRef=shift;
my$eventsRef=shift;
my@config=@{$configRef};
my%bad_events;
my($rc,$err);
my$dbh;
my$i=0;
# connect to DB
($rc,$err)=connect_to_DB(\$dbh);
if(!$rc){
return(0,'send_query can\'t connect do DB: '.$err);
}
while($i<scalar(@config)){
# run DB query -> requestor, client name
my$sth;
if(defined($config[$i]{query})){
$sth=$dbh->prepare($config[$i]{query});
}
else{
return(0,"No query availble\n");
}
if(!($sth->execute)){
return(0,"Couldn't get data from my database: $sth->errstr\n");
};
my@result;
my$contact;
my$msg_text=1;
while(@result=$sth->fetchrow()){
if(defined($config[$i]{contact})){
$contact=$config[$i]{contact};
if($msg_text){
$bad_events{$contact}.=$config[$i]{text}."\n\n";
$msg_text=0;
}
$bad_events{$contact}.=join(", ",@result)."\n";
}
else{
$contact="from_db\@$result[0]";
$bad_events{$contact}.=$config[$i]{text}."\n\n";
$bad_events{$contact}.=join(", ",@result)."\n";
}
}
foreachmy$key(keys%bad_events){
$bad_events{$key}.="\n\n";
}
$sth->finish;
$i++;
}
# disconnect to DB
$dbh->disconnect;
%$eventsRef=%bad_events;
return1;
}
sub run{
my$domain=shift;
my$period=shift;
my$date;
eval{
my$dt=DateTime->now();
$dt=DateTime->now()->subtract(days=>$period);
$date=$dt->date();
}ordo{
#print "Warden watchdog - can't work with date\n";
syslog("err|Warden watchdog - can't work with date\n");
};
# stored procedures
# iptest - is ip from private network
my@procedures=('DROP FUNCTION IF EXISTS iptest;','CREATE FUNCTION iptest(ip VARCHAR(15)) RETURNS TINYINT(1) DETERMINISTIC
BEGIN
SET @nip = INET_ATON(ip);
IF(
ISNULL( @nip) OR
@nip BETWEEN 0 AND 16777216 OR
@nip BETWEEN 167772160 AND 171966464 OR
@nip BETWEEN 2130706432 AND 2130706433 OR
@nip BETWEEN 2851995648 AND 2851995649 OR
@nip BETWEEN 2886729728 AND 2886729729 OR
@nip BETWEEN 3221225472 AND 3221225473 OR
@nip BETWEEN 3221225984 AND 3221225985 OR
@nip BETWEEN 3227017984 AND 3227017985 OR
@nip BETWEEN 3232235520 AND 3232235521 OR
@nip BETWEEN 3323068416 AND 3323068417 OR
@nip BETWEEN 3325256704 AND 3325256705 OR
@nip BETWEEN 3405803776 AND 3405803777 OR
@nip BETWEEN 3758096384 AND 3758096385 OR
@nip BETWEEN 4026531840 AND 4026531841 OR
@nip > 4294967295) THEN
RETURN TRUE;
ELSE
RETURN FALSE;
END IF;
END;');
# {query => ; text => ; contact => }
# Time of last event of each client.
# Is it unsupported type of event?
# Is event from the future?
# Martane - Is IP from the private network?
my@configuration=(
{query=>"SELECT hostname, service, MAX(received) FROM events WHERE valid = 't' GROUP BY hostname, service ORDER BY MAX(received) ASC;",text=>"Uvedeny klient, nebo klienti jiz delsi dobu nereportovali zadne udalosti do Wardenu. Je mozne, ze nefunguji spravne.",contact=>'jakubcegan@cesnet.cz, ph@cesnet.cz'},
{query=>"SELECT requestor FROM clients WHERE service IN (SELECT service FROM events WHERE detected > '$date' AND type NOT IN ('portscan', 'bruteforce', 'probe', 'spam', 'phishing', 'botnet_c_c', 'dos', 'malware', 'copyright', 'webattack', 'test', 'other') AND valid = 't' GROUP BY service) GROUP BY requestor;",text=>"Uvedeny klient, nebo klienti zasilaji nepodporovany nebo zastaraly typ udalosti na server Warden",contact=>'jakubcegan@cesnet.cz, ph@cesnet.cz'},
{query=>"SELECT hostname, service, type, COUNT(*) FROM events WHERE detected - received > 0 AND received > '$date' GROUP BY hostname, service, type;",text=>"Uvedeny klient, nebo klienti odesilaji odesilaji udalosti s casem z budoucnosti. Cas prirazeny serverem pri prichodu udalosti (received) musi byt vzdy roven nebo vetsi casu detekce (detected).",contact=>'jakubcegan@cesnet.cz, ph@cesnet.cz'},
{query=>"SELECT hostname, service, received, source, count(source) AS c, min(received), max(received) FROM events WHERE valid = 't' AND source_type = 'IP' AND iptest(source) GROUP BY hostname, service, source ORDER BY c DESC;",text=>"Uvedeni klient, nebo klienti odesilaji udalosti se zdrojovou adresou, ktera by se nemela objevit v internetu (privatni rozsah), nebo je neplatna (prazdny oktet, oktet je vetsi nez 255, apod.). kvuli omezeni verzi MySQL serveru funguje zatim pouze pro IPv6.",contact=>'jakubcegan@cesnet.cz, ph@cesnet.cz'});