рефераты скачать
 
Главная | Карта сайта
рефераты скачать
РАЗДЕЛЫ

рефераты скачать
ПАРТНЕРЫ

рефераты скачать
АЛФАВИТ
... А Б В Г Д Е Ж З И К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Э Ю Я

рефераты скачать
ПОИСК
Введите фамилию автора:


Дипломная работа: Разработка и анализ эффективности средств отражения распределенных атак

findNodeData->SeqAckNumber = p->tcph->th_ack-1;

break;

case PACKET_TYPE_RST_FROM_SERVER:

findNodeData->SeqAckNumber = p->tcph->th_ack-1;

break;

case PACKET_TYPE_SYN_ACK:

findNodeData->SeqAckNumber = p->tcph->th_seq-1;

break;

}

После того, как определен тип пришедшего пакета, он передается в рассмотренный выше модуль TcpConnEstTimeChecker, функция TcpConnEstTimeChecker_ProcessPacket которого сообщает основному модулю о том, есть ли в данный момент атака или нет. Она может вернуть одно из двух следующих значений:

/*** Состояния атаки ***/

#define SYN_ATACK_IS_NOT_PRESENT 1

#define SYN_ATACK_IS_PRESENT 2

Далее идет проверка того, нужно ли сгенерировать какое-нибудь сообщение и изменить текущий режим работы. Это иллюстрируется следующим фрагментом кода:

if(checkerResult == SYN_ATACK_IS_PRESENT){

// Если атака только началась

if(tcpSynFloodData->workingMode == TCP_SYN_FLOOD_DETECTION){

// Генерируем сообщение 'Atack Started'

GenerateSnortEvent(NULL, GENERATOR_TCP_SYN_FLOOD, 0,0,0,3,SYNFLOOD_STARTED);

//изменяем режим

tcpSynFloodData->workingMode = TCP_SYN_FLOOD_PREVENTION;

}

}

else{

// Если атака только закончилась

if(tcpSynFloodData->workingMode == TCP_SYN_FLOOD_PREVENTION){

// генерируем сообщение "ATACK FINISHED"

GenerateSnortEvent(NULL, GENERATOR_TCP_SYN_FLOOD, 0,0,0,3,SYNFLOOD_FINISHED);

//изменяем режим

tcpSynFloodData->workingMode = TCP_SYN_FLOOD_DETECTION;

}

}

После этого идет проверка того, должен ли этот пакет быть обработан модулем предотвращения. Если это ACK пакет, пришедший от клиента, то он должен увеличить значение счетчика в статистике для данного клиента, а если это SYN пакет, то в зависимости от текущего режима работы модуля этот пакет либо будет пропущен, либо удален.

if(preventionResult == PREVENTION_PACKET_IS_BAD){

if(InlineMode()){

InlineDrop();

}

}

Как видно из приведенного фрагмента в случае "плохого" пакета осуществляется проверка того, в каком режиме работает Snort. Если в режиме inline, то доступен метод InlineDrop, который говорит Snort о том, что этот пакет пропускать нельзя. В качестве дальнейшего развития этого модуля возможна реализация активного ответа для Snort работающего в режиме простого обнаружения. В качестве такого активного ответа может быть рассылка серверу и клиенту RST пакетов для закрытия этого соединения.

Как отмечалось выше, исходные значения параметров для модуля задаются администратором в виде правила, которое имеет следующий вид:

#tcp_syn_flood:

# [0] - ip_server

# [1] - server_timeout_sec

# [2] - max_overdue_count

# [3] - max_overdue_count_diviation

# [4] - overdue_time_sec

# [5] - check_period_sec

pass tcp any any <> any any (tcp_syn_flood:172.20.24.20, 60, 10, 2, 5, 1;)

Конкретное значение параметра max_overdue_count можно определить с помощью соотношения (3.14) . Для этого сначала с помощью специальных утилит [22] необходимо найти значения интенсивности входящего потока и вероятности потери пакетов в сети.

Рассмотрим пример, когда интенсивность обращений к серверу λ равна 1000 заявок в секунду, вероятность потери пакетов в сети Pпп 0.01, значение 1/μ (отведенный на сервере таймаут ) примем равным 60 секундам, и количество попыток повторной передачи SYN+ACK пакетов  равным 2.

Подставив такие значения в соотношение (3.14) получим:

Т.е. значение параметра max_overdue_count в правиле Snort следует принять равным 24.

Описанная выше программная реализация модуля расширения функциональности для системы предотвращения вторжений Snort_inline может быть использована для защиты критичных ресурсов корпоративной сети. Для этого необходимо создать программно-аппаратный комплекс, представляющий из себя маршрутизатор на базе Linux системы с установленным IPS Snort_inline. Во время разработки модуля акцент делался на независимость от операционной системы, но на данный момент тестирование проводилось только на ОС Linux.

К достоинствам такой реализации можно отнести возможность использовать один комплекс для защиты нескольких серверов, т.к. параметры защиты для конкретного сервера задаются в отдельном правиле Snort, допустимое количество которых ограничено лишь вычислительными возможностями оборудования.


ВЫВОДЫ

На современном этапе развития информационных технологий всё больше проявляется зависимость эффективного функционирования государственных и коммерческих предприятий и организаций от безопасности и надёжности применяемых корпоративных информационно-телекоммуникационных систем. Среди основных требований, предъявляемых к таким системам, можно выделить необходимость обеспечения услуги доступности. В виду того, что одним из самых распространенных видов атак в современных сетях являются атаки типа отказа в обслуживании, которые при успешной реализации способны парализовать работу как отдельных серверов, так и целых сетей, проблема обеспечения доступности ресурсов является чрезвычайно актуальной для общедоступных информационных систем, в частности, сети Internet.

В настоящее время существуют различные механизмы обнаружения и противодействия TCP SYN атаке. Наиболее эффективным из них является метод SYN Cookies, однако он, как и все другие, имеет недостатки, такие как необходимость внесения соответствующих изменений в реализацию стека протоколов TCP/IP на защищаемом сервере, недостаточная эффективность обнаружения атаки из-за отсутствия методики выбора конкретных значений для параметров защиты. В связи с этим, проблема TCP SYN атак требует новых эффективных решений.

В результате проделанной работы была разработана методика обнаружения TCP SYN атаки, позволяющая обнаруживать атаку на ранних стадиях. В основе предложенной методики лежит математическая модель, описывающая обслуживание сервером потока заявок на установление TCP соединения. С помощью математического аппарата теории систем массового обслуживания находятся допустимые интервалы значений для количества полуоткрытых TCP соединений на сервере, работающем в нормальном режиме (при условии отсутствия атаки). В соответствии с этим методом, решение о начале атаки принимается в том случае, когда реальное количество полуоткрытых на сервере соединений выходит за пределы допустимого интервала. Для определения границ этого интервала необходимо получить значения таких параметров как: интенсивность входного потока заявок, время, в течение которого с заданной вероятностью заявка будет обслужена (время прихода ACK пакета), вероятность потери IP пакетов при передаче по сети, количество попыток повторного отправления сервером SYN + ACK пакетов, таймаут отведенный на сервере на установку TCP соединения и вероятность верного обнаружения атаки. Часть параметров можно определить, используя предложенные методики сбора данных, часть определяется настройками стека протоколов TCP/IP на защищаемом сервере.

К достоинствам разработанной методики можно отнести то, что она позволяет обнаружить атаку на начальном этапе, устойчива к резкому возрастанию интенсивности входного потока запросов к серверу, учитывает характеристики сети и защищаемого сервера.

Недостатком данной методики является то, что неисправности сетевого оборудования, в результате которых повышается вероятность потери пакета в сети, будут интерпретированы как TCP SYN атака.

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

К достоинствам такой реализации можно отнести возможность использовать один программно-аппаратный комплекс для одновременной защиты нескольких серверов, т.к. параметры защиты для конкретного сервера задаются в отдельном правиле Snort, допустимое количество которых ограничено лишь вычислительными возможностями оборудования. Так же модульная архитектура позволяет довольно легко менять реализации модуля предотвращения.

Разработанное решение направлено на защиту критических ресурсов корпоративной сети, таких как сервера прикладных сервисов (Web, электронная почта, службы аутентификации и т.д) от TCP SYN атак.

Перспективой дальнейших исследований является разработка адаптивного метода оценки входных параметров в реальном масштабе времени. Так же перспективным является рассмотрение возможности использования разработанной методики для противодействия атакам, направленным на исчерпание всей пропускной способности канала связи, а так же адаптации ее для противодействия другим DoS/DDoS атакам.


ПЕРЕЧЕНЬ ССЫЛОК

1.  Постанова Кабінету Міністрів України від 28.10.2004 р. №1452 "Про затвердження Порядку застосування електронного цифрового підпису органами державної влади, органами місцевого самоврядування, підприємствами, установами та організаціями державної форми власності"

2.  Закон України "Про електронні документи та електронний документообіг" від 22.05.2003 р.

3.  НД ТЗІ 1.1-003-99. ТЕРМІНОЛОГІЯ В ГАЛУЗІ ЗАХИСТУ ІНФОРМАЦІЇ В КОМП’ЮТЕРНИХ СИСТЕМАХ ВІД НЕСАНКЦІОНОВАНОГО ДОСТУПУ

4.  http://bezpeka.com

5.  http://www.virulist.com

6.  http://www.void.ru

7.  http://www.webinform.ru

8.  http://bugtraq.ru

9.  Приказ ДСТСЗИ СБУ 30.04.2004 N 31

10.  BSI.IT Baseline Protection Manual. Standard Security Measures. Version: October 2000

11.  RFC793 Transmission Control Protocol

12.  http://www.securityfocus.com/infocus/1729

13.  http://www.protocols.ru

14.  http://www.preferredtechnology.com

15.  http://www.iss.net

16.  Г.И. Ивченко. Теория массового обслуживания, М:Высшая Школа, 1982.

17.  RFC2616. Hypertext Transfer Protocol – HTTP/1.1.

18.  Д. Камер. Сети TCP/IP том 1, изд. дом "Вильямс" М-Санкт-Петербург-Киев 2003

19.  http://www.internettrafficreport.com/main.htm

20.  http://securitylab.ru

21.  Г.Корн, Т.Корн Справочник по математике для научных работников и инженеров М: "НАУКА",1968.

22.  Д.Л. Ясницкий. "Разработка методики раннего обнаружения и отражения распределённых атак типа "отказ в обслуживании"". Магистерская аттестационная работа. Харьков: ХНУРЭ, 2006

23.  Джей Бил и др. Snort 2.1. Обнаружение вторжений. 2-е изд. Пер. с англ. - М.: ООО "Бином-Пресс", 2006;

24.  Медведовский И.Д., Семьянов П.В., Платонов В.В. Атака через Internet.

25.  http://www.securityfocus.com

26.  Д.Л. Ясницкий, В.Д. Литовский, Р.В. Олейников. Методика раннего обнаружения TCP SYN атаки. Прикладная радиоэлектроника. Т.5, Харьков: ХНУРЭ, 2006.

27.  Snort-2.4.3 source code.

28.  http://kiev-security.org.ua

29.  http://www.sophist.demon.co.uk/ping

30.  http://www.citforum.ru

31.  www.computer.org/

32.  http://wiki.hping.org/172

33.  http://www.snort.org

34.  http://www.bsi.de/

35.  http://www.linuxsecurity.com


Приложение А

Исходный код модуля расширение функциональности для IPS Snort_inline

// Файл tcp_syn_flood.h

#ifndef __SP_TCP_SYN_FLOOD_H__

#define __SP_TCP_SYN_FLOOD_H__

// TcpSynFloodDefinitions

#define TcpSynFloodPreventionModulePtr void*

/*** Pluging working modes ***/

#define TCP_SYN_FLOOD_DETECTION1

#define TCP_SYN_FLOOD_PREVENTION2

/*** TcpSynFlood atack states ***/

#define SYN_ATACK_IS_NOT_PRESENT 1

#define SYN_ATACK_IS_PRESENT 2

/*** Supported packet types ***/

#define PACKET_TYPE_UNSUPPORTED 0

#define PACKET_TYPE_SYN_ACK 1

#define PACKET_TYPE_ACK 2

#define PACKET_TYPE_RST_FROM_SERVER 3

#define PACKET_TYPE_RST_FROM_CLIENT 4

#define PACKET_TYPE_SYN 5

/*** Prevention module checking packet results ***/

#define PREVENTION_PACKET_IS_OK 1

#define PREVENTION_PACKET_IS_BAD 2

void SetupTcpSynFlood();

#endif /* __SP_TCP_SYN_FLOOD_H__ */

// Файл tcp_syn_flood.с

#include <sys/types.h>

#include <stdlib.h>

#include <ctype.h>

#include "rules.h"

#include "decode.h"

#include "plugbase.h"

#include "parser.h"

#include "debug.h"

#include "util.h"

#include "plugin_enum.h"

#include "generators.h"

#include "event_wrapper.h"

#ifdef HAVE_STRINGS_H

#include "mstring.h"

#endif

#include "sp_tcp_syn_flood.h"

#include "tcp_conn_est_time_checker.h"

#include "tcp_syn_flood_prevention_stat.h"

/*

* setup any data structs here

*/

typedef struct _TcpSynFloodData

{

// the current mode of the plugin

int workingMode;

// the IP address of the server being protected

struct in_addr serverIP;

// tcp connection estimate time checker

TcpConnEstTimeChecker* timeChecker;

// prevention module

TcpSynFloodPreventionModulePtr preventionModule;

} TcpSynFloodData;

/* function prototypes go here */

static void TcpSynFloodInit(char *, OptTreeNode *, int);

static void TcpSynFloodRuleParseFunction(char *, OptTreeNode *);

static int TcpSynFloodCheckFunction(Packet *, struct _OptTreeNode *, OptFpList *);

/* internal functions prototypes */

int ParseIntElement(char* token, char *name);

void SetupTcpSynFlood()

{

/* map the keyword to an initialization/processing function */

RegisterPlugin("tcp_syn_flood", TcpSynFloodInit);

DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: TcpSynFlood Setup\n"););

}

static void TcpSynFloodInit(char *data, OptTreeNode *otn, int protocol)

{

// multiple declaration check

if(otn->ds_list[PLUGIN_TCP_SYN_FLOOD])

{

FatalError("%s(%d): Multiple tcpsynflood options in rule\n", file_name,

file_line);

}

// allocate the data structure and attach it to the

// rule's data struct list

TcpSynFloodData* tcpSynFloodData = (TcpSynFloodData*) SnortAlloc(sizeof(TcpSynFloodData));tcpSynFloodData->workingMode = TCP_SYN_FLOOD_DETECTION;

tcpSynFloodData->preventionModule = TcpSynFloodPreventionCreateModule();

otn->ds_list[PLUGIN_TCP_SYN_FLOOD] = tcpSynFloodData;

TcpSynFloodRuleParseFunction(data, otn);

// finally, attach the option's detection function to the rule's

// detect function pointer list

AddOptFuncToList(TcpSynFloodCheckFunction, otn);

}

/** Expected Rule Structure

# tcp_syn_flood:

# [0] - ip_server

# [1] - server_timeout_sec

# [2] - max_overdue_count

# [3] - max_overdue_count_diviation

# [4] - overdue_time_sec

# [5] - check_period_sec

*/

static void TcpSynFloodRuleParseFunction(

char *data,

OptTreeNode *otn)

{

int server_timeout_sec = 0;

int max_overdue_count = 0;

int max_overdue_count_diviation = 0;

int overdue_time_sec = 0;

int check_period_sec = 0;

TcpSynFloodData *tcpSynFloodData;

tcpSynFloodData = otn->ds_list[PLUGIN_TCP_SYN_FLOOD];

while(isspace((int)*data))

data++;

int numTokens;

const int TokensCount = 6;

char **tokens = mSplit(data, ",", TokensCount, &numTokens, 0);

printf("numtokens %d\n", numTokens );

if(numTokens != TokensCount)

{

FatalError("in TcpSynFlood rule: invalid number of init parameters\n");

}

if(inet_aton(tokens[0], &tcpSynFloodData->serverIP) == 0)

{

FatalError("in TcpSynFlood rule: %s is invalid ip address\n", tokens[0]);

}

server_timeout_sec = ParseIntElement(tokens[1], "server timeout");

max_overdue_count = ParseIntElement(tokens[2], "overdue count");

max_overdue_count_diviation = ParseIntElement(tokens[3], "overdue count diviation");

overdue_time_sec = ParseIntElement(tokens[4], "overdue time (in seconds)");

check_period_sec = ParseIntElement(tokens[5], "check period (in seconds)");

// init checker

TcpConnEstTimeChecker* checker = (TcpConnEstTimeChecker*)SnortAlloc(sizeof(TcpConnEstTimeChecker));

InitTcpConnEstTimeChecker(checker,

overdue_time_sec, // overdueTime

check_period_sec, // int _checkPeriod

max_overdue_count, // overdueUpperBound

max_overdue_count_diviation, // overdueUpperBoundDiviation

server_timeout_sec// serverTimeout

);

tcpSynFloodData->timeChecker = checker;

printf("TcpSynFlood module initialized with the following parameters:\n");

printf("\tserver timeout %d\n", server_timeout_sec);

printf("\tmax overdue count %d\n", max_overdue_count);

printf("\tmax overdue count diviation %d\n", max_overdue_count_diviation);

printf("\toverdue time %d\n", overdue_time_sec);

printf("\theck period %d\n", check_period_sec);

// free tokens memory

mSplitFree(&tokens, numTokens);

}

static int TcpSynFloodCheckFunction(

Packet *p,

struct _OptTreeNode *otn,

OptFpList *fp_list)

{

// Get Rule Data

TcpSynFloodData *tcpSynFloodData;

tcpSynFloodData = otn->ds_list[PLUGIN_TCP_SYN_FLOOD];

int packetType = GetPacketType(tcpSynFloodData->timeChecker, p, tcpSynFloodData->serverIP);

if(packetType != PACKET_TYPE_UNSUPPORTED)

{

// process ACK packets with prevention module

if(packetType == PACKET_TYPE_ACK)

{

printf("Processing ACK\n");

// check if atack is absent

int changeStat = (tcpSynFloodData->workingMode == TCP_SYN_FLOOD_DETECTION) ? CHANGE_STAT_YES : CHANGE_STAT_NO;

if(changeStat == CHANGE_STAT_YES)

{

// update statistics for "good" client

TcpSynFloodPreventionProcessPacket(tcpSynFloodData->preventionModule, p, changeStat);

}

} // process SYN packet with prevetntion module

else if(packetType == PACKET_TYPE_SYN)

{

printf("processing SYN\n");

// check if atack is present

if(tcpSynFloodData->workingMode == TCP_SYN_FLOOD_PREVENTION)

{

printf("processing SYN while attack is present\n");

// get packet status

int packetStatus = TcpSynFloodPreventionProcessPacket(tcpSynFloodData->preventionModule, p, CHANGE_STAT_NO);

if(packetStatus == PREVENTION_PACKET_IS_BAD)

{

printf("Processing bas SYN\n");

if(InlineMode())

{

InlineDrop();

}

// else {} // Another type of ActiveReply should be implemented

// For example sending RST packets to server and client

return 0;

}

}

}

// process packet with time checker

int checkerResult = TcpConnEstTimeChecker_ProcessPacket(tcpSynFloodData->timeChecker, p, packetType);

if(checkerResult == SYN_ATACK_IS_PRESENT)

{

// Check if atack has been started now

if(tcpSynFloodData->workingMode == TCP_SYN_FLOOD_DETECTION)

{

// Generate log message 'Atack Started'

GenerateSnortEvent(NULL, GENERATOR_TCP_SYN_FLOOD, 0,0,0,3,SYNFLOOD_STARTED);

//change mode

tcpSynFloodData->workingMode = TCP_SYN_FLOOD_PREVENTION;

}

}

else

{

// Check if atack has been finished now

if(tcpSynFloodData->workingMode == TCP_SYN_FLOOD_PREVENTION)

{

// Generate event log "ATACK FINISHED"

GenerateSnortEvent(NULL, GENERATOR_TCP_SYN_FLOOD, 0,0,0,3,SYNFLOOD_FINISHED);

//change mode

tcpSynFloodData->workingMode = TCP_SYN_FLOOD_DETECTION;

}

}

}// PACKET IS SUPPORTED

return fp_list->next->OptTestFunc(p, otn, fp_list->next);

}

int ParseIntElement(char* token, char *name)

{

char * tail;

int value = (int) strtol(token, &tail, 10);

if(*tail)

{

FatalError("in TcpSynFlood rule: %s is invalid %s.\n", token, name);

}

return value;

}

inline int GetPacketType(TcpConnEstTimeChecker* checker, Packet* p, struct in_addr ipServer)

{

// check IP address

struct in_addr ipSrc = p->iph->ip_src;

struct in_addr ipDst = p->iph->ip_dst;

u_int8_t flags = p->tcph->th_flags;

if((ipDst.s_addr == ipServer.s_addr) && ((flags ^ R_SYN) == 0))

{

return PACKET_TYPE_SYN;

}

if((ipSrc.s_addr == ipServer.s_addr) && ((flags ^ R_SYN ^ R_ACK) == 0))

{

return PACKET_TYPE_SYN_ACK;

}

else if((ipDst.s_addr == ipServer.s_addr) && ((flags ^ R_ACK) == 0))

{

return PACKET_TYPE_ACK;

}

else if((ipSrc.s_addr == ipServer.s_addr) && ((flags ^ R_RST) == 0))

{

return PACKET_TYPE_RST_FROM_SERVER;

}

else if((ipDst.s_addr == ipServer.s_addr) && ((flags ^ R_RST) == 0))

{

return PACKET_TYPE_RST_FROM_CLIENT;

}

return PACKET_TYPE_UNSUPPORTED;

}

// файл tcp_conn_est_time_checker.h

#ifndef __TCP_CONN_EST_TIME_CHECKER_H__

#define __TCP_CONN_EST_TIME_CHECKER_H__

#include <time.h>

#include <sys/time.h>

#include "config.h"

#include "decode.h"

#include "ubi_SplayTree.h"

typedef struct _TcpConnEstTimeChecker

{

/*** Rule Options ***/

// time in seconds after which the half-open connection is overdue

long overdueTime;

// period in seconds to check the number of overdue half-open connections

long checkPeriod;

// the max allowed number of half-open connections

int overdueUpperBound;

// the diviation of overdueUpperBound

int overdueUpperBoundDiviation;

/*** Internal Data ***/

// the number of root nodes in the array

int rootNodesCount;

// the array of root nodes

ubi_btRoot* rootNodes;

// the index of the first node, which contains overdued connections

int firstOverduedNodeIndex;

// time when the last shift was made

struct timeval lastShiftTime;

// Indicates if Syn Flood atack presents

int atackState;

}

TcpConnEstTimeChecker;

/*** Inerface ***/

void InitTcpConnEstTimeChecker(TcpConnEstTimeChecker* checker, long _overdueTime,

long _checkPeriod, int _overdueUpperBound,

int _overdueUpperBoundDiviation, long _serverTimeout);

void DeInitTcpConnEstTimeChecker(TcpConnEstTimeChecker* checker);

int TcpConnEstTimeChecker_ProcessPacket(TcpConnEstTimeChecker* checker, Packet* p, int packetType);

int ShiftRootNodes(TcpConnEstTimeChecker* checker, int GenerationCount);

#endif /* __SP_TCP_SYN_FLOOD_H__ */

// файл tcp_conn_est_time_checker.c

#ifndef __TCP_CONN_EST_TIME_CHECKER_H__

#include "tcp_conn_est_time_checker.h"

#endif

#include "sp_tcp_syn_flood.h"

#include <memory.h>

#include <math.h>

#include <stdlib.h>

#include "rules.h"

#include "util.h"

/********* States of Timechecker Tree Node Data ********/

#define NODE_STATE_SYN_RECEIVED 1

#define NODE_STATE_SYN_ACK_RECEIVED 2

typedef struct _TimeCheckerTreeNodeData

{

ubi_trNode Node;

// state of the node

int NodeState;

// Sequence number for client SYN packet

u_int32_t ClientNumber;

// Sequence number for server SYN+ACK packet

u_int32_t ServerNumber;

}

TChTreeNodeData;

/*** TChTreeNodeData manipulation functions ***/

static int TChTreeNodeDataCompareFunc(ubi_trItemPtr ItemPtr, ubi_trNodePtr NodePtr);

static void TChTreeNodeDataDeleteNode(ubi_btNodePtr NodePtr);

/*** TcpConnEstTimeChecker manipulation functions ***/

void InitTcpConnEstTimeChecker(TcpConnEstTimeChecker* checker, long _overdueTime,

long _checkPeriod, int _overdueUpperBound,

int _overdueUpperBoundDiviation, long _serverTimeout)

{

CheckInitParams(_overdueTime, _checkPeriod, _overdueUpperBound, _overdueUpperBoundDiviation,_serverTimeout);

checker->overdueTime = _overdueTime;

checker->checkPeriod = _checkPeriod;

checker->overdueUpperBound = _overdueUpperBound;

checker->overdueUpperBoundDiviation = _overdueUpperBoundDiviation;

// Get rootNodes count

double serverTimeout = _serverTimeout;

int rootNodesCount = ceil(serverTimeout / _checkPeriod);

checker->rootNodesCount = rootNodesCount;

printf("NODES COUNT %d\n", rootNodesCount);

// init the array of root nodes

checker->rootNodes = (ubi_btRoot*)SnortAlloc(sizeof(ubi_btRoot) * rootNodesCount);

// the index of the first node with overdued connections

checker->firstOverduedNodeIndex = checker->overdueTime / checker->checkPeriod;

int i;

for(i = 0; i < rootNodesCount; i++)

{

ubi_trInitTree(checker->rootNodes + i,/* ptr to the tree head */

TChTreeNodeDataCompareFunc, /* comparison function */

ubi_trDUPKEY);

//0); /* do not allow nither OVERWRITE nor DUPLICATES */

}

// get current time

struct timezone tz;

gettimeofday(&checker->lastShiftTime, &tz);

//time(&checker->lastShiftTime);

checker->atackState = SYN_ATACK_IS_NOT_PRESENT;

}

void DeInitTcpConnEstTimeChecker(TcpConnEstTimeChecker* checker)

{

int rootNodesCount = checker->rootNodesCount;

// delete trees

int i;

for(i = 0; i < rootNodesCount; i++)

{

ubi_trKillTree(checker->rootNodes + i, TChTreeNodeDataDeleteNode);

}

// delete array

free(checker->rootNodes);

checker->rootNodes = NULL;

}

long GetTimeDifference(struct timeval* time1, struct timeval* time2)

{

long secDiff =time1->tv_sec - time2->tv_sec;

long micSecDiff = time1->tv_usec - time2->tv_usec;

return labs(secDiff)*1000000 + labs(micSecDiff);

}

int TcpConnEstTimeChecker_ProcessPacket(TcpConnEstTimeChecker* checker, Packet* p, int packetType)

{

int i;

/*

// get current time

time_t curTime;

time(&curTime);

//check the time

int diff = difftime(curTime, checker->lastShiftTime);

*/

struct timeval currTime;

struct timezone zone;

gettimeofday(&currTime, &zone);

long diff = GetTimeDifference(&currTime, &checker->lastShiftTime);

if(diff >= checker->checkPeriod)

{

// shift trees

printf("shifting trees\n");

int generationsCount = ((float)diff) / checker->checkPeriod;

ShiftRootNodes(checker, generationsCount);

}

// is used as item to search

TChTreeNodeData* findNodeData = NULL;

// flag which indicates if the node is inserted successfully

ubi_trBool insertResult;

// if Syn add node to the tree

if(packetType == PACKET_TYPE_SYN)

{

printf("processing SYN packet in time checker \n");

TChTreeNodeData* newNodeData = (TChTreeNodeData*)SnortAlloc(sizeof(TChTreeNodeData));

ubi_trNodePtr nodePtr = &newNodeData->Node;

ubi_btInitNode(nodePtr);

// save sequence number and set NODE_STATE_SYN_RECEIVED

newNodeData->ClientNumber = p->tcph->th_seq;

newNodeData->NodeState = NODE_STATE_SYN_RECEIVED;

// trying to insert the node to the 0-th tree

insertResult =

ubi_trInsert(checker->rootNodes, nodePtr, (ubi_trItemPtr)newNodeData, NULL);

if(insertResult != ubi_trTRUE)

{

printf("failed to add SYN to the tree\n");

// there is already the node with the same key in the tree

free(newNodeData);

}

}

// if Syn + Ack

else if(packetType == PACKET_TYPE_SYN_ACK)

{

printf("processing SYN + ACK in time checker\n" );

// find the node that is corresponded to received SYN

findNodeData = (TChTreeNodeData*)SnortAlloc(sizeof(TChTreeNodeData));

findNodeData->NodeState = NODE_STATE_SYN_RECEIVED;

findNodeData->ClientNumber = p->tcph->th_ack - 1;

// run over all trees and try to find the node

for(i = 0; i < checker->rootNodesCount; i++)

{

TChTreeNodeData* foundNodeData = (TChTreeNodeData*)ubi_trFind(checker->rootNodes + i, findNodeData);

if(foundNodeData != NULL)

{

// remove node from tree

ubi_trRemove(checker->rootNodes + i, foundNodeData);

// set Acknowledgement number and update node state to NODE_STATE_SYN_ACK_RECEIVED

foundNodeData->NodeState = NODE_STATE_SYN_ACK_RECEIVED;

foundNodeData->ServerNumber = p->tcph->th_seq;

// insert node again in the tree

insertResult =

ubi_trInsert(checker->rootNodes + i, foundNodeData, (ubi_trItemPtr)foundNodeData, NULL);

if(insertResult != ubi_trTRUE)

{

// there is already the node with the same key in the tree

free(foundNodeData);

}

break;

}

}

free(findNodeData);

}

// if Ack or Resets

else if ((packetType == PACKET_TYPE_ACK) ||

(packetType == PACKET_TYPE_RST_FROM_SERVER) ||

(packetType == PACKET_TYPE_SYN_ACK))

{

TChTreeNodeData* findNodeData = (TChTreeNodeData*)SnortAlloc(sizeof(TChTreeNodeData));

switch(packetType)

{

case PACKET_TYPE_ACK:

printf("processing ACK packet\n");

findNodeData->NodeState = NODE_STATE_SYN_ACK_RECEIVED;

findNodeData->ClientNumber = p->tcph->th_seq - 1;

findNodeData->ServerNumber = p->tcph->th_ack - 1;

break;

/*

case PACKET_TYPE_RST_FROM_SERVER:

printf("processing RST from server\n");

findNodeData->SeqAckNumber = p->tcph->th_ack-1;

break;

case PACKET_TYPE_SYN_ACK:

printf("processing RST from client\n");

findNodeData->SeqAckNumber = p->tcph->th_seq-1;

break;

*/

}

// run over all trees and try to Find and Delete node with the given key

for(i = 0; i < checker->rootNodesCount; i++)

{

ubi_trNodePtr nodePtr = ubi_trFind(checker->rootNodes + i, findNodeData);

if(nodePtr != NULL)

{

// delete

ubi_trRemove(checker->rootNodes + i, nodePtr);

free((TChTreeNodeData*)nodePtr);

break;

}

}

free(findNodeData);

}

// check overdue connections count

printf("chekcing\n");

return CheckOverdueConnectionsCount(checker);

}

int ShiftRootNodes(TcpConnEstTimeChecker* checker, int generationCount)

{

int i;

if(generationCount > checker->rootNodesCount)

{

generationCount = checker->rootNodesCount;

}

// free old trees

for( i = (checker->rootNodesCount - generationCount); i < checker->rootNodesCount; i++ )

{

ubi_trKillTree(checker->rootNodes + i, TChTreeNodeDataDeleteNode);

}

// shift

memmove(checker->rootNodes + generationCount,

checker->rootNodes, (checker->rootNodesCount - generationCount) * sizeof(ubi_btRoot));

// init new trees

for(i = 0; i < generationCount; i++)

{

ubi_trInitTree(&checker->rootNodes[i],/* ptr to the tree head */

TChTreeNodeDataCompareFunc, /* comparison function */

ubi_trDUPKEY); /* allow duplicates */

}

struct timezone zone;

gettimeofday(&checker->lastShiftTime, &zone);

return 0;

}

int CheckOverdueConnectionsCount(TcpConnEstTimeChecker* checker)

{

int resCount = 0;

int i;

for(i = checker->firstOverduedNodeIndex; i < checker->rootNodesCount; i++ )

{

resCount += ubi_trCount(checker->rootNodes + i);

}

int currentlyAllowedBound;

if(checker->atackState == SYN_ATACK_IS_PRESENT)

{

// subtract diviation from the bound

currentlyAllowedBound = checker->overdueUpperBound - checker->overdueUpperBoundDiviation;

}

else

{

// add diviation to the bound

currentlyAllowedBound = checker->overdueUpperBound + checker->overdueUpperBoundDiviation;

}

// save current atack state

checker->atackState = (resCount > currentlyAllowedBound )? SYN_ATACK_IS_PRESENT : SYN_ATACK_IS_NOT_PRESENT;

printf("check overdued: %d - %d\n", currentlyAllowedBound, resCount);

return checker->atackState;

}

void CheckInitParams(int _overdueTime,int _checkPeriod,

int _overdueUpperBound, int _overdueUpperBoundDiviation,

int _serverTimeout)

{

if(_overdueTime < 0)

{

FatalError("TcpConnectionEstimateTimeChecker:: _overdueTime must be > 0\n");

}

if(_checkPeriod < 0)

{

FatalError("TcpConnectionEstimateTimeChecker:: _checkPeriod must be > 0\n");

}

if(_overdueUpperBound < 0)

{

FatalError("TcpConnectionEstimateTimeChecker:: _overdueUpperBound must be > 0\n");

}

if(_overdueUpperBoundDiviation < 0)

{

FatalError("TcpConnectionEstimateTimeChecker:: _overdueUpperBoundDiviation must be > 0\n");

}

if((_overdueUpperBound - _overdueUpperBoundDiviation) < 0)

{

FatalError("TcpConnectionEstimateTimeChecker:: (_overdueUpperBound - _overdueUpperBoundDiviation) must be > 0\n");

}

if((_overdueUpperBound + _overdueUpperBoundDiviation) > _serverTimeout)

{

FatalError("TcpConnectionEstimateTimeChecker:: (_overdueUpperBound + _overdueUpperBoundDiviation) must be < _serverTimeout\n");

}

if(_serverTimeout < 0)

{

FatalError("TcpConnectionEstimateTimeChecker:: _serverTimeout must be > 0\n");

}

if(_overdueTime > _serverTimeout)

{

FatalError("TcpConnectionEstimateTimeChecker:: overdue time can't be greater than server timeout\n");

}

if(_serverTimeout <= _checkPeriod)

{

FatalError("TcpConnectionEstimateTimeChecker:: _serverTimeout must be greater than _checkPeriod\n");

}

}

/* Returns -1 if A < B

Returns 1 if A > B

Returns 0 if A = B

At first Client number is checked.

Than if neccessary Server nubmer is checked

*/

static int TChTreeNodeDataCompareFunc(ubi_trItemPtr ItemPtr, ubi_trNodePtr NodePtr)

{

TChTreeNodeData *A = (TChTreeNodeData *) ItemPtr;

TChTreeNodeData *B = (TChTreeNodeData *) NodePtr;

if(A->ClientNumber < B->ClientNumber)return -1;

if(A->ClientNumber == B->ClientNumber)return 0;

else // check curr node state

if(B->NodeState == NODE_STATE_SYN_ACK_RECEIVED)

{

if(A->ServerNumber < B->ServerNumber) return -1;

if(A->ServerNumber == B->ServerNumber) return 0;

else return 1;

}

else // state is NODE_STATE_SYN_RECEIVED

{

return 1;

}

}

static void TChTreeNodeDataDeleteNode(ubi_btNodePtr NodePtr)

{

free(NodePtr);

}

// файл tcp_syn_flood_prevention_stat.h

#ifndef _TCP_SYN_FLOOD_PREVENTION_STAT_H_

#define _TCP_SYN_FLOOD_PREVENTION_STAT_H_

//#include "config.h"

#include "decode.h"

#include "sp_tcp_syn_flood.h"

#include "ubi_SplayTree.h"

#define CHANGE_STAT_YES 1

#define CHANGE_STAT_NO 2

typedef struct _TcpSynFloodPreventionModule

{

// the root of the statistics tree

ubi_btRootPtr rootStat;

long totalPacketsCount;

} TcpSynFloodPreventionModule;

// Creates and initializes the prevention module

void* TcpSynFloodPreventionStatCreateModule();

void TcpSynFloodPreventionStatDeinitModule(TcpSynFloodPreventionModule* preventionModule);

int TcpSynFloodPreventionStatProcessPacket(TcpSynFloodPreventionModule* preventionModule, Packet* packet, int changeStat);

// Unified Tcp Syn Flood prevention interface

#define TcpSynFloodPreventionProcessPacket( module, p, changeStat ) TcpSynFloodPreventionStatProcessPacket( (TcpSynFloodPreventionModule*) (module) ,(Packet*) (p), (int) (changeStat) )

#define TcpSynFloodPreventionCreateModule TcpSynFloodPreventionStatCreateModule

#define TcpSynFloodPreventionDeinitModule( module ) TcpSynFloodPreventionStatDeinitModule( (TcpSynFloodPreventionModule*) (module) )

#endif

// файл tcp_syn_flood_prevention_stat.c

#ifndef _TCP_SYN_FLOOD_PREVENTION_STAT_H_

#include "tcp_syn_flood_prevention_stat.h"

#endif

typedef struct _TcpSynFloodPreventionStatTreeNodeData

{

// the node in which data is stored

ubi_trNode Node;

// Fields to identify from what client the packet has came

u_int8_t ttl;

struct in_addr ipSrc;

// the number of packets with TTL=ttl and IPSrc=ipSrc that've been processed

long counter;

} TcpSynFloodPreventionStatTreeNodeData;

/*** TcpSynFloodPreventionStatTreeNodeData manipulation functions ***/

static int TcpSynFloodPreventionStatTreeNodeDataCompareFunc(ubi_trItemPtr ItemPtr, ubi_trNodePtr NodePtr);

static void TcpSynFloodPreventionStatTreeNodeDataDeleteNode(ubi_btNodePtr NodePtr);

void* TcpSynFloodPreventionStatCreateModule()

{

TcpSynFloodPreventionModule* newModule = (TcpSynFloodPreventionModule* )SnortAlloc(sizeof(TcpSynFloodPreventionModule));

newModule->totalPacketsCount = 0l;

int* a = (int*)SnortAlloc(10);

newModule->rootStat = (ubi_btRootPtr)SnortAlloc(sizeof(ubi_btRoot));

ubi_trInitTree(newModule->rootStat,/* ptr to the tree head */

TcpSynFloodPreventionStatTreeNodeDataCompareFunc, /* comparison function */

0); /* do not allow nither OVERWRITE nor DUPLICATES */

return newModule;

}

void TcpSynFloodPreventionStatDeinitModule(TcpSynFloodPreventionModule* preventionModule)

{

// kill tree

ubi_trKillTree(preventionModule->rootStat, TcpSynFloodPreventionStatTreeNodeDataDeleteNode);

free(preventionModule->rootStat);

free(preventionModule);

}

int TcpSynFloodPreventionStatProcessPacket(TcpSynFloodPreventionModule* module, Packet* packet, int changeStat)

{

// try to find

TcpSynFloodPreventionStatTreeNodeData* findNodeData = (TcpSynFloodPreventionStatTreeNodeData*)SnortAlloc(sizeof(TcpSynFloodPreventionStatTreeNodeData));

findNodeData->ipSrc = packet->iph->ip_src;

findNodeData->ttl = packet->iph->ip_ttl;

TcpSynFloodPreventionStatTreeNodeData* currNodeData = (TcpSynFloodPreventionStatTreeNodeData* )ubi_trFind(module->rootStat, findNodeData);

// update statistics

if(changeStat == CHANGE_STAT_YES)

{

if(currNodeData == NULL)

{

// add new node to the tree

TcpSynFloodPreventionStatTreeNodeData* newNodeData = (TcpSynFloodPreventionStatTreeNodeData*)SnortAlloc(sizeof(TcpSynFloodPreventionStatTreeNodeData));

newNodeData->ipSrc = findNodeData->ipSrc;

newNodeData->ttl = findNodeData->ttl;

ubi_trNodePtr newNodePtr = &newNodeData->Node;

ubi_trInsert(module->rootStat, newNodePtr, (ubi_trItemPtr)newNodeData, NULL);

currNodeData = newNodeData;

}

module->totalPacketsCount++;

currNodeData->counter++;

printf("stats is updated %d \n", currNodeData->counter);

}

free(findNodeData);

// Make the decision if the packet is bad

if(currNodeData == NULL) return PREVENTION_PACKET_IS_BAD;

double avg = 0;

double nodesCount = ubi_trCount(module->rootStat);

if(nodesCount != 0)

{

avg = module->totalPacketsCount / nodesCount;

}

if(currNodeData->counter >= avg)

{

printf("packet is OK\n");

return PREVENTION_PACKET_IS_OK;

}

else

{

printf("packet is BAD\n");

return PREVENTION_PACKET_IS_BAD;

}

}

/* Returns -1 if A < B

Returns 1 if A > B

Returns 0 if A = B */

static int TcpSynFloodPreventionStatTreeNodeDataCompareFunc(ubi_trItemPtr ItemPtr, ubi_trNodePtr NodePtr)

{

TcpSynFloodPreventionStatTreeNodeData *A = (TcpSynFloodPreventionStatTreeNodeData *) ItemPtr;

TcpSynFloodPreventionStatTreeNodeData *B = (TcpSynFloodPreventionStatTreeNodeData *) NodePtr;

if((A->ipSrc.s_addr == B->ipSrc.s_addr) && (A->ttl == B->ttl))

return 0;

else

{

if(A->ipSrc.s_addr < B->ipSrc.s_addr)

return -1;

else if(A->ipSrc.s_addr > B->ipSrc.s_addr)

return 1;

else

return (A->ttl < B->ttl ) ? -1 : 1;

}

}

static void TcpSynFloodPreventionStatTreeNodeDataDeleteNode(ubi_btNodePtr NodePtr){

free(NodePtr);

}


Приложение Б

Исходный код вспомогательной утилиты

Утилита предназначена для:

·  Извлечения из html страницы списка пингуемых хостов

·  Извлечение из логов пингования времени отклика

·  Анализ распределения полученных извлеченных значений времени

namespace pings{

class Class1{

public static void ExtractUrls(string FileName){

StreamReader sr = new StreamReader(FileName);

StreamWriter sw = new StreamWriter("run_pings.cmd");

string content = sr.ReadToEnd();

string pattern = @"href=.*""";

System.Text.RegularExpressions.MatchCollection matches = Regex.Matches(content, pattern );

foreach(Match match in matches){

string val = match.Value;

if(val.IndexOf("viacom.local") > -1) continue;

val = val.Replace("href=", "");

val = val.Replace("http://", "");

val = val.Replace(@"""", "");

val = val.Replace("/", "");

sw.WriteLine("ping " + Regex.Split(val, ":")[0]);

}

sr.Close();

sw.Close();

}

public static void ExtractPingTime(string FileName){

StreamReader sr = new StreamReader(FileName);

StreamWriter sw = new StreamWriter("extracted_time.txt");

string str;

int count = 0;

while((str = sr.ReadLine()) != null){

if(str != string.Empty){

string [] tokens = str.Split();

foreach(string token in tokens){

if(token.IndexOf("time=") > -1){

count ++;

sw.WriteLine(token.Replace("time=", "").Replace("ms", ""));

}

}

}

}

sr.Close();

sw.Close();

}

public static void Usage(){

Console.WriteLine("pings <option> <filename>");

Console.WriteLine(" option={url, time}");

}

[STAThread]

static void Main(string[] args){

if(args.Length == 2){

switch(args[0]){

case "url":

ExtractUrls(args[1]);

break;

case "time":

ExtractPingTime(args[1]);

break;

}

}

else{

Usage();

}

}

}

}


Страницы: 1, 2, 3, 4, 5


рефераты скачать
НОВОСТИ рефераты скачать
рефераты скачать
ВХОД рефераты скачать
Логин:
Пароль:
регистрация
забыли пароль?

рефераты скачать    
рефераты скачать
ТЕГИ рефераты скачать

Рефераты бесплатно, реферат бесплатно, рефераты на тему, сочинения, курсовые работы, реферат, доклады, рефераты, рефераты скачать, курсовые, дипломы, научные работы и многое другое.


Copyright © 2012 г.
При использовании материалов - ссылка на сайт обязательна.