Алгоритм выявления сетевых атак двух типов: DDoS и сканирование портов




В результате проведенных исследований нам удалось выявить закономерности, позволяющие на основании NetFlow-данных определить IP-адреса компьютеров, с которых проводятся DDoS-атаки и сканирование портов. На основании этих закономерностей, был разработан алгоритм обнаружения атак. Прежде чем сформулировать данный алгоритм уточним формат записи данных для потока:

· Дата и время начала потока

· Длительность потока (в секундах, с точностью до тысячных)

· Название протокола передачи

· IP-адрес и порт источника

· IP-адрес и порт назначения

· Количество переданных пакетов

· Количество переданных байтов

Разработанный алгоритм обнаружения атак типа DDoS и сканирования портов заключается в следующем:

1. Найти IP-адреса источников, которые генерируют большое количество потоков.

а) Если размер данных потоков очень короткий (44 байт), то происходит сканирование портов;

б) Если размер потоков больше 44 байт, то c данного IP-адреса возможно осуществляется атака типа DoS.

2. Найти IP-адреса источников, которые генерируют очень длинные потоки (длительностью свыше 5 минут). В этом случае на IP-адрес назначение может проводиться DoS-атака.

В случае если одновременно обнаружено множество IP-адресов, с которых производится DoS-атака, то возможно проводится атака типа DDoS.

Для любой сетевой атаки важно своевременное обнаружение для того, чтобы как можно быстрее принять меры по её нейтрализации. NetFlow-данные поступают с маршрутизатора периодически, в зависимости от выставленных нами настроек. В то же время необходим баланс между частотой сбора статистики по потокам и временем, необходимым для ее обработки. Поэтому решено было установить периодичность запроса NetFlow данных один раз в одну минуту.

Следует отметить, что NetFlow-статистика содержит информацию о уже завершившихся потоках. Поскольку поток считается активным в течение определенного времени по его завершению, то подобные завершившиеся потоки также необходимо считать активными.

Листинг скрипта

Скрипт выполняет обработку файлов NetFlow-коллектора nfdump, поступающего с граничного маршрутизатора СГАУ Cisco 6509, после чего формирует список подозрительных IP-адресов, занося их в базу данных MySQL и блокируя на защищаемых серверах при помощи брандмауэра iptables.

Сначала объявляются все необходимые для обработки переменные: массивы записей параметров потоков, учетные данные входа в базу MySQL, папки с файлами nfdump, временные данные. Далее выполняется поиск последнего файла nfdump (папка /var/cache/nfdump/), поступившего с маршрутизатора. Файл nfdump представляет собой данные по всем потокам, завершившимся за последнюю минуту минуту. Этот файл преобразуется из бинарного формата в текстовый и сохраняется в указанную папку на сервере. После этого открывается текстовый файл и построчно записывается в массив (lines). В каждой строке выделяются все параметры потока и записываются в отдельные массивы. Таким образом, под каждый параметр потока отводится отдельный массив, номер элемента которого соответсвует порядковому номеру потока в исходном файле nfdump. Также формируются два массива, содержащих в себе информацию о потоках, завершенных на защищаемых серверах 91.222.128.200 и 91.222.129.201. Эти два массива сортируются по IP-адресам источников для того, чтобы подсчитать число потоков, приходящихся на каждый IP-адрес. Выполняется подсчет числа потоков, и если на один IP-адрес приходится более 300 потоков, то данный адрес заносится в список подозрительных адресов, блокируюется брандмауэром iptables и заносится в базу данных MySQL. В конце блокировка снимается на те адреса, которые были заблокированы больше 5 минут назад. Адреса, которые были заблокированы, сохраняются в файле-отчете, где указывается IP-адрес и число потоков, приходящихся на него.

********************************************************

#!/usr/bin/perl

use 5.8.8; use strict; use warnings; use DBI;

 

my $hostname = "localhost";

my $database = "admin";

my $user = "admin";

my $password = "Rdhw89pF%lk9D&2";

my $dbh = 0;

my $sth = 0;

my $rc = 0;

 

my $path = "/var/cache/nfdump/"; #путь к файлам nfcapd.xxxxxxxxxxxx

my $path1 = "/root/DATA/";

 

#Исходные данные

my @lines = (); #массив строк с исходными данными

my $date = 0; #дата файла

my @time = (); #массив записей времени начала потоков

my @duration = (); #массив записей длительностей потоков

my @protocol = (); #массив записей названий протоколов потоков

my @srcIP = (); #массив записей адресов источников потоков

my @srcPort = (); #массив записей портов источников потоков

my @dstIP = (); #массив записей адресов назначения потоков

my @dstPort = (); #массив записей портов назначения потоков

my @packets = (); #массив записей числа переданных в потоке пакетов

my @bytes = (); #массив записей количества переданных байт в

my $fl = 0; #Число потоков

my $fl2 = 0; # #Число потоков для второго сервера

my @masIP = (); #Массив отсортированных IP-адресов

my @masIP2 = (); # #Массив отсортированных IP-адресов для второго сервера

my @masIPstream = (); #Массив отсортированных IP-адресов stream

my $count = 0; #Счетчик числа потоков

#Вторичные данные

my @mIP = ();

my @mIP2 = (); #

#Временные данные

my $i = 0;

###############

 

#поиск последнего файла

chdir $path;

my (@file_list) = glob "nfcapd.20*";

my $flowfile = 0;

$flowfile = $file_list[$#file_list];

##############################

#преобразование из формата nfdump в txt и копирование в директорию $path1

my $comand = 0;

$comand = "nfdump -r ".$path.$flowfile." >> ".$path1.$flowfile.".txt";

system $comand;

#$comand = "nfdump -r ".$path.$flowfile." >> /var/www/galcev/data/".$flowfile.".txt";

#system $comand;

$comand = "rm -f ".$path.$flowfile;

system $comand;

 

open(FileData,$path1.$flowfile.".txt"); #открытие файла с исходными данными

@lines = <FileData>; #запись в массив строк с исходными данными

close(FileData); #закрытие файла с исходными данными

 

for ($i = 1; $i < @lines-4; $i++) { #заполнение массивов исходных данных

 

if($lines[$i] =~ m/\d+\:\d+\:\d+\.\d+/g){ #поиск в строке времени

$time[$fl]=substr($lines[$i],pos($lines[$i])-length($&),length($&));

}

if($lines[$i] =~ m/\d+\.\d+/g){ #поиск в строке длительности потока

$duration[$fl]=substr($lines[$i],pos($lines[$i])-length($&),length($&));

}

if($lines[$i] =~ m/\w+/g){ #поиск в строке названия протокола

$protocol[$fl]=substr($lines[$i],pos($lines[$i])-length($&),length($&));

}

if($lines[$i] =~ m/\d+\.\d+\.\d+\.\d+/g){ #поиск в строке IP-адреса источника пакета

$srcIP[$fl]=substr($lines[$i],pos($lines[$i])-length($&),length($&));

}

if($lines[$i] =~ m/\:\d+/g){ #поиск в строке порта источника пакета

$srcPort[$fl]=substr($lines[$i],pos($lines[$i])-length($&)+1,length($&));

}

if($lines[$i] =~ m/\d+\.\d+\.\d+\.\d+/g){ #поиск в строке IP-адреса назначения

$dstIP[$fl]=substr($lines[$i],pos($lines[$i])-length($&),length($&));

}

if($lines[$i] =~ m/\:\d+/g){ #поиск в строке порта назначения

$dstPort[$fl]=substr($lines[$i],pos($lines[$i])-length($&)+1,length($&));

}

if($lines[$i] =~ m/\d+/g){ #поиск в строке числа пакетов в потоке

$packets[$fl]=substr($lines[$i],pos($lines[$i])-length($&),length($&));

}

if($lines[$i] =~ m/\d+\.\d+\s\w+|\d+/g){ #поиск в строке числа байтов в потоке

$bytes[$fl]=substr($lines[$i],pos($lines[$i])-length($&),length($&));

#ФИЛЬТР ПО АДРЕСУ IP4TV.RU(91.222.128.200) и сервер трансляций (91.222.129.201)

 

if ($dstIP[$fl] eq "91.222.128.200") {

push(@masIP2, [$srcIP[$fl],$time[$fl]]);

++($fl2);

}

if ($dstIP[$fl] eq "91.222.129.201") {

push(@masIP, [$srcIP[$fl],$time[$fl]]);

++($fl);

}

 

}

}

--($fl);

--($fl2);

#СТАТИСТИКА

 

#массив mIP - сортировка данных по IP-адресу источника

@mIP = sort {

($a->[0] cmp $b->[0])

} @masIP;

 

@mIP2 = sort {

($a->[0] cmp $b->[0])

} @masIP2;

#Формирование файла (IP-адрес источника;Число потоков > 300)

$count = 1;

open(IPToBan,">> /var/www/galcev/banIP.txt");

$dbh = DBI->connect("DBI:mysql:$database:$hostname", $user, $password)|| print IPToBan "Got error". $dbh->errstr."\n";

my $statement = 0;

 

for ($i = 1; $i < $fl; $i++) {

if ($mIP[$i-1][0] eq $mIP[$i][0]) {++($count);}

else {

if ($count > 300){

my $ipT = $mIP[$i-1][0];

 

$statement = "select ban('".$ipT."');";

print IPToBan substr($flowfile,13,2),"\.",substr($flowfile,11,2),"\.",substr($flowfile,7,4)," ",$mIP[$i-1][1]," ",$ipT," ",$count,"\n";

$sth = $dbh->prepare($statement);

$sth->execute;

if ($sth == 1){

$comand = "iptables -I fail2ban-galcev -s ".$ipT." -j DROP";

system $comand;

}

}

$count = 1;

}

}

 

my $ref = 0;

$statement = "SELECT id,INET_NTOA(ip) FROM banlist WHERE time<CURRENT_TIMESTAMP-300;";

$sth = $dbh->prepare($statement);

$sth->execute;

while ($ref = $sth->fetchrow_arrayref) {

$comand = "iptables -D fail2ban-galcev -s ".$$ref[1]." -j DROP";

system $comand;

my $stm = "DELETE FROM banlist WHERE id='".$$ref[0]."';";

$sth = $dbh->prepare($stm);

$sth->execute;

}

 

 

$rc = $sth->finish;

$rc = $dbh->disconnect;

close(IPToBan);

###########################################

open(IPToBan2,">> /var/www/galcev/banIP2.txt");

$count = 1;

for ($i = 1; $i < $fl2; $i++) {

if ($mIP2[$i-1][0] eq $mIP2[$i][0]) {++($count);}

else {

if ($count > 0){

print IPToBan2 substr($flowfile,13,2),"\.",substr($flowfile,11,2),"\.",substr($flowfile,7,4)," ",$mIP2[$i-1][1]," ",$mIP2[$i-1][0]," ",$count,"\n";

}

$count = 1;

}

}

close(IPToBan2);

####################################

exit(0);



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2017-04-03 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: