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

Автор работы: Пользователь скрыл имя, 22 Февраля 2013 в 11:47, дипломная работа

Описание

Проблема с вредоносным программным обеспечением (далее ВПО) не является новой, точно также она не исчезнет в ближайшем будущем. Слишком много денег вложено теми людьми, которые используют трояны, вирусы и армии ботов, чтобы просто отказаться от их использования. Целью атак этого вредоносного программного обеспечения являются не только обычные пользователя домашних компьютеров, но и также пользователи корпоративных компьютеров.
Актуальность выполнения дипломного проекта по данной теме обусловлена фактом использования вредоносных программ для решения задач промышленного шпионажа.

Содержание

ВВЕДЕНИЕ 3
1 АНАЛИЗ УГРОЗ ВЫЧИСЛИТЕЛЬНОМУ ПРОЦЕССУ ПРЕДПРИЯТИЯ ОТ ВРЕДОНОСНОГО ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ 5
1.1 КЛАССИФИКАЦИЯ ВРЕДОНОСНОГО ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ 5
1.2 КАНАЛЫ РАСПРОСТРАНЕНИЯ ВРЕДОНОСНОГО ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ 6
1.3 ОПИСАНИЕ ПОПУЛЯРНЫХ ВИДОВ ВРЕДОНОСНОГО ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ 7
1.4 ОБЗОР ВПО НА ПРИМЕРЕ ВИРУСА WIN32.MANIAC.B 9
1.5 ПОСТАНОВКА ЗАДАЧИ НА ДИПЛОМНОЕ ПРОЕКТИРОВАНИЕ 12
2 МЕТОДЫ БОРЬБЫ С ВРЕДОНОСНЫМ ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ 13
2.1 КОНТРОЛЬ ПРИЛОЖЕНИЙ 13
2.2 ОРГАНИЗАЦИЯ КОНТРОЛЯ ПРИЛОЖЕНИЙ В СРЕДЕ WINDOWS 14
2.3 ОРГАНИЗАЦИЯ КОНТРОЛЯ ПРИЛОЖЕНИЙ В СРЕДЕ UNIX 16
2.4 ПРОАКТИВНЫЕ ТЕХНОЛОГИИ 16
2.5 АНТИВИРУСНАЯ ЗАЩИТА 18
2.6 ОРГАНИЗАЦИОННЫЕ МЕРЫ 20
3 РАЗРАБОТКА СИСТЕМЫ ПО ОБНАРУЖЕНИЮ ЗАПРЕЩЕННОГО И ВРЕДОНОСНОГО ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ 22
3.1 ПРОЦЕСС РАЗРАБОТКИ 22
3.2 ИСПОЛЬЗУЕМЫЕ ТЕХНОЛОГИИ В ХОДЕ РАЗРАБОТКИ 23
3.2.1 ТРАНСПОРТНЫЙ ПРОТОКОЛ UDP 23
3.2.2 СИГНАТУРНОЕ ОБНАРУЖЕНИЕ 24
3.2.3 ПРОЦЕССЫ В СРЕДЕ ОС UNIX 26
3.3 ПОИСК И СОЗДАНИЕ СИГНАТУРЫ 29
3.4 ПРИНЦИП РАБОТЫ РАЗРАБОТАННОЙ СИСТЕМЫ ПО ОБНАРУЖЕНИЮ ВПО LA_SERVER.PL И LA_CONSOLE.PL 30
РИСУНОК 17 – ДЕМОНСТРАЦИЯ РАБОТЫ LA_SERVER.PL И LA_CONSOLE.PL ПО ШИРОКОВЕЩАТЕЛЬНОМУ КАНАЛУ. 32
3.5 РАЗБОР РАБОТЫ СЕРВЕРНОЙ ЧАСТИ LA_SERVER.PL 33
3.5 РАЗБОР РАБОТЫ КЛИЕНТСКОЙ ЧАСТИ LA_CONSOLE.PL 40
ЗАКЛЮЧЕНИЕ 46
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ 47
ПРИЛОЖЕНИЯ 48

Работа состоит из  1 файл

мой_диплом_se.doc

— 1.87 Мб (Скачать документ)

 

Рисунок 13 – Трассировка ИЭ при помощи strace

 

Рисунок  14 – Открытие ИЭ редактором the.

 

Следующий шаг - это дизассемблирование ИЭ. На рисунке 15 показан участок, где ИЭ вызывает команду rm –fr /etc/passwd через функцию execve().

 

 Рисунок 15 – Дизассемблирование первого варианта ИЭ.

 

На снимке значение 409 - это смещение в байтах от начала файла и до искомой сигнатуры, а расстояние от 409 до 440 - это размер сигнатуры равный 55 байт. Ассемблерные команды mov в данном случаи передают аргументы функции execve() в регистр esp, а команда call как раз вызывает функцию execve(“rm –fr /etc/passwd”).

Сигнатура уже найдена, теперь необходимо создать ее контрольную сумму по md5, для этого был разработан скрипт sign_create.pl, который приведен в приложении Б.

По результату работы скрипта, была получена контрольная сумма и записана в файл базы сигнатур в виде:

 

87918881bc8bd3c24f07615650544ab8 1033 55 Unix.PwdFIle.Removed

 

Формат записи сигнатуры: MD5-сумма\tсмещение\tразмер\tописание.

 

На рисунке 16 приведен результат дизассемблирования второго ИЭ, который отличается от первого, следовательно и md5 сумма сигнатуры будет иной. В этом случаи длина сигнатуры равна 50 байт, а контрольная сумма выглядит так c35b002c0d68e5caa3605cbd2ffed100.

 

Рисунок 16 – Дизассемблирование второго варианта ИЭ.

3.4 Принцип работы разработанной системы по обнаружению ВПО la_server.pl и la_console.pl

Сетевое взаимодействие. На РС администратора сети устанавливается клиентская часть la_console.pl, а на остальные РС в сети устанавливается la_server.pl. Эти два приложения взаимодействуют между собой по UDP протоколу, а именно: приложение la_server.pl после сканирования локальной РС в случае обнаружения ВПО или запрещенного ПО устанавливает связь с РС на которой запущен la_console.pl использую широковещательный канал под UDP и передает полученные данные. Так же при первом запуске la_server.pl делает запрос update к console.pl с целью скачать новые базы сигнатур.

За организацию передачи данных по UDP отвечают функции udp_server() net_send(), udp_client(). Функция udp_server() слушает заданный порт переменной $src_pserver и выполняет действия согласно условию при поступлении определенных команд:

- !cmd – вернуть вывод команды оболочки shell;

- iplist – вернуть вывод команды uname;

- update – обратиться к РС с la_console.pl за обновлением баз сигнатур.

Функция udp_client() отправляет данные переданные в качестве аргумента.

Функция net_send() использует функцию udp_client() для отправки данных, но при этом если данные превышают MTU, эта функция их разбивает, добавляя к каждому пакету свой заголовок, таким образом если в адрес la_console.pl приходит много данных с разных РС сети, он собирает все пакеты воедино, используя переданный заголовок. Заголовок представляет собой номер пакета и уникальную контрольную сумму.

Сценарии la_client.pl и la_server.pl сами по себе работают как сервер так и клиент. В ходе их запуска выполняется вызов функции fork(), которая ответвляет дочерний процесс, в итоге получается родительский процесс и дочерний. Родительский процесс выступает в роли сервера, а дочерний в роли клиента в случае с la_server.pl, а в случае с la_console.pl наоборот.

Механизмы поиска la_sevrer.pl. Функция generic_fs_md5() осуществляет рекурсивный поиск по файловой систему сохраняя в хэш свойства файла и его контрольную сумму по md5.

Функция proc_mon() мониторит текущие процессы и появление новых процессов используя procfs (/dev/proc). Через procfs эта функция получат путь к файлу процесса (запущенное приложение), после чего получает его свойства stat() и контрольную сумму md5.

Функция compare() делает сравнение контрольных сумм файлов найденного с базой сигнатур.

Используемые  команды. Административная часть la_console.pl поддерживает следующие команды:

- use использовать заданный IP для выполнения комманд оболочки;

- !cmd - выполнение комманд на серверах указанных в use;

- show - показать заданные IP опцией use;

- scan - сканировать фс  в заданном окружении;

- iplist - вывести опрошенных  по UDP бродкасту хостов

- update - обновить базы сигнатур

 

На рисунке 17 приведен пример взаимодействия la_server.pl и la_console.pl, используя широковещательный канал.

Интерфейс разработанной  программы представляет собой консоль  и изображен на рисунке 18.

Рисунок 17 – Демонстрация работы la_server.pl и la_console.pl по широковещательному каналу.

 

 

Рисунок 18 – Консольный интерфейс la_console.pl и отправленный результат обнаружения ВПО.

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

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

Настоящая разработка не так эффективна, как скажем тот же бесплатный антивирус clamav, но сама по себе оригинальна и в случае, если попадется элемент ВПО, который по своему стандарту будет искать известные антивирусы среди запущенных процессов, эта разработка ему знакома не будет, и в случае имения сигнатуры, ВПО будет обнаружено.

3.5 Разбор работы серверной части la_server.pl

Для детального понимая  принципа работы серверной части la_server.pl ниже приведен исходный код сценария с описанием функций и взаимодействия оных между собой.

Ниже первая строка определяет местоположение интерпретатора Perl, далее подключаются 2е прагмы strict (отслеживает не безопасные конструкции Perl) и warnings (отвечает за предупреждение в случае нарушения синтаксиса).

 

#!/usr/bin/perl

 

use strict;

use warnings;

 

### --- Используемые  модули --- ###

# работа с  сокетами

use Socket;

# рекурсивный  поиск файлов и каталогов

use File::Find;

# генерация md5 хэша

use Digest::MD5 "md5_hex";

### ---/ ###

 

Через our, ниже объявлены глобальные переменные, которые можно изменять. Под изменения попадают только следующие переменные : $sdbf, $tim, $scan_path_fs, $MTU, $DSZ, $src_pserver, $dst_pserver.

 

# файл сигнатур

our $sdbf = "sign.txt";

# таймаут сканирования

our $tim = 9;

# ХЕШ формата  файл-stat()

our %fhs;

# загрузившиеся сигнатуры

our %sign;

# путь по  умолчанию для сканирования ФС

our $scan_path_fs = '/home/n4n/my_diplom/src/test_files';

# Maximum Transmission Unit

our $MTU = 1500;

# Размер данных  без своего заголовка

our $DSZ = 1472;

# локальный  порт

our $src_pserver = 7777;

# удаленный  порт

our $dst_pserver = 7778;

 

Приведенная ниже функция main() является главной функцией, из нее вызываются все остальные функции, содержащиеся в сценарии. Начало ее начинается с вызова функции fork(), которая порождает дочерний процесс, эта сделано для того что бы сценарий работал одновременно как сервер, так и клиент.

В случае сценария la_server.pl, родительский процесс производит сканирования ФС при помощи функции generic_fs_md5() и мониторинг процессов при помощи функции proc_mon(), но перед первым запуском производиться скачка новых баз сигнатур, отправляя при помощи функции udp_client() команду update. Последнюю функцию которую вызывает родительский процесс, является compare(), она производит сравнения полученных ранее вызванными функциями данные и сравнивает сигнатуры с подгруженной базой. Эти полученные данные функциями generation_fs_md5() и proc_mon() помещаются с хэш.

Дочерний процесс в  свою очередь работает сервером. Его  серверная часть ожидает команды  от сценарий la_console.pl и в зависимости от команд, ответ возвращается функцией net_send().

 

# точка входа

main:

{

# ответвляем  процесс средствами fork()

die " *ERR: fork()\n" unless (defined(my $pid = fork()));

 

# родительский процесс

# эта часть  кода делает сканирование ФС и мониторинг процессов

if($pid == 0)

{

# открыть базу  сигнатур и поместить в хеш

my $tm_str; if( !($tm_str = _read_file($sdbf)) )

{

# в случае неудачи, сделать запрос на root-консоль для ее получения

print "[-] База сигнатур  не найдена\n";

udp_client('update');

 

foreach my $str( split /\n/, $tm_str )

{

my ( $x, $y ) = split /\t/, $str;

$sign{$x} = $y;

}

 

do

{

# сканироние ФС

generic_fs_md5($scan_path_fs);

# мониторинг используемых  файлов процессом

proc_mon();

# сравнение md5

compare();

} while(sleep $tim);

 

exit;

}

# потомок

# эта часть  кода обрабатывает полученные  сообщения от администратора

else

{

print "[~] Start UDP server...\n";

udp_server();

exit;

}

}

 

# Разбить данные  на части равные MTU для сети ethernet

sub net_send

{

my ( $data, $count, $len_data, $chksum, @pos, @data_spliting ) = ( shift, 0 );

print ">> $data <<\n";

# сгенерить  чексумму для пакета

$chksum = generic_pwd(7);

# размер данных

$len_data = length($data);

 

if( $len_data <= $DSZ )

{

udp_client($data);

}

# реформировать  пакет

else

{

@data_spliting  = split //, $data;

for(my $i = 0; $i <= $#data_spliting; $i += $DSZ)

{

push @pos, $i;

}

 

push @pos, $len_data if ( $#pos < $len_data );

}

 

my ( $j, $k, @packets );

for( $j = 0, $k = 1; $k <= $#pos; $k++ )

{

my $pkt = join("", @data_spliting[$pos[$j] .. $pos[$k]-1]);

push @packets, $pkt;

$j++;

}

 

foreach my $send ( @packets )

{

my $send_cpy = $send;

$count += 1;

 

if( ($count == 1) || ($count > 1 && $count < $#packets) )

{

$send = "<s:$chksum:$send_cpy:$count>";

}

else

{

$send = "<s:$chksum:$send_cpy:$count>";

}

 

udp_client($send);

}

}

 

#

sub udp_client

{

# Отправляемые  данные

my $data = shift;

# Открыть сокет

socket( SOCKET, PF_INET, SOCK_DGRAM, getprotobyname("udp") ) or die "Error: can't create an udp socket: $!\n";

# Отключить буферизацию для дескриптора SOCKET

select( ( select(SOCKET), $|=1 )[0] );

# Сформировать пару IP:PORT для сокета

my $broadcastAddr = sockaddr_in( $dst_pserver, INADDR_BROADCAST );

# Установить опцию сокета SO_BROADCAST

setsockopt( SOCKET, SOL_SOCKET, SO_BROADCAST, 1 );

# Отправка данных

send( SOCKET, $data, 0,  $broadcastAddr ) or die "Error at sendding: $!\n";

# Закрытие сокета

close SOCKET;

}

 

#

sub udp_server

{

socket( UDPSOCK, PF_INET, SOCK_DGRAM, getprotobyname('udp') ) or die "socket: $!";

select( ( select(UDPSOCK), $|=1 )[0] ); # no suffering from buffering

 

setsockopt( UDPSOCK, SOL_SOCKET, SO_BROADCAST, 1 ) or die "setsockopt SO_BROADCAST: $!";

 

# my $broadcastAddr = sockaddr_in( $udp_port, INADDR_BROADCAST );

my $broadcastAddr = sockaddr_in( $src_pserver, INADDR_ANY );

bind( UDPSOCK, $broadcastAddr ) or die "bind failed: $!\n";

 

my $in;

while( my $addr = recv( UDPSOCK, $in, $MTU, 0 ) )

{

my ( $r_port, $r_addr ) = unpack_sockaddr_in($addr);

my $cmd_buffer;

 

print  inet_ntoa($r_addr) . " : $r_port   $in\n";

 

if($in eq 'iplist')

{

 

# вернуть о  системе, ос, проц..

$cmd_buffer = `uname -s -n -r -o`;

net_send($cmd_buffer);

}

elsif($in =~ /^cmd/)

{

$in =~ s/^cmd://;

$cmd_buffer = join("", `$in`);

net_send($cmd_buffer);

}

elsif($in =~ /^update/)

{

$in =~ s/^update//;

_write_file($sdbf, $in);

}

}

}

 

# поиск файлов, можно по маске

sub generic_fs_md5

{

my ( $path, $mask ) = @_;

find

(

sub

{

return unless -r;

return if( $mask && $_ !~ /$mask$/ );

 

open FH, $_ or warn "$path/$_ : $!";

my $file;

while(my $str = <FH>)

{

$file .= $str;

}

close FH;

 

@{$fhs{"$path/$_"}}{qw/md5 uid gid size atime mtime/} =

file_stat("$path/$_");

},

$path

);

}

 

# мониторинг процессов

sub proc_mon

{

opendir DH, "/proc" or die $!;

foreach my $d ( readdir( DH ) )

{

next if $d !~ /[0-9]/;

#$pid{$d} = _read_file("/proc/$d/cmdline");

if(my $pfname = _read_file("/proc/$d/cmdline"))

{

@{$fhs{$pfname}}{qw/md5 uid gid size atime mtime/} =

file_stat($pfname) if -r $pfname;

}

}

close DH;

}

 

# генерация случайного пароля

sub generic_pwd

{

my ( $size, @char, $pwd ) = shift;

@char = ('a'..'z','A'..'Z','0'..'9','_');

$pwd = '';

 

while(length($pwd) < $size)

{

$pwd .= $char[int rand @char];

}

 

return $pwd;

}

 

# получить информацию  по файлу

sub file_stat

{

my ( $file, @info ) = shift;

 

push @info, Digest::MD5::md5_hex( _read_file($file) );

push @info, (stat($file))[4,5,7,8,9];

# формат: md5, uid, gid, size, atime, mtime

return @info;

}

 

# сравнение

sub compare

{

my $report;

foreach my $smd5 ( keys %sign )

{

foreach my $f ( keys %fhs )

{

$report .= "[FOUND] $f $sign{$smd5}\n" if ($smd5 eq $fhs{$f}{'md5'});

}

}

if($report)

{

net_send($report);

undef($report);

}

}

 

# вернуть содержимое файла

sub _read_file

{

open RFH, shift or return 0;

my $src;

while(read(RFH, my $buf, $DSZ)) { $src .= $buf; }

close RFH;

$src = 0 unless $src;

return $src;

}

 

# записать в файл

sub _write_file

{

my( $file, $data ) = @_;

open WFH, ">$file" or return 0;

print WFH $data;

close WFH;

}

 

sub avscan

{

my ( $file, $sdb ) = @_;

 

my %dbf;

my $vir;

 

# читаем файл  с сигнатурами в память

open DBF, $sdb or die $!;

while(my $str = <DBF>)

{

chomp $str;

my ( $md5, $offset, $length, $desc ) = split /\t/, $str;

$dbf{$md5}{'offset'} = $offset;

$dbf{$md5}{'length'} = $length;

$dbf{$md5}{'descriptions'} = $desc;

}

close DBF;

 

# для быстрого  поиска помещаем элемент ВПО  в память

open VIR, $file or die $!;

$vir .= $_ while(<VIR>);

close VIR;

 

# разбиваем  посичволно и помещаем в массив

my @el = split //, $vir;

undef($vir);

 

# сам поиск сигнатуры

foreach my $k ( keys %dbf )

for(my $j = 0; $j <= ($#el - $dbf{$k}{'length'}); $j++)

{

my $st = $j;

my $ed = ($j+$dbf{$k}{'length'}-1);

$vir = join("",@el[$st .. $ed]);

if( Digest::MD5::md5_hex($vir) eq $k )

{

return "File 'file' infected $dbf{$k}{'descriptions'}\n";

exit; } } } }

3.5 Разбор работы клиентской части la_console.pl

Для детального понимая принципа работы клиентской части la_console.pl ниже приведен исходный код сценария с описанием функций и взаимодействия оных между собой.

Ниже первая строка определяет местоположение интерпретатора Perl, далее подключаются 2е прагмы strict (отслеживает не безопасные конструкции Perl) и warnings (отвечает за предупреждение в случае нарушения синтаксиса).

 

#!/usr/bin/perl

use warnings;

use strict;

 

#

# Консоль упровления 

#

 

### --- Используемые  модули --- ###

# работа с  сокетами

use Socket;

 

Ниже перечислины глобальные переменные, изменять можно только переменные $sdbf, $src_pserver, $dst_pserver.

 

### --- Глобальные  переменные --- ###

# файл базы  сигнатур

our $sdbf = "sign.dbf";

# локальный  порт 

our $src_pserver = 7778;

# удаленный порт

Информация о работе Разработка подсистемы сканирования корпоративной сети на наличие запрещенных к использованию программ