ELK: Анализ почтовых журналов. Подготовка

ELK: Анализ почтовых журналов. Подготовка
Продолжим тематику визуального анализа журналов. С журналов доступа в сеть Интернет переключимся на почтовые.
Начнем с получения журналов с почтового сервера и их подготовку к передаче ELK.
Так получилось, что в моей сети в качестве внутреннего почтового сервера используется  Microsoft Exchange 2003 . Каким-то неведомым мне образом, раз в сутки в почту падает файл с архивом почтового журнала сервера за предыдущий день. Мы пытались настоять на том, чтобы журналы отправлялись по протоколу syslog c помощью snare , но в этом было отказано под "уважительным" предлогом "высокой чувствительности пользователей к минимальным задержкам в работе сервиса".
Сначала письмо, как и множество других, проходит через  procmail . Оно попадает под действие правила:
 :0:  
* ^Subject(.*Exchange log file*)
{
:0 Bcw
| /home/sa/bin/logs/ExtractAttachment.pl
:0 a
| /home/sa/bin/logs/ImportMaillog.pl
:0
inbox/mailstat/.
}

Скрипт "/home/sa/bin/logs/ExtractAttachment.pl" является вариантом этого скрипта.
За скрипт "home/sa/bin/logs/ImportMaillog.pl" не судите строго. Он писался в режиме "быстрее хоть что-нибудь" и сейчас исправлять его не хочется, потому-что "работает!".
 use strict;  
use Encode qw(decode);
use Time::Local;
use Sys::Syslog;
use open qw(:std :utf8);
my $configfile = "/home/sa/bin/logs/rcfile";
my $conf = new Config::General("$configfile");
my %config = $conf->getall;
open (FILE, "<:encoding(utf8)", "/tmp/maillog.tmp") or die "Can't open file /tmp/maillog.tmp!
";
open (OFILE, ">/tmp/maillog") or die "unable to open /tmp/maillog !";
openlog("Secure_Maillog", "ndelay", "local0");
while (<FILE>) {
s/<>/postmaster@udmurtneft.ru/g;
my @str = split(/t/);
my $str18 = "";
if ( $str[8] =~ /102[80]/ ) {
if ( $str[18] =~ /=?/ ) {
$str[18] =~ s/UNICODE-1-1-UTF-8/UTF-8/g;
$str[18] =~ s/unicode-1-1-utf-7/UTF-8/g;
$str[18] =~ s/x-user-defined/UTF-8/g;
$str[18] =~ s/gb18030/windows-1251/g;
$str[18] =~ s/window-1251/windows-1251/g;
$str[18] =~ s/UNKNOWN/windows-1251/g;
$str[18] =~ s/134/windows-1251/g;
my $flag = utf8::is_utf8($str[18]);
$str[18] = Encode::decode('MIME-Header',$str[18]);
$str18 = $str[18];
}
$str[1] =~ s/ GMT//g;
my $time = $str[0]." ".$str[1];
my @t = ($time =~ /^(d{4})-(d{1,2})-(d{1,2})s(d{1,2}):(d{1,2}):(d{1,2})/);
$t[1]--; $t[3] = $t[3]+4;
if ( $t[3] > 23 ) { $t[3] = $t[3] - 24 };
my $timestamp = timelocal 0,@t[4,3,2,1,0];
print OFILE "t$timestampt$str[19]t$str[7]t$str[12]t$str[18]
";
syslog('mail|info', $timestamp."t".$str[19]."t".$str[7]."t".$str[12]."t".$str[18]);
}
}
closelog();
close(OFILE);
system("mysqlimport --local logs /tmp/maillog --user=$config{db}->{user} --password=$config{db}->{password}");
unlink("/tmp/maillog.tmp");
unlink("/tmp/maillog");
unlink("/tmp/report.zip");
Важные строки выделены жирным. Первая из них передает строку журнала в syslog, а оттуда в logstash. Вторая записывает в олдскульный sql для тяжелого анализа.
В следующий раз, чтобы разбавить тему анализа глазами. рассмотрим что можно достать из SQL.
PS. Если вы захотите отметить, что хранить временные файлы в общей директории /tmp не безопасно, то ответа будет два:
1. На сервере, куда падают журналы, все пользователи имеют доступ к ним.
2.
 $ cat /etc/profile | grep umask  
umask 077

Alt text

Не ждите, пока хакеры вас взломают - подпишитесь на наш канал и станьте неприступной крепостью!

Подписаться

Сергей Солдатов

REPLY-TO-ALL is a double language blog (English/Russian) run by three information security practitioners. Want to discuss information security problems? This is the place.