PROTÓTIPO DE SOFTWARE DE SEGURANÇA EM REDES …... iii Dedico este trabalho aos meus pais, Oscar e...

126
UNIVERSIDADE REGIONAL DE BLUMENAU CENTRO DE CIÊNCIAS EXATAS E NATURAIS CURSO DE CIÊNCIAS DA COMPUTAÇÃO (Bacharelado) PROTÓTIPO DE SOFTWARE DE SEGURANÇA EM REDES PARA A MONITORAÇÃO DE PACOTES EM UMA CONEXÃO TCP/IP TRABALHO DE CONCLUSÃO DE CURSO SUBMETIDO À UNIVERSIDADE REGIONAL DE BLUMENAU PARA A OBTENÇÃO DOS CRÉDITOS NA DISCIPLINA COM NOME EQUIVALENTE NO CURSO DE CIÊNCIAS DA COMPUTAÇÃO — BACHARELADO PAULO FERNANDO DA SILVA BLUMENAU, DEZEMBRO/2001. 2001/2-38

Transcript of PROTÓTIPO DE SOFTWARE DE SEGURANÇA EM REDES …... iii Dedico este trabalho aos meus pais, Oscar e...

UNIVERSIDADE REGIONAL DE BLUMENAU

CENTRO DE CIÊNCIAS EXATAS E NATURAIS

CURSO DE CIÊNCIAS DA COMPUTAÇÃO

(Bacharelado)

PROTÓTIPO DE SOFTWARE DE SEGURANÇA EM REDES PARA A MONITORAÇÃO DE PACOTES EM UMA CONEXÃO

TCP/IP

TRABALHO DE CONCLUSÃO DE CURSO SUBMETIDO À UNIVERSIDADE REGIONAL DE BLUMENAU PARA A OBTENÇÃO DOS CRÉDITOS NA

DISCIPLINA COM NOME EQUIVALENTE NO CURSO DE CIÊNCIAS DA COMPUTAÇÃO — BACHARELADO

PAULO FERNANDO DA SILVA

BLUMENAU, DEZEMBRO/2001.

2001/2-38

ii

PROTÓTIPO DE SOFTWARE DE SEGURANÇA EM REDES PARA MONITORAÇÃO DE PACOTES EM UMA CONEXÃO

TCP/IP

PAULO FERNANDO DA SILVA

ESTE TRABALHO DE CONCLUSÃO DE CURSO, FOI JULGADO ADEQUADO PARA OBTENÇÃO DOS CRÉDITOS NA DISCIPLINA DE TRABALHO DE

CONCLUSÃO DE CURSO OBRIGATÓRIA PARA OBTENÇÃO DO TÍTULO DE:

BACHAREL EM CIÊNCIAS DA COMPUTAÇÃO

Prof. Sérgio Stringari — Orientador na FURB

Prof. José Roque Voltolini da Silva — Coordenador do TCC

BANCA EXAMINADORA

Prof. Sérgio Stringari Prof. Francisco Adell Péricas Prof. Miguel Alexandre Wisintainer

iii

Dedico este trabalho aos meus pais, Oscar e Diná, e a minha

noiva, Viviane, pelo incentivo recebido durante o

desenvolvimento deste trabalho.

iv

AGRADECIMENTOS

Agradeço primeiramente a Deus, por todas as oportunidades e desafios que Ele tem

colocado em meu caminho.

Aos professores do curso de Bacharelado em Ciência da Computação, que

contribuíram de forma indispensável na minha formação pessoal e profissional. Em especial

ao professor Sérgio Stringari, que me orientou no desenvolvimento deste trabalho.

Aos meus familiares e colegas, que sempre me apoiaram e incentivaram durante toda a

minha formação acadêmica.

v

SUMÁRIO

AGRADECIMENTOS .............................................................................................................IV

LISTA DE FIGURAS ........................................................................................................... VIII

LISTA DE QUADROS .............................................................................................................X

LISTA DE TABELAS ..............................................................................................................X

LISTA DE ABREVIATURAS E SIGLAS ...............................................................................X

RESUMO .............................................................................................................................. XIII

ABSTRACT ..........................................................................................................................XIV

1 INTRODUÇÃO.....................................................................................................................1

1.1 OBJETIVOS DO TRABALHO ..........................................................................................2

1.2 ESTRUTURA DO TRABALHO........................................................................................3

2 FUNDAMENTAÇÃO TEÓRICA.........................................................................................4

2.1 CONSIDERAÇÕES SOBRE A INTERNET......................................................................4

2.1.1 A ESTRUTURA DA INTERNET....................................................................................5

2.1.2 OS RECURSOS DA INTERNET.....................................................................................6

2.2 CONSIDERAÇÕES SOBRE O PROTOCOLO TCP/IP ....................................................7

2.2.1 A ARQUITETURA TCP/IP .............................................................................................8

3 A SEGURANÇA NA INTERNET......................................................................................23

3.1 VULNERABILIDADES DA INTERNET .......................................................................24

3.1.1 VULNERABILIDADES DOS PRODUTOS .................................................................24

3.1.2 VULNERABILIDADES NAS CONFIGURAÇÕES.....................................................25

3.1.3 POLÍTICA DE OPERAÇÃO..........................................................................................25

3.2 FORMAS DE ATAQUE À INTERNET ..........................................................................26

vi

3.2.1 RECUSA DE SERVIÇOS ..............................................................................................26

3.2.2 SPOOFING DE IP ..........................................................................................................28

3.2.3 SEQÜESTRO DE SEÇÃO .............................................................................................29

3.2.4 SNIFFERS .......................................................................................................................30

3.2.5 CAVALOS DE TRÓIA ..................................................................................................30

3.2.6 PORTA DOS FUNDOS..................................................................................................31

3.3 FORMAS DE DEFESA ....................................................................................................32

3.3.1 FIREWALL ......................................................................................................................33

3.3.2 CRIPTOGRAFIA............................................................................................................36

3.3.3 OUTRAS MEDIDAS DE SEGURANÇA......................................................................37

3.3.4 MONITORAÇÃO E LOGS ............................................................................................37

4 TECNOLOGIAS UTILIZADAS NO PROTÓTIPO...........................................................39

4.1 UTILIZAÇÃO DA API DO WINDOWS 98 ....................................................................42

4.2 UTILZAÇÃO DA API DA NDIS.....................................................................................43

4.2.1 DRIVER DE PROTOCOLO NDIS .................................................................................44

5 DESENVOLVIMENTO DO PROTÓTIPO ........................................................................47

5.1 REQUISITOS PRINCIPAIS DO PROTÓTIPO ...............................................................47

5.2 ESPECIFICAÇÃO DO PROTÓTIPO ..............................................................................48

5.2.1 ESPECIFICAÇÃO DO MÓDULO APLICAÇÃO.........................................................49

5.2.2 ESPECIFICAÇÃO DO MÓDULO DRIVER .................................................................56

5.3 IMPLEMENTAÇÃO ........................................................................................................65

5.3.1 FERRAMENTAS UTILIZADAS NA IMPLEMENTAÇÃO ........................................65

5.3.2 PRINCIPAIS FUNÇÕES DO MÓDULO APLICAÇÃO ..............................................65

5.3.3 PRINCIPAIS FUNÇÕES DO MÓDULO DRIVER .......................................................69

5.3.4 OPERACIONALIDADE DA IMPLEMENTAÇÃO......................................................72

vii

5.4 TESTE E VALIDAÇÃO...................................................................................................76

6 CONCLUSÕES ...................................................................................................................81

6.1 DIFICULDADES ENCONTRADAS ...............................................................................82

6.2 LIMITAÇÕES...................................................................................................................82

6.3 EXTENSÕES ....................................................................................................................82

ANEXO 1 .................................................................................................................................83

ANEXO 2 .................................................................................................................................89

ANEXO 3 .................................................................................................................................98

ANEXO 4 ...............................................................................................................................105

REFERÊNCIAS BIBLIOGRÁFICAS ...................................................................................111

viii

LISTA DE FIGURAS

Figura 1: Camadas do protocolo TCP/IP e demonstração do encapsulamento dos dados

efetuado em cada camada. ..................................................................................................8

Figura 2: Formato do datagrama IP..........................................................................................10

Figura 3: Formato do datagrama UDP. ....................................................................................16

Figura 4: Formato do segmento TCP. ......................................................................................17

Figura 5: Máquina de estado finito do TCP. ............................................................................20

Figura 6: Visão geral da arquitetura do Windows 98...............................................................39

Figura 7: Programa aplicativo acessando um hardware...........................................................40

Figura 8: Transmissão serial de dados no Windows 98. ..........................................................41

Figura 9: Drivers oferecidos pela NDIS...................................................................................43

Figura 10: Visualização geral do módulo aplicação.................................................................50

Figura 11: Fluxograma do processo A (Ativar Monitor). ........................................................51

Figura 12: Fluxograma do processo D (Abrir Adaptador). ......................................................52

Figura 13: Fluxograma do processo B (Desativar Monitor).....................................................53

Figura 14: Fluxograma do processo E (Fechar Adaptador). ....................................................54

Figura 15: Fluxograma do processo C (Leitura dos pacotes)...................................................55

Figura 16: Fluxograma do processo G (Receber Pacote). ........................................................56

Figura 17: Visualização geral do módulo driver. .....................................................................58

Figura 18: Fluxograma do processo C (Inicialização)..............................................................58

Figura 19: Fluxograma do processo I (Protocolo se conecta ao adaptador).............................59

Figura 20: Fluxograma do processo K (Protocolo se desconecta do adaptador)......................61

Figura 21: Fluxograma do processo H (Trata código para receber pacote). ............................61

ix

Figura 22: Fluxograma do processo N (Protocolo recebe pacote). ..........................................62

Figura 23: Tela principal do protótipo......................................................................................72

Figura 24: Tela de configuração do log....................................................................................74

Figura 25: Tela de configuração de alertas – IP Remoto. ........................................................74

Figura 26: Tela de configuração de alertas – Porta Local. .......................................................75

Figura 27: Configuração de alerta para IP remoto. ..................................................................77

Figura 28: Configuração de alerta para portas locais. ..............................................................78

Figura 29: Monitor de pacotes em funcionamento...................................................................79

Figura 30: Alertas gerados pelo monitor de pacotes................................................................80

Figura 31: Fluxograma do processo F (Setar Filtro)................................................................83

Figura 32: Fluxograma do processo H (Adicionar Log)...........................................................84

Figura 33: Fluxograma do processo I (Verificar Alertas). .......................................................86

Figura 34: Fluxograma do processo J (Alocar pacote).............................................................87

Figura 35: Fluxograma do processo K (Desalocar pacote). .....................................................87

Figura 36: Fluxograma do processo A (Carregar Driver). .......................................................89

Figura 37: Fluxograma do processo B (Procedimento de controle).........................................89

Figura 38: Fluxograma do processo D (Trata código de controle)...........................................90

Figura 39: Fluxograma do processo E (Trata código de conexão)...........................................91

Figura 40: Fluxograma do processo F (Trata código de desconexão)......................................92

Figura 41: Fluxograma do processo G (Trata código para setar filtro). ...................................93

Figura 42: Fluxograma do processo J (Conectar adaptador completado). ...............................94

Figura 43: Fluxograma do processo L (Desconecta adaptador completado). ..........................95

Figura 44: Fluxograma do processo M (Requisição completada)............................................95

Figura 45: Fluxograma do processo O (Transferência de dados completada). ........................96

Figura 46: Fluxograma do processo P (Descarregar protocolo)...............................................97

x

LISTA DE QUADROS

Quadro 1: Exemplo de algoritmo de roteamento......................................................................14

Quadro 2: Implementação referente ao processo D (Abrir adaptador) ....................................66

Quadro 3: Implementação referente ao processo E (Fechar adaptador)...................................67

Quadro 4: Implementação referente ao processo G (Receber pacote) .....................................68

Quadro 5: Implementação do processo I (Conecta adaptador).................................................69

Quadro 6: Implementação referente ao processo K (Desconecta adaptador)...........................71

Quadro 7: Implementação referente ao processo H (Trata receber pacote) .............................71

LISTA DE TABELAS

Tabela 1: Código das mensagens ICMP...................................................................................15

Tabela 2: Bits do campo Código do cabeçalho TCP................................................................18

Tabela 3: Processos do módulo aplicação. ...............................................................................49

Tabela 4: Processos do módulo driver. ....................................................................................57

xi

LISTA DE ABREVIATURAS E SIGLAS

ACL – Access Control List

ARP – Address Resolution Protocol

ARPANET – Advanced Research Projects Agency Network

BGP – Border Gateway Protocol

DDK – Driver Development Kit

DES – Data Encryption Standard

DNS – Domain Name Server

DoS – Denial of Service

EGP – Exterior Gateway Protocol

FTP – File Transfer Protocol

HTTP – Hyper Text Transfer Protocol

ICMP – Internet Control Message Protocol

IP – Internet Protocol

NCP – Network Control Protocol

NDIS – Network Driver Interface Specification

NSF – National Science Foundation

NSFNET – National Science Foundation Network

OSPF – Open Shortest Path First

PPP – Point to Point Protocol

xii

RARP – Reverse Address Resolution Protocol

RSA – Rivest, Shamir and Adleman

SMTP – Simple Mail Transfer Protocol

TCP – Transmission Control Protocol

TCP/IP – Transmission Control Protocol/Internet Protocol

TelNet – Telecommunications Network

UDP – User Datagram Protocol

WWW – World Wide Web

xiii

RESUMO

Este trabalho apresenta um estudo sobre a segurança em redes de computadores.

Apresenta também, a descrição sobre a especificação e implementação de um protótipo de

software para monitoração de pacotes, executado em um computador conectado a rede

Internet. Para o funcionamento do protótipo foi desenvolvido também, um driver utilizando a

NDIS (Network Driver Interface Specification).

xiv

ABSTRACT

This project presents a study on the computer network security, as well as description

on the specification and implementation of a software prototype for monitoring packets,

executed on a computer connected to the Internet. In order to make such prototype work, a

NDIS driver running on Windows 98 has also been developed.

1

1 INTRODUÇÃO

A segurança dos dados tanto pessoais como corporativos deve ser um fator seriamente

analisado quando se decide estabelecer uma conexão com a Internet. Na Internet os dados

trafegam por comutação de pacotes. Estes pacotes podem passar por diversas rotas entre a

origem e o destino e estas rotas podem não apresentar qualquer tipo de segurança, mas não

existe apenas o risco dos dados serem interceptados entre a origem e o destino de uma

transmissão, existe um outro problema que pode ser considerado ainda mais grave, é o caso de

uma pessoa acessar remotamente serviços ou dados sem autorização.

Bernstein (1997) cita cinco categorias comuns de ameaças apresentadas ao se

estabelecer uma conexão com a Internet. Dentre estas categorias pode-se destacar duas que se

caracterizam pelo acesso não autorizado a serviços e dados particulares, as quais são:

a) ameaças à rede corporativa: consiste no acesso de intrusos a componentes da rede

corporativa interna de computadores (este acesso pode ser obtido através de

serviços disponibilizados para a Internet que podem causar graves falhas de

segurança);

b) ameaças aos servidores da Internet: consiste em um intruso entrar em um servidor

Internet e ler ou até mesmo modificar arquivos armazenados no servidor.

Existem várias formas de ataques conhecidas em que pessoas obtêm acesso não

autorizado a serviços ou dados. Entre eles pode-se citar ataques baseados em senhas, em que o

intruso tenta obter senhas de usuários legítimos para obter acesso a serviços ou dados que só

eram autorizados ao usuário legítimo, ou ainda para se fazer passar por outro usuário.

Spoofing de IP, é um ataque que interfere no estabelecimento da conexão entre um cliente e

um servidor, de forma a infiltrar informações falsas de conexão para obter acesso não-

autorizado. Seqüestro de Sessão, intercepta uma conexão já estabelecida para obter acesso

não-autorizado, semelhante ao Spoofing de IP.

Estes pontos vulneráveis citados acima e muitos outros podem ser usados para permitir

inúmeras ações não autorizadas incluindo o uso de serviços, o acesso a sistemas de arquivos

de importância crítica, o acesso a dados do usuário ou programas e privilégios de acesso.

2

Ferramentas de monitoração são importantes, pois através delas pode-se determinar

com grande rapidez se ouve realmente uma invasão à rede interna e quais os danos causados

por esta invasão, auxiliando o administrador de rede a tomar providências para que os danos

causados pela invasão sejam contidos o mais rápido possível.

O funcionamento de um monitor de pacotes consiste basicamente em interceptar

pacotes que trafegam entre o meio interno e externo de um determinado host e armazenar

dados sobre estes pacotes para posterior análise. Mas além de simplesmente armazenar dados

o monitor de pacotes pode ser implementado para alertar situações de perigo, como uma

conexão não prevista ou indicar situações novas, como um endereço IP que nunca havia se

conectado à rede. Podem também existir opções para a exibição de dados dos pacotes, com

vários níveis de abstração para que possam ser melhor interpretados.

Para que um pacote possa ser interpretado pelo monitor é necessário que se entenda

como este está organizado. TCP/IP (Transmission Control Protocol/Internet Protocol) é o

conjunto de protocolos que rege a Internet, portanto todos os pacotes que trafegam na Internet

estão dispostos conforme as especificações do protocolo TCP/IP. O protocolo TPC/IP opera

através da utilização de uma pilha de protocolos. Essa pilha é a soma de todos os protocolos

necessários para transferir os dados entre dois computadores. Portanto para analisar os pacotes

em uma conexão com a Internet é fundamental o domínio do conjunto de protocolos TCP/IP.

O protótipo desenvolvido por este trabalho é um monitor de pacotes aplicado a um

host conectado à Internet através de um acesso discado, utilizando para tanto o protocolo PPP

(Point to Point Protocol). O host disponibiliza serviços para a Internet os quais estarão sendo

monitorados pelo monitor de pacotes. Quando algo suspeito ocorrer, conforme configuração

do administrador de rede, o monitor de pacotes deverá emitir um alerta.

1.1 OBJETIVOS DO TRABALHO

O objetivo principal deste trabalho consiste em especificar e desenvolver um protótipo

de software de monitoração de pacotes, que tenha a capacidade de monitorar os pacotes que

trafegam entre um host e a Internet e alertar o usuário quando ocorrerem situações suspeitas.

Os objetivos específicos do trabalho são:

a) interceptação e interpretação de pacotes TCP/IP;

3

b) análise dos dados contidos nos pacotes;

c) identificação de situações suspeitas;

d) armazenamento das informações monitoradas.

1.2 ESTRUTURA DO TRABALHO

O trabalho está organizado em seis capítulos, estando assim distribuídos:

No capítulo 1, encontramos a introdução, os objetivos e a organização do trabalho.

No capítulo 2, são apresentados fundamentos sobre a Internet e o protocolo TCP/IP,

necessários para o desenvolvimento deste trabalho.

No capítulo 3, é apresentado um estudo sobre a segurança em redes de computadores

conectados à Internet, abordando problemas e soluções.

O capítulo 4 descreve tecnologias utilizadas no desenvolvimento do protótipo.

No capítulo 5, é apresentada a especificação e a implementação do protótipo de

monitoração de pacotes.

O capítulo 6 apresenta a considerações finais sobre o trabalho e sugestões para

trabalhos futuros.

Após o capítulo 6 são apresentados anexos e referências bibliográficas, utilizadas para

a elaboração deste trabalho.

4

2 FUNDAMENTAÇÃO TEÓRICA

Neste capítulo são apresentados os fundamentos e os conceitos das tecnologias que

servem de base para o desenvolvimento do trabalho. Estas tecnologias são importantes para

que sejam alcançados os objetivos do trabalho e o conseqüente entendimento destes objetivos.

2.1 CONSIDERAÇÕES SOBRE A INTERNET

Segundo Cyclades (2000) a Internet é um conjunto de redes de computadores

interligadas, que tem em comum um conjunto de protocolos e serviços, de forma que os

usuários a ela conectados podem usufruir de serviços de informação e comunicação. Este

conceito também é apresentado por Honeycutt (1998).

A Internet atualmente é a maior rede de computadores do mundo. Em um mesmo

espaço estão interligadas empresas, bancos, universidades, governos e muitos outros. Por esta

razão a Internet passa a ter uma influência cada vez maior na vida das pessoas.

Em 1962 Paul Baran trabalhava no desenvolvimento de um novo conceito que,

segundo Segurança (2000) tratava-se de uma rede de computadores capaz de operar sem um

ponto central. Esta rede deveria ter a capacidade de continuar funcionando mesmo que um ou

vários de seus computadores saíssem do ar. O objetivo desta rede era resistir a ataques

militares. Na época, as redes eram baseadas em mainframes, computadores de grande porte

que armazenavam todas as informações da rede. Haviam terminais que acessavam

diretamente os mainframes, que eram o ponto central da rede. Do ponto de vista militar estas

redes eram totalmente vulneráveis, pois se o computador central fosse atingido toda a rede era

destruída.

Quando Baran terminou seu trabalho havia projetado uma rede onde todos os nós

poderiam comunicar-se entre si, além disto os dados poderiam determinar a sua rota

dinamicamente, ou seja, se os dados encontrassem problemas em um nós da rede estes

poderiam encontrar dinamicamente um novo caminho para chegarem ao seu destino. Porém o

projeto de Baran não foi aprovado pelo Pentágono e acabou sendo abandonado.

Em 1969, baseado nas idéias de Baran, surgi a ARPANET (Advanced Research

Projects Agency Network), era a primeira rede de computadores descentralizada. No início a

5

ARPANET era constituída de quatro computadores que se localizavam em instituições

acadêmicas dos Estados Unidos, as instituições eram:

a) Stanford Research;

b) University of Utah;

c) University of California em Los Angeles;

d) University of California em Santa Barbara.

Em 1985, de acordo com Cyclades (2000), uma outra entidade americana, a NSF

(National Science Foundation), interligou os supercomputadores dos seus centros de

pesquisa, formando assim uma outra grande rede de computadores, chamada de NSFNET

(National Science Foundation Network). Finalmente em 1986 a NSFNET foi interligada à

ARPANET, e ao conjunto destas duas redes de computadores, a ARPANET e a NSFNET,

deu-se o nome de Internet.

2.1.1 A ESTRUTURA DA INTERNET

A estrutura da Internet é formada basicamente por três figuras principais. Os

backbones, os provedores de acesso e os usuários finais.

Backbones são grandes redes de computadores de alta velocidade, projetadas para a

transmissão de um grande volume de dados. Pode-se dizer que os backbones são a espinha

dorsal das redes de computadores. A Internet é formada por vários backbones espalhados pelo

mundo, sendo o que seu backbone principal se encontra nos EUA.

Um provedor de acesso conecta-se diretamente aos backbones da Internet, formando

conexões dedicadas e permanente. O objetivo do provedor de acesso é fornecer acesso a

Internet e outros serviços correlatos aos usuários finais.

Os usuários finais podem ser particulares ou empresas que desejam obter acesso a

Internet. Os usuários finais conectam-se aos provedores de acesso através da rede telefônica,

via modem, e utilizam todos os recursos disponíveis na Internet.

A estrutura dos backbones, provedores de acesso ou usuários finais na Internet podem

ainda serem formadas por host, que são computadores que estão conectados a uma única rede

física e tem o objetivo de executar principalmente programas aplicativos, ou roteadores, que

6

são computadores conectados a duas ou mais redes físicas, e são responsáveis pela

transmissão entre as redes.

2.1.2 OS RECURSOS DA INTERNET

Os recursos disponíveis na Internet são ilimitados. A cada dia surgem novas

possibilidades de utilização da rede. Os principais recursos disponíveis na Internet são:

a) E-Mail: é um recurso que permite a troca de mensagens entre usuários. A troca das

mensagens é baseada em endereços no formato usuário@domínio, em que

“usuário” corresponde a um único usuário ou a um conjunto de usuários, e

“domínio” corresponde ao nome do domínio de uma rede onde está localizado o

usuário;

b) Telnet (Telecommunications Network): permite a execução retoma de aplicações.

Trata-se de um emulador de sistemas. Que através de um programa “cliente telnet”

o usuário pode conectar-se a um outro host e, dependendo das suas permissões,

executar os aplicativos deste host, como se estivesse trabalhando nele localmente;

c) Network News: fornece artigos referentes a vários assuntos, estas informações são

agrupadas em categorias denominadas newsgroups. Através de um programa de

leitura de news o usuário pode conectar-se a um servidor de network news e ler os

artigos disponíveis;

d) FTP (File Transfer Protocol): é um recurso especializado na transmissão de

arquivos pela Internet. Através de um cliente de FTP o usuário pode conectar-se a

um host, analisar o sistema de arquivo em que está conectado, e escolher quais

arquivos deseja copiar ou enviar;

e) WWW (World Wide Web): é um sistema de busca de informações em que a

passagem de um documento para outro está embutida no próprio documento. A este

mecanismo é dado o nome de navegação por hipertexto. A WWW permite que

sejam incorporados aos documentos recursos de multimídia e imagens. O usuário

utiliza um programa denominado browser para ler os documentos da WWW.

7

2.2 CONSIDERAÇÕES SOBRE O PROTOCOLO TCP/IP

O TCP/IP envolve praticamente toda a Internet. Todos os recursos e possibilidades que

a Internet oferece aos seus usuários somente são possíveis devido à implementação do

TCP/IP.

De acordo com Segurança (2000) o termo TCP/IP é referente aos dois principais

protocolos da Internet, o TCP (Transfer Control Protocol) e o IP (Internet Protocol). Porém

existem muitos outros protocolos além do TCP e do IP que operam na Internet, a este

conjunto de protocolos deu-se o nome de TCP/IP. Os protocolos do conjunto TCP/IP

oferecem transporte de dados na Internet para todos os serviços disponíveis atualmente.

Sob o ponto de vista de Cyclades (2000), o TCP/IP é um conjunto de protocolos de

comunicação utilizado para troca de dados entre computadores em ambientes de redes locais

ou remotos.

Com a criação da ARPANET com 1969 surgiu a necessidade do desenvolvimento de

um conjunto de protocolos mais estável. Segundo Chiozzoto (1999) as primeiras aplicações

da ARPANET, e-mail e telnet, utilizavam o protocolo NCP (Network Control Protocol). A

utilização do protocolo NCP na ARPANET começou a apresentar limitações, à medida que o

número de equipamentos aumentava.

Um grupo liderado por Vint Cerf, no início da década de setenta, iniciou os estudos

para o desenvolvimento de um novo protocolo para a ARPANET. Dos resultados destes

estudos foi criado o documento “A Protocol for Packet Network Interconnection”, neste

documento está a especificação do protocolo TCP.

O TCP começou a ser utilizado na ARPANET em 1975, porém logo surgiu a

necessidade das funções exercidas pelo TCP serem dividas em dois grupos: as funções de

controle de fluxo e as funções de conectividade. As funções de controle de fluxo ficaram sob

responsabilidade do TCP, mas para as funções de conectividade foi criado um novo protocolo,

o IP. Desta forma nasceu o protocolo conhecido como TCP/IP.

8

O TCP/IP trabalhou em conjunto com o NCP até o final de 1982. A partir de 1983 a

ARPANET começou a operar exclusivamente com o protocolo TCP/IP. Deste então o TCP/IP

tem sido o padrão absoluto para conexões com a Internet.

2.2.1 A ARQUITETURA TCP/IP

Segundo Comer (1998) a arquitetura TCP/IP trata-se de um conjunto de protocolos

divididos em quatro camadas, sendo que cada uma destas camadas possui funções bem

definidas.

Figura 1: Camadas do protocolo TCP/IP e demonstração do encapsulamento dos dados efetuado em cada

camada.

Conforme a Figura 1, as camadas que compõem a pilha de protocolos do TCP/IP são:

a) camada de aplicação: é a camada em que rodam os aplicativos do usuário. Esta

camada interage com a camada de transporte para enviar ou receber dados;

b) camada de transporte: é responsável pela comunicação fim-a-fim entre os

aplicativos, controla o fluxo de dados e o quebra formando pacotes passando-os

para a camada seguinte;

c) camada Internet: esta camada coloca o pacote em um datagrama IP, executa o

roteamento e passa o datagrama para a interface de rede apropriada para a

transmissão;

9

d) camada de enlace de dados ou interface de rede: é responsável por encapsular os

pacotes da camada Internet no formato específico da rede associada e extrair os

pacotes dos quadros vindos da rede e encaminhá-los à camada Internet.

A seguir são apresentados maiores detalhes sobre o funcionamento de cada um dos

principais protocolos da pilha TCP/IP.

2.2.1.1 ADDRESS RESOLUTION PROTOCOL (ARP)

O protocolo ARP é responsável por mapear endereços IP em endereços físicos, para

que um datagrama IP possa ser enviado através de uma arquitetura de rede específica.

A implementação do ARP possui duas funções básicas. A primeira é mapear um

endereço físico quando for enviar um pacote pela rede. A segunda é responder às solicitações

de outras máquinas em busca de um endereço IP.

Quando o protocolo ARP deseja enviar um pacote pela rede ele primeiro verifica se já

conhece o endereço físico correspondente ao endereço IP do pacote que deseja enviar. Se o

endereço físico já for conhecido o pacote é enviado. Se o endereço físico ainda não for

conhecido o ARP envia uma solicitação de endereço por difusão e aguarda a resposta.

2.2.1.2 REVERSE ADDRESS RESOLUTION PROTOCOL (RARP)

O protocolo RARP executa a função inversa ao protocolo ARP, mapeando endereços

físicos em endereços IP.

A utilização do protocolo RARP pode ser vista no caso de um computador que não

possui unidade de disco e armazena seus dados em um servidor de arquivos remoto. Para que

os aplicativos TCP/IP deste computador funcionem é necessário que ele saiba o seu endereço

IP. Sendo assim na inicialização do sistema o protocolo RARP envia uma solicitação por

broadcast e aguarda que um servidor de endereços IP responda à sua solicitação informando-

lhe o seu endereço IP.

10

2.2.1.3 INTERNET PROTOCOL

É o principal protocolo da camada Internet. O Internet protocol oferece um serviço de

transmissão sem conexão e não confiável. A transmissão realizada pelo IP é dita sem conexão

porque não existe relação entre os pacotes enviados, ou seja, não existe controle sobre a

ordem de chegada dos pacotes enviados e alguns pacotes podem até ser perdidos. É também

classificada como transmissão não confiável porque não existe, por parte do IP, controle sobre

falhas na transmissão dos pacotes. Um pacote pode atrasar-se, ser duplicado, ser entregue com

falha ou nem ser entregue.

Para realizar uma transmissão o protocolo IP monta um datagrama IP e coloca os

dados neste datagrama. Na Figura 2 temos o formato de um datagrama IP.

Figura 2: Formato do datagrama IP.

O primeiro campo do datagrama, chamado versão, possuí quatro bits e indica a versão

do protocolo IP utilizado para montar o datagrama. Um protocolo IP ao receber um

datagrama, utiliza este campo para verificar se a versão do protocolo IP que montou o

datagrama é compatível com a sua versão.

Em seguida vem o campo de comprimento de cabeçalho (IHL), também com quatro

bits. Este campo indica o comprimento do cabeçalho do datagrama em palavras de 32 bits.

Um datagrama comum possui o tamanho de 20 bytes, neste caso o campo IHL possui o valor

cinco. O campo identificado por “comprimento total” armazena o tamanho total, cabeçalho

mais dados do datagrama em bytes. Este campo possui 16 bits de comprimento. É através da

11

subtração do campo IHL no campo comprimento total que o protocolo IP determina o

tamanho do campo de dados.

O campo tipo de serviço sugere como o datagrama deve ser tratado e é dividido em

cinco partes, as quais são:

a) precedência: possui três bits e identifica, em uma escala que um a sete, a prioridade

do datagrama;

b) delay: possui um bit e indica que o datagrama deve ser enviado pela interface de

menor delay;

c) throughput: possui um bit e indica que o datagrama deve ser enviado pela interface

que possui maior taxa de transmissão;

d) reliability: possui um bit e indica que o datagrama deve ser enviado pela interface

que possui maior confiabilidade;

e) cost: possui um bit e indica que o datagrama deve ser enviado pela interface de

menor custo. Ainda existe mais um bit no campo tipo de serviço, que reservado para

implementações futuras.

Algumas vezes um datagrama IP necessita ser fragmentado, para ser transmitido por

uma rede física que possua um tamanho de quadro menor do que o tamanho de quadro da rede

física que originou a transmissão do datagrama. Os campos identificação, flags e offset de

fragmento controlam a fragmentação e a remontagem dos datagramas. O campo identificação

possui um número de seqüência que é utilizado para a reconstituição de datagramas

fragmentados. O campo flags é formado por três bits, porém somente os dois bits de mais

baixa ordem são utilizados. E suas funções são respectivamente identificar se o datagrama

pode ser fragmentado. E identificar se o datagrama faz parte do meio ou do final de uma

fragmentação. O campo offset de fragmento indica o deslocamento dos dados no datagrama

atual com base no datagrama original em bytes.

O campo tempo de vida é decrementado cada vez que um datagrama passa por um

roteador. Quando o tempo de vida chega a zero o datagrama é descartado pelo roteador que

retorna à origem uma mensagem de erro. O conceito de tempo de vida é importante para

garantir que os datagramas não trafeguem infinitamente.

12

No campo protocolo, que possui oito bits, fica identificado qual protocolo de alto nível

gerou a área de dados do datagrama e no campo “verificação da soma do cabeçalho”, que

possui dezesseis bits, é gerado um número com base nos dados do cabeçalho. Cada vez que

um datagrama passa por um roteador, este calcula novamente o valor de verificação cabeçalho

o compara com o valor gravado no campo, isto é feito para garantir a integridade dos dados

do cabeçalho.

Os campos Endereço IP de origem e endereço IP de destino contém os endereços IP

dos hosts de origem e destino respectivamente. Os endereços IP são palavras de 32 bits

utilizadas para identificar um computador na arquitetura de protocolos TCP/IP.

O campo opções não é obrigatório nos datagramas IP e o seu tamanho é variável. Este

campo é utilizado principalmente para testes e depuração na rede. O campo PAD é utilizado

em conjunto com o campo opções e contém apenas bits zerados, para que o tamanho do

cabeçalho do datagrama IP seja múltiplo de 32 bits, já que o campo IHL utiliza esta unidade

de medida.

O campo dados delimita a área dos dados que estão sendo transmitidos. O protocolo IP

não faz qualquer tipo de processamento, consistência ou validação nas informações contidas

neste campo.

A principal tarefa do IP é decidir para qual host ou roteador o datagrama deve ser

encaminhado, esta tarefa é chamada de roteamento, pois trata-se da escolha da rota utilizada

pelo datagrama para atingir o seu destino. Quando o destino de um datagrama for um host

conectado diretamente ao computador em que se encontra o datagrama, o mesmo passa por

um roteamento direto. No roteamento direto o IP informa a camada de interface de rede que o

datagrama deve ser entregue ao endereço IP existente no campo “IP destino” do datagrama.

Porém, quando o destino de um datagrama não estiver diretamente conectado ao

roteador em que se encontra o datagrama, o IP deverá executar o roteamento indireto. No

roteamento indireto o datagrama é encaminhado a um outro roteador, este procedimento é

executado até que o datagrama chegue a um roteador que possa entregá-lo diretamente ao seu

destino.

13

Para decidir a qual roteador um datagrama deve ser encaminhado, de forma de chegue

ao seu destino, o IP utiliza uma estrutura conhecida como tabela de roteamento. A tabela de

roteamento contém basicamente entradas que indicam qual deve ser o próximo passo a ser

tomado por um datagrama com um determinado endereço IP de destino, ou seja, a tabela de

roteamento não sabe a rota completa para a entrega de um datagrama, ela sabe apenas o

próximo passo.

Existem várias formas de otimizar a tabela de roteamento de forma que ela fique

menor e o IP torne-se mais eficaz na escolha de uma rota. Utilizar o endereço da rede destino

na tabela de roteamento ao invés do host de destino torna o roteamento mais eficaz, com este

método a tabela de roteamento contém apenas as entradas das redes de destino e para qual

roteador um datagrama endereçado a uma destas redes deve ser encaminhado. Outra forma de

otimizar a tabela de roteamento é inserir na tabela uma rota default, este método é muito útil

no caso de uma rede local que se conecta com a Internet através de um único ponto, neste

caso todos os datagramas, que não pertencem à rede local, devem ser encaminhados para este

ponto. O Quadro 1, extraído de Comer (1998), apresentar um exemplo de um algoritmo de

roteamento.

14

Quadro 1: Exemplo de algoritmo de roteamento.

A construção e a manutenção da tabela de roteamento pode ser feita de três formas

distintas, estas formas são:

a) estática: a informação das rotas é realizada manualmente pelo administrador da

rede;

b) dinâmica, via ICMP (Internet Control Message Protocol): uma entrada na tabela de

roteamento pode ser alterada através de uma mensagem REDIRECT do protocolo

ICMP;

c) dinâmica, via protocolos de roteamento: utilização de protocolos específicos de

roteamento como o OSPF (Open Shortest Path First), BGP (Border Gateway

Protocol) ou EGP (Exterior Gateway Protocol), que trocam constantemente

informações sobre roteamento.

Após o IP determinar o próximo passo da rota de um datagrama através da tabela de

roteamento, ele passa o datagrama para a camada de interface de rede informando o endereço

IP que o datagrama deve ser entregue, a camada de interface de rede faz a veiculação do

endereço IP para o endereço físico, coloca o datagrama em um quadro e envia o quadro ao seu

destino.

Algoritmo:

Extrai o endereço IP de destino, D, do datagrama,

e calculo o prefixo da rede, N;

Se N corresponder com qualquer endereço de rede conectado

Diretamente entregue datagrama ao destino D através

desta rede;

se a tabela contiver uma rota específica do host para D

envie o datagrama para o próximo passo da rota

especificado na tabela

se a tabela contiver uma rota para a rede N

envie o datagrama para o próximo passo da rota

especificado na tabela

se a tabela contiver uma rota padrão

envie o datagrama para o roteador padrão especificado

na tabela

Caso contrário declare um erro de roteamento;

15

Quando o IP recebe um datagrama vindo da camada de interface de rede, caso o

computador seja em um host, o IP irá verificar se o datagrama é destinado ao próprio host,

caso for, o datagrama é passado para a camada de transporte, caso não for o datagrama é

descartado, ou seja, um host não pode encaminhar datagramas a outros hosts. Caso um

datagrama chegue a um roteador, este também irá verifica se o datagrama é destinado a ele

mesmo e passa o datagrama para a camada de transporte. Mas, caso não seja, é executado o

roteamento e enviado o datagrama novamente.

2.2.1.4 INTERNET CONTROL MESSAGE PROTOCOL

O protocolo IP possui um protocolo auxiliar para tratamento de erros, este protocolo é

o ICMP.

Durante a transmissão de datagramas pelo protocolo IP, existem diversas situações que

podem causar a não entrega do datagrama ao seu destinatário, como o congestionamento de

um roteador ou o fim do tempo de vida do datagrama. Para permitir que host intermediários

informem erros ou situações inesperadas à origem do datagrama é utilizado o protocolo

ICMP.

Tabela 1: Código das mensagens ICMP.

Campo tipo Tipo de Mensagem ICMP 0 Resposta ao eco (Echo Reply) 3 Destino não acessível 4 Dissipação da origem 5 Redirecionamento (mudar a rota) 8 Solicitação de eco (Echo Request) 11 Tempo excedido para um datagrama 12 Problema de parâmetro num datagrama 13 Solicitação de indicação de hora 14 Resposta de indicação de hora 15 Solicitação de informação (obsoleto) 16 Resposta de informação (obsoleto) 17 Solicitação de máscara de endereço 18 Resposta de máscara de endereço

A Tabela 1 apresenta as mensagens transmitidas pelo protocolo ICMP. Por exemplo,

as mensagens 0 e 8 são utilizadas para verificar a existência e o status de um host. Estas

mensagens são usadas pelo comando ping.

16

A mensagem 3 é utilizada para informar à origem do datagrama que, por diversos

motivos, não foi possível entregar o datagrama ao seu destinatário. Já a mensagem 4 sinaliza

que o datagrama foi descartado, pois existe um congestionamento ou sobrecarga na rede.

Desta forma cada uma das mensagens possui em objetivo específico e também uma

estrutura específica para sua transmissão.

2.2.1.5 USER DATAGRAM PROTOCOL (UDP)

É um protocolo da camada de transporte que oferece serviço de transmissão sem

conexão e não confiável. Na verdade o serviço oferecido pelo UDP é o mesmo oferecido pelo

IP, apenas com a diferença que o UDP tem a capacidade de endereçar as portas de origem e

destino, identificando assim o protocolo da camada de aplicação que deverá receber o

datagrama. Portas de origem e destino são números utilizados para identificar os aplicativos

que estão participando da conexão.

Uma mensagem UDP é denominada de datagrama de usuário. O formato de um

datagrama de usuário é apresentado na Figura 3.

Figura 3: Formato do datagrama UDP.

O campo porta de origem é opcional e nele é informado o número da porta que

originou o datagrama de usuário. Caso não seja utilizado é preenchido com zeros. No campo

porta de destino, é informado o número da porta a que se destina o datagrama do usuário.

Cada um dos campos que contém número de porta possui 16 bits.

O campo comprimento possui 16 bits e contém o tamanho total do datagrama UDP,

cabeçalho mais dados, em bytes. O campo soma de verificação possui um valor calculado

com base em todo o datagrama UDP para que seja testada a integridade do datagrama quando

17

o mesmo for recebido por um host. O cálculo do campo soma de verificação não é

obrigatório, sendo que quando não for utilizado é preenchido com zeros.

2.2.1.6 TRANSMISSION CONTROL PROTOCOL

O TCP é um protocolo da camada de transporte que oferece um serviço de transporte

de streams confiável e orientado a conexão. A transmissão efetuada pelo TCP é considerada

confiável porque o protocolo implementa meios que asseguram a entrega de seus segmentos,

e é considerada orientada à conexão porque o TCP estabelece circuitos virtuais entre

transmissor e receptor antes da transmissão dos dados propriamente ditos começar. Para que

uma transmissão TCP ocorra é necessário que transmissor e receptor estejam cientes de tal

transmissão e concordem com a mesma.

Quando o TCP realiza uma transmissão ele formata suas informações (cabeçalho +

dados) em uma estrutura chamada segmento. Na Figura 4 temos o formato de um segmento

TCP.

Figura 4: Formato do segmento TCP.

Os campos porta origem e porta destino, com 16 bits cada, armazenam os números das

portas participantes da conexão. O campo “número de seqüência” possui 32 bits e armazena

um número que identifica a ordenação dos bytes transmitidos, já o campo “número de

reconhecimento”, também com 32 bits, informa o número dos bytes que o destino confirma já

Janela

18

ter recebido. O campo “tamanho de cabeçalho” contém o tamanho do cabeçalho representado

por um número inteiro, o valor deste campo representa unidades de 32 bits. O campo

reservado possui seis bits e é reservado para implementações futuras.

O segmento TCP transporta informações com propósitos específicos, como estabelecer

ou encerrar conexões, confirmações de recebimento ou apenas transporte de dados. O campo

código de bits é utilizado para identificar qual o propósito do segmento e também para indicar

a validade de alguns campos do segmento. Na Tabela 2 é apresentado o significado de cada

um dos bits do campo código de bits.

Tabela 2: Bits do campo Código do cabeçalho TCP.

Bits da esquerda para a direita

Significado se o bit estiver ligado

URG Campo de ponteiro urgente é válido ACK Campo de reconhecimento é válido PSH Este segmento requer push RST Restabelecer conexão SYN Sincronizar os números de seqüência FIN O emissor atingiu o final do fluxo de bytes

O campo janela indica a quantidade de bytes que podem ser enviados para o receptor,

ou seja, o tamanho da janela de dados que o receptor esta suportando. O campo soma de

verificação contém um número que é calculado com base no conteúdo do segmento e em

alguns campos do datagrama IP que contém o segmento, para que seja feita a verificação da

integridade do segmento. Dados urgentes é um ponteiro para a posição, no campo dados, em

que terminam os dados que devem ser entregues com urgência.

O campo opções possui tamanho variável e é utilizado pelo TCP para realizar

negociações com o host remoto, uma das funções do campo opções é a negociação do

tamanho máximo do segmento para a conexão. O campo PAD possui bits zerados e é

utilizado para que o segmento tenha um tamanho múltiplo de quatro bytes, devido ao tamanho

variável do campo opções. O campo que contém os dados que o segmento transporta.

O estabelecimento de uma conexão ocorre em três etapas, este processo é conhecido

por handshake de três vias, ou aperto de mão triplo. Primeiramente um host “A”, que deseja

estabelecer a conexão envia um segmento com um com o bit SYN ativado, com um número

de seqüência inicial e com um número de reconhecimento em branco. Em seguida um outro

19

host “B”, retorna um segmento com os bits SYN e ACK, com o seu próprio número de

seqüência e com um número de reconhecimento igual ao número de seqüência recebido mais

um, para indicar que entendeu e aceitou o segmento enviado por “A”. Para finalizar “A” envia

um outro segmento para “B” contendo SYN e ACK e o campo um número de reconhecimento

contendo o número de seqüência recebido mais um. Assim a conexão está estabelecida.

Para executar uma desconexão o host “A” envia um segmento com o bit FIN ativado e

o host “B” retorna um segmento contendo FIN e ACK, neste momento “B” informa aos seus

aplicativos que está encerrando a conexão, após isto “B” envia para “A” um novo segmento

contendo FIN e ACK e “A” retorna com ACK para sinalizar que entendeu, e a desconexão

está terminada. É possível também resetar uma conexão, para isto basta que seja enviado um

segmento com o bit RST ativado. A operação de RST faz com que a conexão seja abortada e

todos os recursos sejam liberados.

A confirmação da transmissão de dados do TCP é feita ao nível de bytes, um segmento

com o bit ACK ativado significa que já foram recebidos os bytes até a posição do número

contido no campo “número de reconhecimento”, partindo como número base do stream o

número de seqüência inicial. Para cada segmento enviado é iniciada a contagem de um

temporizador, se a contagem chegar ao fim e o host não tiver recebido a confirmação do

recebimento do respectivo segmento, este segmento é enviado novamente.

Na transmissão o TCP pode agrupar bytes para que os segmentos obtenham o melhor

tamanho possível, porém para alguns aplicativos este agrupamento pode causar problemas.

Imagine uma aplicação interativa em que a decisão do usuário depende de cada caractere que

chega ao seu hosts, neste caso o agrupamento de bytes pode causar problemas. Para isto existe

o bit de controle PSH, este bit sinaliza que os dados devem ser enviados imediatamente, sem

aguardar que um segmento seja completamente preenchido.

20

Figura 5: Máquina de estado finito do TCP.

Todo o funcionamento do TCP pode ser melhor analisado através de um diagrama

conhecido por máquina de estado finito. Neste diagrama estão representados os estados

possíveis para o TCP e o que leva a alteração destes estados.

A Figura 5 demonstra a máquina de estado finito do TCP. De acordo com a máquina

de estado finito, os estados possíveis para o TCP são:

a) closed: não existe conexão, nem nenhum tipo de transmissão;

21

b) listen: devido à ação de algum aplicativo o TCP está no aguardo de um pedido de

conexão (open passivo);

c) syn sent: foi enviado um pedido de conexão e o protocolo está aguardando o retorno

da confirmação;

d) syn rcvd: foi recebido um pedido de conexão, o protocolo enviou a confirmação e

está esperando a confirmação da confirmação para que conexão se estabeleça;

e) estabilished: conexão já estabelecida, é o estado em que ocorre a transmissão dos

dados;

f) fin wait 1: o TCP enviou um pedido de desconexão e está aguardando a resposta;

g) fin wait 2: o protocolo recebeu a confirmação de um pedido anterior de desconexão;

h) closing: o host que enviou o pedido de desconexão e obteve uma confirmação,

acaba de receber um pedido de desconexão, o protocolo está aguardando a liberação

das aplicações para enviar uma confirmação do pedido;

i) time wait: a conexão já está encerrada, mas o TCP está aguardando a chega de

possíveis segmentos duplicados, o tempo deste estado é geralmente o dobro do

tempo de vida dos segmentos;

j) close wait: o protocolo recebeu um pedido de desconexão, e está aguardando a

liberação das aplicações para enviar a confirmação;

k) last ack: o TCP já enviou o último pedido de desconexão e está aguardando a última

confirmação para que a conexão seja encerrada. Após este estado também será feita

a temporização do estado time wait.

2.2.1.7 PROTOCOLOS DA CAMADA DE APLICAÇÃO

Nesta camada funcionam os protocolos usados pelas aplicações dos usuários. Os

protocolos da camada de aplicação utilizam os serviços da camada de transporte para realizar

as suas tarefas, que podem ser transmissão de dados com ou sem conexão. Existem vários

protocolos desenvolvidos para esta camada e não existe uma padronização definida para estes

protocolos, uma padronização informal ocorre na medida em que alguns protocolos se

destacam na realização de algumas tarefas perante outros.

Dentre os protocolos mais conhecidos e utilizados da camada de aplicação podemos

destacar alguns, são eles:

22

a) SMTP (Simple Mail Transfer Protocol): protocolo utilizado em aplicações de

transferência de mensagens (correio eletrônico). O destino das mensagens é

determinado por um endereço no formato usuário@domínio, onde usuário

especifica o nome de uma caixa postal e domínio a rede em que se encontra tal

caixa;

b) FTP: protocolo desenvolvido para a transferência de arquivos entre um host local e

um host remoto. Através do FTP o usuário pode, dependendo das permissões,

navegar no sistema de arquivos do host remoto e escolher quais arquivos deseja

transferir. A transferência dos arquivos pode ser realizada tanto do host local para o

host remoto como o contrário, do host remoto para o local;

c) HTTP (Hyper Text Transfer Protocol): protocolo desenvolvido para oferecer

serviços de transmissão e navegação através de hiper texto, suporta a transmissão de

textos, gráficos e qualquer tipo de arquivo. É o protocolo utilizado pela WWW;

d) TelNet: este protocolo oferece serviço de emulação de um terminal de uma rede

remota. Uma aplicação que utilize o protocolo TelNet permite que o usuário

conecte-se a um host remoto e execute comandos como se estivesse operando

localmente;

e) DNS (Domain Name Server): muitas vezes é mais simples para o usuário

memorizar um nome simbólico do que um endereço IP. Por este motivo foram

associados nomes simbólicos aos computadores da Internet. O DNS é um protocolo

responsável pela resolução dos nomes simbólicos. Ele recebe uma requisição com

um nome simbólico e responder o respectivo endereço IP.

23

3 A SEGURANÇA NA INTERNET

Atualmente a Internet é utilizada por várias empresas e particulares, que fornecem e

utilizam serviços dos mais variados possíveis, estes serviços podem abranger transações

comerciais e financeiras. Porém conectar-se a Internet significa expor seus dados a diversas

ameaças de segurança. Estas ameaças podem ir desde a simples impossibilidade de utilização

de um serviço até a obtenções indevidas de informações confidenciais ou movimentações

financeiras indevidas.

Segundo Bernstein (1997), quando a Internet foi projetada o seu objetivo principal era

a interoperabilidade entre as diversas redes conectadas. Portanto aspectos de segurança não

foram priorizados no projeto. Os dados transmitidos pela Internet podem passar por vários

hosts intermediários até atingirem o seu destino, nos quais podem ocorrer várias situações

imprevistas como perda, alteração ou espionagem das informações transmitidas. Isto torna a

Internet um meio de comunicação não confiável e inseguro.

Os ataques às informações ou serviços da Internet são realizados por crackers. Os

crackers, segundo Segurança (2000), são pessoas que de algum modo dominam ou violam

sistemas remotos com intenções maliciosas. Estes são geralmente confundidos com hackers,

porém hackers são, segundo Segurança (2000), pessoas intensamente interessadas no estudo

de falhas em sistemas operacionais, e possuem um avançado conhecimento em linguagens de

programação. Os hackers não têm como objetivo atacar redes ou informações na Internet.

Os motivos que levam os crackers a invadir redes ou espionar dados são os mais

diversos possíveis. Segundo Bernstein (1997), alguns crackers revelaram os motivos que os

levaram a praticar seus ataques, estes motivos são:

a) ganhos financeiros: são ataques a bancos para transferência de dinheiro, alteração

de valores de dívidas ou captura de informações importantes para posterior venda;

b) vinganças: funcionários descontentes ou demitidos podem realizar ataques,

danificando a rede ou os dados de empresas;

c) necessidade de aceitação ou respeito: crackers são desafiados a invadir uma rede ou

obter informações privadas, para poderem ser aceitos em um grupo;

d) idealismo: alguns crackers realizam ataques contra instituições ou sistemas do

governo cujos propósitos eles discordem;

24

e) curiosidade ou busca de emoção: estes ataques são realizados simplesmente porque

o acesso a uma determinada rede era proibido ou considerado seguro;

f) anarquia: são crackers que realizam ataques com o objetivo de provocar desordem

ou atrapalhar a realização de atividades;

g) aprendizado: alguns crackers violam pequenas redes com o intuito de aprendizado,

para o no futuro realizarem ataques maiores;

h) ignorância: são usuários que não sabem que seus atos são ilegais. Realizam

invasões para testar ou melhorar a segurança das redes;

i) espionagem industrial: são empresas que se dedicam a atacar a rede de outras

empresas para obter informações sigilosas;

j) espionagem nacional: semelhante à espionagem industrial, são países atacam redes

de outros países para obter informações estratégicas, financeiras ou técnicas.

3.1 VULNERABILIDADES DA INTERNET

Uma vulnerabilidade ou brecha é qualquer problema ou configuração encontrados em

um hardware ou software que facilite ou ofereça a possibilidade de um ataque a uma rede

remota, a obtenção de acesso não permitido ou qualquer tipo ilícito de operação na rede. As

vulnerabilidades ou brechas podem estar presentes em roteadores, softwares cliente-servidor,

sistemas operacionais e firewalls.

Existem inúmeras vulnerabilidades já descobertas e documentadas, e a cada dia

surgem novas vulnerabilidades capazes de abrirem as portas dos hosts para novos ataques. As

vulnerabilidades podem ser descobertas por hackers, que pesquisam e estudam os softwares,

por fornecedores de softwares ou hardware, que testando seus produtos descobrem novas

falhas, ou por crackers, na tentativa de promover novos ataques.

3.1.1 VULNERABILIDADES DOS PRODUTOS

Embutidos em muitos produtos, tanto de hardware quanto de software, podem estar

diversas vulnerabilidades ainda não descobertas. Seja o projeto de um produto, que não

priorizou a segurança do mesmo, ou algum defeito (bug) neste produto que gerou uma

vulnerabilidade.

25

O conjunto de protocolos TCP/IP apresenta vulnerabilidades originadas de seu projeto,

que não priorizou aspectos de segurança. Qualquer host na Internet pode gerar mensagens

com dados de origem (endereço IP ou portas) falsos para outro host, sendo que quem recebe

as mensagens não tem como saber que são dados falsos, ou saber qual a verdadeira origem

das mensagens. A falta de proteção dos dados entre a origem e o destino é outra brecha

encontrada no TCP/IP, qualquer roteador pode observar os dados que passam por ele sem

qualquer restrição.

Sistemas operacionais ou softwares aplicativos também podem apresentar

vulnerabilidades.

3.1.2 VULNERABILIDADES NAS CONFIGURAÇÕES

Alguns produtos favorecem o aparecimento de vulnerabilidades por serem complexos

de operar e configurar. Outros permitem opções que aumentam o risco de ataques. Quando se

adquire um produto é necessário analisar o seu funcionamento, para verificar o impacto de tal

produto sobre a segurança da rede.

Um exemplo de vulnerabilidade é visto no sistema operacional Unix. Trata-se de uma

lista, que pode ser definida pelo usuário, que contém de nomes ou endereços de host

“confiáveis”. Os hosts contidos nesta lista podem efetuar conexões sem a necessidade de

informar senhas. Se nesta lista for adicionado um caractere “+”, todos os hosts da Internet

serão considerados confiáveis, aumentando ainda mais o risco de ataques.

Outras vulnerabilidades ou brechas de configuração comuns podem ser encontradas

em contas para usuários convidados ou contas expiradas que não são eliminadas. Contas em

que os usuários colocam senhas conhecidas ou fáceis de serem descobertas ou contas que

ficam muito tempo com a mesma senha. Serviços para a Internet configurados incorretamente

e, produtos que são vendidos com parâmetros default que podem gerar vulnerabilidades.

3.1.3 POLÍTICA DE OPERAÇÃO

Política de operação são as regras pelas quais os sistemas são operados. Podem ser

chamados também de controles básicos, estes controles estabelecem o nível de segurança que

será adotado pela empresa.

26

Na política de operação pode estar prevista a solução para várias vulnerabilidades

conhecidas. Ela pode proibir o uso de produtos que foram considerados inseguros. Pode

também estabelecer período para atualização dos softwares, de forma que os mesmo não

fiquem desatualizados e, possivelmente contendo vulnerabilidades já descobertas.

Muitas vezes usuários despreocupados colocam senhas fáceis de serem descobertas. A

política de operação pode prever isto e estabelecer o formado das senhas, de forma que

obrigue os usuários a colocarem senhas não triviais e a trocarem de senha periodicamente.

A política de operação pode ser um grande aliado no combate as vulnerabilidades,

porém falhas na política de operação, ou uma política mal elaborada podem tornar um sistema

extremamente vulnerável.

3.2 FORMAS DE ATAQUE À INTERNET

Segundo Segurança (2000) um ataque é qualquer ação não autorizada empreendida

com a intenção de impedir, danificar, incapacitar ou quebrar a segurança de um servidor

conectado à Internet. O ataque pode ser uma simples recusa de serviços ou até a captura ou

destruição de todas as informações contidas ou servidor.

Existem vários formas de realizar ataques a servidores na Internet, cada uma delas

pode explorar diferentes vulnerabilidades oferecidas pelo alvo. Geralmente os ataques visam

primeiramente obter acesso confiável com o host alvo. Isto pode ser obtido através da captura

ou falsificação de senha, ou se passando por outro host, que já possui o acesso confiável.

Após conseguir o acesso confiável o cracker pode iniciar a execução dos atos ilícitos que o

motivaram a realizar tal ataque. Estes atos podem ir desde a espionagem à alteração ou

destruição de dados.

3.2.1 RECUSA DE SERVIÇOS

De acordo com McClure (2000), o objetivo deste tipo de ataque é interromper ou negar

serviços a usuários legítimos de rede, servidores ou outros recursos da Internet. Ataques de

recusa de serviços, também conhecidos com DoS (Denial of Service), podem causar inúmeros

prejuízos pois têm a capacidade de deixar redes corporativas ou provedores de Internet fora

27

do ar. Ataques de recusa de serviços quase sempre se aproveitam de vulnerabilidades

encontradas na arquitetura do conjunto de protocolos TCP/IP.

Uma forma de realizar um ataque de DoS é o consumo da largura de banda da rede que

está sendo atacada. Para realizar tal ataque o cracker precisa ter uma largura de banda maior

que a largura de banda da rede que está sendo atacada ou pode utilizar várias estações. Para

realizar o ataque geralmente são enviadas consultas ICMP, onde o endereço IP de origem

destas consultas é alterado para que não seja possível descobrir facilmente a origem do

ataque. Uma inundação de consulta ICMP consome toda a largura de banda da rede vítima e a

deixa fora do ar.

Outra possibilidade de realizar este tipo de ataque é consumir os recursos do servidor

que está sendo atacado, ao invés de consumir os recursos da rede. Este ataque é chamado de

inanição de recursos e consiste em tentar consumir o máximo de ciclos da CPU, memória,

sistema de arquivos e processos do sistema operacional, nestes ataques o sistema acaba

travando ou ficando totalmente inutilizável. Para realizar este ataque, basta que sejam

enviados para a vítima vários pedidos de conexão TCP (SYN) com um endereço IP de origem

inexistente. Ao receber um pedido de conexão o TCP/IP aloca recursos para receber a nova

conexão e responde com um segmento TCP contendo SYN - ACK, como a resposta foi

enviada para um endereço IP inexistente a vítima não irá receber qualquer resposta sobre seu

SYN - ACK. Segundo Oliveira (2000), o sistema operacional Windows NT sob estas

circunstâncias irá retransmitir a resposta ao pedido de conexão por mais cinco vezes,

dobrando o valor de tempo de vida dos pacotes a cada retransmissão. Desde primeiro pedido

até o final da última tentativa, incluindo a alocação e liberação de recursos, terá se passado

189 segundos. Conforme McClure (2000) este tempo pode chegar a até 23 minutos nas piores

implementações do TCP/IP. Várias solicitações falsas de conexão acabarão tornando o

sistema inoperante.

Os ataques de negação de serviços podem ser feitos também através da alteração das

informações contidas em tabelas de roteamento. Um cracker pode transformar uma rota

legítima contida em uma tabela de roteamento em uma rota inexistente. Ataque semelhante

pode ser feito em servidores de DNS, estes ataques consistem em fazer com que os servidores

de DNS guardem em seu cache endereços IP falsos. Com alterações tanto em tabelas de

roteamento como em servidores DNS, o endereço IP atacado não será mais acessível, pois um

28

roteamento para tal endereço estará indicando uma rota falsa ou inexistente assim como uma

consulta a um servidor DNS adulterado também.

3.2.2 SPOOFING DE IP

Spoofing de IP, segundo Segurança (2000), é uma técnica sofisticada de autenticar uma

máquina para outra forjando pacotes de um endereço de origem confiável. Gomes (2000)

compartilha da mesma opinião sobre este conceito, segundo ele spoofing de IP é a troca do IP

original por um outro, podendo assim se passar por um outro host. Esta é uma técnica de

ataque complexa, que depende de vários fatores e geralmente rara de ocorrer.

Para que ocorra um ataque de spoofing de IP é necessário que existam dois hosts que

possuam acesso confiável entre si e que a autenticação deste acesso seja feita através do

endereço IP de origem dos datagramas. Quando dois hosts possuem acesso confiável entre si

estes hosts não precisam de senhas para estabelecem uma conexão entre eles. Considerando

esta situação, está aberta a brecha para que ocorra um ataque de spoofing de IP.

Supondo a existência de três hosts, um host “A” e um host “B” que possuem acesso

confiável entre si, e um host “C” que deseja realizar o ataque de spoofing de IP. O ataque

ocorre quando o host “C” tenta fazer uma conexão com o host “A”, alterando o endereço IP

de origem de seus datagramas para parecer que estes vem do host “B”. Quando “A” receber

uma solicitação de conexão irá criar um número de seqüência inicial para a conexão e

preparar um datagrama de reposta que será enviado para “B”. Como a resposta do pedido de

conexão foi enviada para “B” e não para “C” criam-se dois problemas. Em primeiro lugar “B”

irá receber a resposta de um pedido de conexão que não fez, se isto ocorrer “B” irá negar o

pedido de conexão e o ataque irá falhar. E em segundo lugar, “C” não pode dar continuidade

ao processo de conexão, pois não consegue responder à confirmação enviada por “A” já que

não sabe o número de seqüência que foi enviado.

O primeiro problema é facilmente resolvido consumindo os recursos do host “B” de

forma que ele não consiga receber ou responder ao pacote que está recebendo de “A”. A

solução para o segundo problema é um pouco mais complexa, pois “C” terá que adivinhar o

número de seqüência inicial emitido por “A”. Para resolver este problema são realizadas

previamente várias conexões legítimas entre o cracker que está realizando o ataque o e host

29

“A”, nestas conexões o cracker determina um padrão entre os números de seqüência gerados

pelo host “A”. De posse deste padrão o host “C” já pode responder para “A” a confirmação do

pedido de conexão e assim completar o processo de conexão e estabelecer um acesso

confiável entre “A” e “C”.

O ataque demonstrado acima é realmente complexo de ser executado, porém em

Segurança (2000) e Bernstein (1997) podem ser encontrados exemplos de ferramentas que

automatizam o processo.

3.2.3 SEQÜESTRO DE SEÇÃO

Trata-se do domínio, por parte de um intruso (cracker), de uma conexão legítima já

estabelecida entre dois host. Este tipo de ataque aproveita-se de uma grande vulnerabilidade

do protocolo TCP, o TCP permite que dados falsos inseridos em uma conexão legítima sejam

reconhecidos como dados verdadeiros por um host remoto.

O seqüestro de seção é muito semelhante ao spoofing de IP, porém muito mais simples

de ser executado, não é necessário que o invasor adivinhe os números de seqüência que estão

sendo usados na conexão. Outra vantagem é que o invasor consegue ver os dados enviados de

volta pelo host atacado, diferente do que acontece no spoofing de IP.

Para realizar um ataque de seqüestro de seção o cracker primeiramente precisa ter

acesso, local ou remoto, a um host por onde passam dados de várias conexões, como um host

de firewall, um roteador ou um provedor de serviços. Após obter o domínio deste host o

cracker começa a monitorar conexões já estabelecidas que passam por ele. Com isto é

possível determinar os endereços IP e os números de seqüência de host que já estão

conectados, confiam e cooperam entre si. De posse destes dados o cracker pode gerar

datagramas para qualquer um destes host falsificando a identidade do outro, seqüestrando a

seção e, desta forma dominando o host ao qual está enviando datagramas. O host atacado

obedecera a todos os comandos do cracker, pois imagina que estes comandos venham de uma

origem confiável.

A grande diferença entre o seqüestro de seção e o spoofing de IP e é que o primeiro

procura capturar conexões já estabelecidas, enquanto que o segundo tenta estabelecer a

conexão.

30

3.2.4 SNIFFERS

Sniffers são quaisquer procedimentos que, envolvendo hardware ou software, capturem

informações ao longo da rede. Os sniffers podem ser usando tanto para atos lícitos, como a

depuração de problemas de rede, como para atos ilícitos, como a espionagem de informações.

Os sniffers representam um grande problema de segurança, pois podem ser instalados em

qualquer parte da rede e podem capturar informações importantes como nomes de contas e

senhas.

Nas redes de computadores que utilizam placas Ethernet, os frames (pequenas

unidades de dados) sempre são enviados para todas as estações, porém somente a estação ao

qual um frame está endereçado aceita recebê-lo, as outras estações simplesmente ignoram o

frame. Mas se a placa de rede Ethernet estiver em modo promíscuo todos os frames que

chegarem a estação serão aceitos, independente do endereço de destino de tais frames.

O primeiro passo de um sniffer, quando instalado em um host, é colocar a placa de

rede em modo promíscuo. A partir deste momento o sniffer começa a monitorar todo o tráfego

da rede, porém os sniffers não podem simplesmente copiar todos os dados que trafegam na

rede, pois este volume geralmente é muito grande e em pouco tempo não haveria mais espaço

em disco para armazenar as informações capturadas. Portanto a grande maioria dos sniffers

copia apenas os bytes entre 200 e 400 de cada frame ou pacote, pois é nesta faixa de bytes que

se encontram os nomes de usuários e as senhas.

Os alvos preferidos dos ataques de sniffers são redes ou servidores que recebem muitas

senhas para serem validadas. Também são alvos bastante visados os servidores que realizam a

ligação entre uma rede corporativa e a Internet, pois é por esta rota que deverão passar

obrigatoriamente as senhas que validam o uso dos serviços que a rede ou o servidor oferecem

à Internet.

3.2.5 CAVALOS DE TRÓIA

Um Cavalo de tróia, também conhecido como Trojan, é qualquer programa de

computador que se destina a fazer algo útil, interessante ou apenas divertido, mas na verdade

realiza tarefas desconhecidas pelo usuário que o executa. As tarefas ocultas em um cavalo de

tróia sempre possuem caráter prejudicial para o sistema que o está executando, estas tarefas

31

podem ser a simples infecção outros arquivos com o próprio cavalo de tróia ou a captura de

senhas, a destruição de dados, a criação de portas dos fundos nos sistemas, e muitos outros.

Qualquer programa executável do sistema pode estar infectado por um cavalo de tróia,

pois se trata de um programa comum com funções ocultas. Os cavalos de tróia podem

também se camuflar em fotos, documentos texto ou quaisquer outros arquivos do sistema,

estes quando abertos na realidade executarão as funções determinadas pelo cavalo de tróia.

Portanto a descoberta de um cavalo de tróia, dependendo do objetivo de suas funções ocultas,

pode tornar-se bastante difícil.

A instalação de um cavalo de tróia em um sistema muitas vezes é feita acidentalmente

pelo próprio usuário do sistema, quando baixa arquivos de sites não confiáveis na Internet ou

abre um anexo contido em E-mails de procedência desconhecida. Outras vezes esta instalação

é feita por crackers que conseguiram invadir o sistema remotamente. Outra possibilidade é a

distribuição de programas legítimos já infectados por cavalos de tróia, porém estes casos são

muito raros de ocorrer.

O risco para a segurança apresentado por um ataque de cavalo de tróia é bastante

considerável. Os cavalos de tróia podem se automultiplicar dominado cada vez mais o

sistema, podem levar meses para serem descobertos e durante este tempo o cracker pode

adquirir, através do cavalo de tróia, privilégios de administrador tendo acesso a todos os

dados e recursos da rede.

3.2.6 PORTA DOS FUNDOS

De acordo com Oliveira (2000) porta dos fundos, também conhecidas como back

doors, são maneiras que um usuário cria para entrar em um sistema a qualquer momento.

Uma vez que um cracker invadiu um sistema ele pode criar uma porta dos fundos para obter

novamente o acesso a este sistema rapidamente, cavalos de tróia também podem ser

responsáveis pela criação de portas dos fundos.

Dependendo do tipo de porta dos fundos criada um cracker pode manipular arquivos

do sistema, obter senhas, monitorar informações do sistema e até adquirir poderes de

administrador.

32

Contas de usuários são um ótimo tipo de porta dos fundos. Quando um cracker invadir

um sistema certamente irá tentar criar uma conta de usuário para ele, em um sistema com

muitos usuários dificilmente uma conta a mais será descoberta. Preferencialmente o cracker

irá tentar criar uma conta com privilégios de administrador. Com uma conta criada um

cracker poderá voltar a invadir o sistema de maneira muito mais fácil.

Mecanismos de inicialização dos sistemas operacionais também são alvos bastante

visados para a instalação de portas dos fundos. Um cracker pode alterar registros ou arquivos

de inicialização para que abram portas dos fundos para ele. Estas portas dos fundos podem

tanto ser parâmetros de inicialização do sistema que facilitem a sua invasão como a ativação

de serviços, que normalmente não estariam ativos. Através destes serviços o cracker poderia

invadir o sistema novamente.

Da mesma forma que mecanismos de inicialização são alvos de portas dos fundos,

sistemas de agendamento de tarefas também são. Criando uma tarefa agendada para disparar

serviços durante a madrugada um cracker tem maiores possibilidades de não ser descoberto.

Para estabelecer uma porta dos fundos o invasor geralmente instala no host invadido

um programa que lhe possibilitará comandar o host, de nada adiantaria conseguir se conectar

no host através de uma porta dos fundos e possui senhas de administrados sem ter como usa-

las para comandar o host atacado.

3.3 FORMAS DE DEFESA

Se defender de um ataque da Internet não é uma tarefa fácil. Segundo Oliveira (2000)

não existe uma rede 100% protegida, sempre haverá brechas em rede, por onde alguém possa

cometer um ataque. Segundo ele o único sistema totalmente seguro é aquele que está trancado

em uma sala totalmente lacrada.

O que pode ser feito para amenizar o problema de ataques na Internet é a

implementação de técnicas e dispositivos que dificultem a invasão de um sistema. Tão

importante quanto tentar proteger a rede contra ataques, é estar preparado para identificar

todos os prejuízos causados após um ataque ter ocorrido, diminuir ao máximo estes prejuízos

e tentar identificar quem foram os invasores e qual foi a vulnerabilidade utilizada. Estas

medidas servem para evitar futuros ataques da mesma natureza.

33

Quando se implementa uma estrutura de defesa para ataques na Internet, deve-se

principalmente visar três aspectos, os quais são:

a) confidencialidade: proteger as informações ou serviços contra acessos, internos ou

externos, de pessoas não autorizadas;

b) integridade: proteger as informações contra modificações não autorizadas, perda ou

danos, acidentais ou propositais;

c) disponibilidade: assegurar que estarão disponíveis a qualquer momento as

informações ou serviços, a serem utilizados por pessoas devidamente autorizadas.

Algumas técnicas priorizam um aspecto perante outro, outras tentar tratar igualmente

dos três. Outras ainda preocupam-se em monitorar atividades de forma a tentar identificar o

mais rápido possível um ataque que está ocorrendo, e tentar também identificar quem é o

invasor.

3.3.1 FIREWALL

Segundo Segurança (2000) e Oliveira (2000), é chamado de firewall qualquer

dispositivo que impeça o acesso de estranhos em uma rede. Firewalls são dispositivos

formados por hardware e software (roteadores, servidores e vários softwares). Estes

dispositivos são preferencialmente instalados no ponto de ligação entre a rede corporativa e a

Internet, sendo que todo o trafego entre estas duas redes deve passar pelo firewall.

Basicamente o trabalho de um firewall é analisar o trafego de rede que passa por ele.

Com base nesta análise o firewall toma decisões previamente determinadas pelo

administrador da rede. Um firewall pode, por exemplo, proibir qualquer tipo de trafego do

protocolo FTP entre a rede corporativa e a Internet, ou proibir que sejam estabelecidas

conexões com determinados endereços IP ou em determinadas portas.

Alguns firewalls conseguem impedir o ataque de spoofing de IP, quando este tenta

explorar acessos confiáveis entre host de uma rede local. Estes firewalls simplesmente

ignoram pacotes de venham da Internet com endereços IP de host da rede interna.

Um firewall bem projetado, bem configurado e bem mantido é uma grande arma

contra ataques na Internet. E os invasores também sabem disto. Portanto, tentarão desviar do

firewall e entrar na rede de alguma outra forma, explorando, por exemplo, um acesso discado.

34

O firewall é apenas um ponto de entrada para a rede Internet, se um invasor conseguir

ultrapassa este ponto toda a rede estará vulnerável. O firewall não pode ser utilizado como

única forma de defesa contra ataques na Internet.

A arquitetura de um firewall está dividida em dois grandes grupos: filtro de pacotes e

proxy de aplicativos, os quais serão vistos com mais detalhes a seguir.

3.3.1.1 FILTRO DE PACOTES

Um host ou um roteador que faz a ligação entre uma rede privada e a Internet com a

capacidade de filtrar pacotes, é um firewall baseado em filtro de pacotes, é a implementação

mais simples de uma arquitetura firewall.

Quando um pacote chega a um host ou roteador que possui o filtro de pacotes, as

informações contidas neste pacote são comparadas com uma lista de regras que determinam

se o pacote pode seguir adiante ou deve ser bloqueado. As regras são aplicadas aos pacotes na

mesma ordem em que estão armazenadas, portanto a ordem das regras pode mudar o resultado

final. Esta lista de regras é também chamada de ACL (Access Control List).

Em um firewall de filtro de pacotes pode-se permitir ou negar a passagem de pacotes

com base em vários dados do pacote como, endereço de origem, endereço de destino,

protocolo, número de porta ou conteúdo.

Apesar dos filtros de pacotes serem muito úteis no controle ao acesso a uma

determinada rede eles também possuem deficiências. Dependendo da configuração feita nas

ACLs, podem ficar brechas que permitam a realização de um acesso não autorizado. O

desempenho do roteador ou host pode cair drasticamente, dependendo do volume de tráfego e

da quantidade de regras definidas.

3.3.1.2 PROXY DE APLICATIVOS

Também conhecidos como gateway de aplicativos, os servidores proxy de aplicativos

são hosts que pertencem a duas redes e regulam o trafego entre elas, encaixando-se até este

momento no conceito de gateways de base dupla. Em gateways de base dupla, para um

usuário realizar uma conexão externa à rede local, ele primeiramente se conecta ao gateway

35

de base dupla e realiza um login no mesmo, após isto, partindo do gateway de base dupla ele

se conecta no destino externo desejado.

Os servidores proxy de aplicativos incluíram algumas funcionalidades a mais no

funcionamento dos gateways de base dupla. Eles aumentaram o nível de transparência do

processo para o usuário que realiza conexões externas, pois a segunda conexão com o destino

é realizada pelo servidor, além de que o usuário não precisa mais se logar e nem interagir com

o sistema operacional do servidor proxy.

Em um firewall baseado em servidores proxy de aplicativos o usuário se conecta ao

servidor proxy e informa com qual destino deseja se comunicar, o servidor verifica em uma

lista de conexões se a conexão é permitida e, caso for, estabelece a conexão com o destino.

Após isto a conexão entre a origem interna e o destino externo é aparentemente transparente

para o usuário.

Para facilitar o trabalho em proxy de aplicativos é possível substituir os aplicativos

comuns por aplicativos que reconheçam o proxy, neste caso basta o usuário informar ao seu

aplicativo qual o host de destino. O aplicativo realiza a conexão com o proxy e o processo fica

totalmente transparente para o usuário.

O firewall de proxy de aplicativo apresenta uma grande proteção à rede interna pelo

fato de ocultar os hosts internos do mundo exterior, a Internet. Esta proteção não é oferecida

pelos filtros de pacote.

Os servidores proxy mais utilizados são:

a) servidores proxy de aplicação específica: fornecem serviços de proxy para

aplicações específicas. Possibilita um controle mais rigoroso sobre a aplicação que

está controlando, por exemplo, em aplicações de FTP pode permitir o download de

arquivos enquanto proíbe o upload;

b) servidores proxy genéricos: como não é possível existirem servidores de proxy

específicos para cada aplicação, foram desenvolvidos servidores de proxy

genéricos. Sua função é receber solicitações de conexão, verificar se estas conexões

são permitidas e estabelecer as conexões com os verdadeiros destinos.

c) servidores proxy de circuito: esta arquitetura permite que vários host se conectem a

36

vários servidores, através da criação de um circuito virtual fim a fim entre a origem

o e destino.

Algumas desvantagens são observadas nos servidores proxy de aplicativos como a falta

de transparência para realizar conexões e a necessidade, em alguns casos, de aplicativos

modificados para interagirem com o proxy.

3.3.2 CRIPTOGRAFIA

A palavra criptografia significa escrita oculta, e é o ato de transformar uma mensagem

em algo incompreensível, de forma que se esta mensagem for interceptada em algum ponto

entre a origem e o destino ela não poderá ser interpretada pelo cracker. Segundo Oliveira

(2000), a criptografia é uma das melhores formas de garantir a confidencialidade das

informações de trafegam pela Internet.

A criptografia de dados é feita através de algoritmos que realizam o ciframento e o

deciframento dos dados. O algoritmo pode ser amplamente conhecido, pois a segurança do

sistema está em uma chave numérica utilizada para cifrar e decifrar os dados. Mesmo que os

dados sejam interceptados e o algoritmo seja conhecido, os dados só poderão ser interpretados

se o cracker conhecer a chave que deve ser utilizada para decifrar os dados.

Os algoritmos de criptografia podem ser:

a) simétricos: utilizam a mesma chave para realizar o ciframento e o deciframento dos

dados. Um exemplo de algoritmo simétrico é o DES (Data Encryption Standard).

b) assimétricos: utilizam chaves diferentes para realizar o ciframento e o deciframento

dos dados, porém sempre existe uma relação entre as duas chaves. Como exemplo

de algoritmo assimétrico temos o RSA (Rivest, Shamir and Adleman)

Um possível problema causado pelo uso intensivo de criptografia é a queda de

performance nas aplicações. Dependendo do algoritmo e do tamanho da chave utilizados, o

processo de ciframento e deciframento dos dados pode ser um pouco demorado. Se muitos

dados estiverem criptografados este tempo pode ser percebido na aplicação.

37

3.3.3 OUTRAS MEDIDAS DE SEGURANÇA

A utilização de firewalls e a criptografia diminuem bastante as chances de um ataque,

no entanto devem ser combinadas a algumas técnicas e medidas simples de segurança, tanto

internas quanto externas, para que possíveis vulnerabilidades sejam eliminadas e a segurança

dos dados e da rede seja ainda maior.

Estas medidas podem ir desde a conscientização de usuários para a execução de

procedimentos mais seguros, até a utilização de ferramentas que auxiliam na proteção a certos

ataques, estas medidas são:

a) forçar os usuários a utilizarem senhas seguras, que não sejam de fácil adivinhação, e

também forçar a troca das senhas periodicamente;

b) conscientizar os usuário a não baixarem arquivos e a não abrirem anexos em E-mail

de procedência suspeita;

c) manter sempre atualizadas versões de drivers e aplicativos, de forma a eliminar

possíveis vulnerabilidades de versões antigas;

d) utilizar ferramentas que detectam e eliminam cavalos de tróia e portas dos fundos

conhecidas;

e) eliminar serviços que não sejam realmente necessários para a empresa;

f) eliminar contas de usuário expiradas ou inativas;

g) inscrever-se em listas de discussão sobre segurança de rede, de forma a estar sempre

atualizado sobre as últimas vulnerabilidades descobertas e como corrigi-las;

h) utilizar tecnologias de rede que não enviem os pacotes para todas as partes de uma

rede de meio físico compartilhado.

3.3.4 MONITORAÇÃO E LOGS

Proteger uma rede, servidor ou host de forma a garantir que este esteja totalmente

seguro é algo muito difícil, os próprios sistemas de segurança podem conter vulnerabilidades

que prejudicam a segurança, além do que novas técnicas de ataque surgem constantemente.

Portanto a utilização de ferramentas de monitoração e log para detectar e conter

invasões, o mais rápido possível, é uma forma de minimizar os possíveis prejuízos causados

38

por uma invasão. Além do que se não forem utilizadas tais ferramentas, um invasor que tiver

obtido acesso não autorizado à rede pode jamais ser descoberto.

Ferramentas de monitoração e log também podem apresentar um quadro geral sobre a

integridade dos mecanismos de segurança instalados. Se algo errado aparecer em um log

significa de existem brechas nos mecanismos de segurança, com base nos logs estas brechas

podem ser identificadas e corrigidas, evitando assim futuros ataques.

A utilização de recursos de log de rede oferece informações úteis para identificar se

ocorreu ou está ocorrendo uma invasão. Analisando um log alguns itens podem indicar fortes

indícios de que ouve um ataque, estes itens são:

a) horário de utilização atípico;

b) padrões de utilização suspeitos e erros atípicos;

c) lacunas em logs do sistema;

d) conexões em portas atípicas;

e) aparecimento de endereços suspeitos.

Muitos sistemas operacionais e firewalls oferecem recursos de logs, estes recursos não

são totalmente confiáveis, pois por serem extremamente conhecidos podem ser alterados

pelos invasores, de tal forma que não apresentem informações que denunciem uma invasão.

Sendo assim o uso de ferramentas de log independentes é extremamente importante para

garantir a integridade dos dados apresentados pelos logs.

Recursos de monitoração apresentam algumas funcionalidades a mais sobre os

recursos de log. Algumas ferramentas de monitoração reconhecem padrões de ataque e podem

ser configuradas com parâmetros que indiquem a ocorrência de situações suspeitas. Quando

ocorrerem as situações previamente informadas a ferramenta de monitoração emite um alerta,

avisando o administrador da rede que situações suspeitas estão ocorrendo. O administrador

pode então analisar os logs emitidos pelo monitor e verificar se realmente está ocorrendo um

ataque, tomando assim as providências necessárias. Ferramentas de monitoração tornam a

descoberta de um ataque mais rápida em vista de simples ferramentas de log.

39

4 TECNOLOGIAS UTILIZADAS NO PROTÓTIPO

Para que o protótipo desenvolvido neste trabalho execute a tarefa de monitoração dos

pacotes é necessário que o mesmo estabeleça, de alguma forma, uma comunicação com o

dispositivo de hardware que está recebendo tais dados. Os sistemas operacionais que operam

em modo protegido, como é o caso do Windows 98, impedem que aplicativos acessem

diretamente dispositivos de hardware. Nestes sistemas operacionais somente programas que

rodam em um nível privilegiado de execução podem acessar dispositivos de hardware ou

estruturas do sistema operacional. Uma visão geral da arquitetura do sistema operacional

Windows 98 que demonstra esta característica é apresentada na Figura 6.

Figura 6: Visão geral da arquitetura do Windows 98.

Conforme visto na Figura 6, os programas que rodam em um nível privilegiado de

execução e podem acessar diretamente dispositivos de hardware são chamado de drivers de

dispositivo (arquivos com a extensão VxD), estes programas podem tanto acessar dispositivos

Aplicativos

Ferramentas de interface com o usuário

Núcleo do Windows 98

Virtual

Machine

Manager

Installable File

System Manager

Configuration

Manager

Drivers de Dispositivo

Hardware

40

de hardware como simular a existência de tais dispositivos, de forma que um aplicativo possa

interagir com um hardware que na verdade não existe.

Os drivers de dispositivo podem oferecer serviços para a manipulação de dispositivos

de hardware. Os serviços que um driver de dispositivo oferece podem estar acessando

diretamente o dispositivo de hardware ou utilizando os serviços de algum outro driver de

dispositivo para isto.

Os programas aplicativos que desejam interagir com algum dispositivo de hardware

devem faze-lo através de um driver de dispositivo que ofereça serviços para a manipulação de

tal hardware, conforme demonstrado na Figura 7.

Figura 7: Programa aplicativo acessando um hardware

Aplicativo deseja realizar acesso de I/O.

Aplicativo se conecta a um driver de

dispositivo.

Aplicativo solicita serviços do driver de

dispositivo, que tem privilégio alto e que pode

realizar o acesso de I/O propriamente dito.

Vxd realiza o acesso de I/O e devolve ao

aplicativo dados lidos da porta.

41

Sendo assim o protótipo é composto por um programa aplicativo e um driver de

dispositivo. O aplicativo utiliza serviços oferecidos pelo driver de dispositivo, que roda em

um nível de código privilegiado e pode acessar estruturas que o aplicativo não poderia. O

driver de dispositivo desenvolvido no protótipo, por sua vez, não interage diretamente com o

dispositivo de hardware, ao invés disto ele utiliza serviços de um outro driver de dispositivo

oferecido pelo sistema operacional Windows 98, o Ndis.vxd. Este driver oferece serviços

específicos para manipulação de dispositivos de rede, através de uma API chamada NDIS.

A NDIS é uma interface padrão para a comunicação dos drivers de placa de adaptador

de rede com os drivers de protocolo e o sistema operacional. A Figura 8 apresenta a

arquitetura de comunicação serial no Windows 98 e a localização do driver Ndis.vxd nesta

arquitetura.

Figura 8: Transmissão serial de dados no Windows 98.

O Ndis.vxd implementa a interface NDIS e realiza a comunicação entre o protocolo

TCP/IP (driver Tcp.vxd) e o protocolo de comunicação serial PPP, implementado no driver

Pppmac.vxd.

42

Duas tecnologias utilizadas no protótipo devem ser apresentadas com maior

profundidade:

a) a comunicação do programa aplicativo com o driver de dispositivo desenvolvido no

protótipo, utilizando funções da API do Windows 98;

b) a comunicação do driver de dispositivo desenvolvido no protótipo com o driver de

dispositivo Ndis.vxd, utilizando funções da NDIS;

Estas duas tecnologias serão vistas nos tópicos a seguir.

4.1 UTILIZAÇÃO DA API DO WINDOWS 98

A API do Windows 98 disponibiliza funções para que um programa aplicativo possa

abrir, utilizar serviços e fechar um driver de dispositivo, desde que tal driver esteja preparado

para oferecer serviços à programas aplicativos.

Para um programa aplicativo carregar um driver de dispositivo basta utilizar a função

CreateFile e especificar qual driver deseja abrir, se o driver suportar esta operação a função

CreateFile irá retornar um código que representa o driver que acabou de ser aberto, este

código é chamado de Handle. Se o driver não puder ser aberto por um programa aplicativo a

função CreateFile irá retornar um código nulo.

A utilização de serviços oferecidos pelo driver de dispositivo é feita através da função

DeviceIoControl. O programa aplicativo deve chamar esta função e passar através dela um

parâmetro (código de controle) para o driver de dispositivo, quando o driver de dispositivo

receber o código de controle, se suportar tal código, irá realizar a operação definida para o

respectivo código.

A função DeviceIoControl recebe como parâmetro uma estrutura chamada

Overlapped, esta estrutura controla operações de I/O assíncronas entre o programa aplicativo

e o driver de dispositivo. Dentro do Overlapped existe uma outra estrutura chamada de

evento, quando o evento está “não-setado” significa que o processo associado a este evento

não foi completo, quando o evento está “setado” significa que o processo foi concluído.

Quando a função DeviceIoControl retorna um código indicando que a operação está

pendente o aplicativo precisa ficar esperando que o processo solicitado seja concluído, ou

43

seja, o evento passe para o estado de “setado”. Para esperar o resultado de uma comunicação

assíncrona é utilizada a função GetOverlappedResult.

Para fechar o driver basta utiliza a função CloseHandle para fechar o handle do driver

que havia sido aberto anteriormente.

Maiores informações sobre funções da API do Windows podem ser encontradas no

Microsoft Developer Network (MICROSOFT, 2000a).

4.2 UTILIZAÇÃO DA API DA NDIS

A NDIS permite o desenvolvimento de três tipos específicos de driver, conforme

demonstrado na Figura 9.

Figura 9: Drivers oferecidos pela NDIS.

De acordo com a Figura 9 os drivers oferecidos pela NDIS são:

a) driver NDIS de miniporta: é o driver de mais baixo nível suportado pela NDIS. Este

tipo de driver tem como função principal gerenciar o funcionamento algum tipo de

dispositivo físico de rede (hardware). Além disto neste driver devem ser

Driver Intermediário NDIS

Driver NDIS de mini-porta

NDIS

Dispositivo físico de rede

Driver de Protocolo NDIS

44

implementadas funções que permitam a comunicação com outros drivers de mais

alto nível;

b) driver NDIS intermediário: por ser um driver situado em uma posição

intermediária, este tipo de driver pode se comunicar com drivers de miniporta e

drivers de protocolo. Um driver intermediário não precisa gerenciar um dispositivo

físico de rede, ele utiliza funções de drivers de miniporta para se comunicar com o

dispositivo de rede, abstraindo detalhes do gerenciamento do dispositivo. Um driver

intermediário NDIS pode ser utilizado para fornecer dispositivos de rede virtuais

para os drivers de mais alto nível ou para fazer conversão de dados entre diferentes

tipos de protocolos de rede;

c) driver de protocolo NDIS: é o driver de mais alto nível suportado pela NDIS. Este

tipo de driver tem a capacidade de enviar e receber pacotes solicitados por uma

aplicação, ele registra funções na NDIS que são chamadas quando determinados

eventos ocorrem.

Para o desenvolvimento do protótipo deste trabalho foi implementado um driver de

protocolo NDIS, que é notificado cada vez que o dispositivo de rede recebe um novo pacote.

Mais detalhes sobre os driver de protocolo NDIS serão apresentados na próxima seção.

4.2.1 DRIVER DE PROTOCOLO NDIS

Para que seja desenvolvido um driver de protocolo NDIS, e o mesmo funcione

corretamente, é necessário seguir o formato exigido pela NDIS para este tipo de driver.

Na inicialização do driver é necessário que exista uma função que tenha

obrigatoriamente o nome “DriverEntry” e os parâmetros definidos pela NDIS. Esta função

tem o objetivo de determinar as características do driver de protocolo que esta iniciando e

registrar o driver na NDIS. Para registrar o driver de protocolo na NDIS é utilizada a função

NdisRegisterProtocol da API da NDIS.

Nas características do driver de protocolo, passadas para a NDIS quando o protocolo é

registrado, são definidas várias funções que compõem o protocolo. Algumas destas funções

são chamadas pelo driver para fazer com que o protocolo execute certas operações, e outras

são chamadas pela NDIS quando determinados eventos ocorrem.

45

As funções que devem ser definidas nas características do protocolo são:

a) BindAdapterHandler: esta função é chamada pelo driver e deve realizar a conexão

entre o protocolo e um adaptador de rede através da função NdisOpenAdapter. Se a

solicitação de conexão retornar pendente, a NDIS irá chamar a função definida em

OpenAdapterCompleteHandler para completar a conexão, quando a solicitação

tiver sido processada por completo;

b) UnbindAdapterHandler: esta função é chamada pelo driver e deve realizar a

desconexão do protocolo com o adaptador de rede através da função

NdisCloseAdapter. Se a solicitação de desconexão retornar pendente, a NDIS irá

chamar a função definida em CloseAdapterCompleteHandler para completar a

desconexão, quando a solicitação tiver sido processada por completo;

c) OpenAdapterCompleteHandler: esta função é chamada pela NDIS quando uma

solicitação de conexão com um adaptador for completada, após a função

NdisOpenAdapter ter indicado que a conexão havia ficado pendente;

d) CloseAdapterCompleteHandler: esta função é chamada pela NDIS quando uma

solicitação de desconexão de um adaptador for completada, após a função

NdisCloseAdapter ter indicado que a desconexão havia ficado pendente;

e) RequestCompleteHandler: esta função é chamada pela NDIS quando uma operação

de requisição à NDIS for completada, após a função NdisRequest ter indicado que a

operação de requisição havia ficado pendente;

f) ReceiveHandler: esta função é chamada pela NDIS quando o adaptador de rede a

que o protocolo está conectado receber um pacote. Caso o pacote ainda não tenha

sido recebido por completo, esta função deve chamar a função NdisTransferData.

Se a operação de transferência do resto dos dados do pacote retornar pendente, a

NDIS irá chamar a função definida em TransferDataCompleteHandler quando a

operação tiver sido processada por completo;

g) ReceiveCompleteHandler: esta função é chamada pela NDIS para realizar algum

tipo de pós-processamento nos pacotes que já foram recebidos pela função definida

em ReceiveHandler. Quando ReceiveCompleteHandler é chamado, todos os pacotes

recebidos até aquele momento podem ser pós-processados;

h) TransferDataCompleteHandler: esta função é chamada pela NDIS quando uma

operação de transferência de dados de um pacote for completada, após a função

46

NdisTransferData ter indicado que a operação de transferência havia ficado

pendente;

i) SendCompleteHandler: esta função é chamada pela NDIS quando uma operação de

envio de pacote for completada, após a função NdisSend ter indicado que a conexão

havia ficado pendente;

j) ResetCompleteHandler: esta função é chamada pela NDIS quando uma operação de

reset for completada, após a função NdisReset ter indicado que a operação de reset

havia ficado pendente;

k) StatusHandler: esta função é chamada pela NDIS quando o status da NDIS ou do

driver intermediário são alterados;

l) StatusCompleteHandler: esta função é chamada pela NDIS quando for completada

a alteração do status da NDIS ou do driver intermediário;

m) UnloadProtocolHandler: esta função é chamada pela NDIS após uma chamada da

função definida em UnbindAdapterHandler. Ela deve fazer uma chamada da função

NdisDeregisterProtocol para remover o registro do protocolo na NDIS.

Após definir cada uma das funções apresentadas acima, basta chamar a função que

conecta o protocolo a um adaptador de rede e as funções do protocolo começarão a serem

chamadas pela NDIS conforme os eventos forem ocorrendo.

Para finalizar o funcionamento do protocolo basta chamar a função que desconecta o

protocolo do adaptador de rede.

Maiores informações sobre drivers NDIS podem ser encontradas no site da Microsoft

junto à documentação do Microsoft Driver Development Kit (MICROSOFT; 1999b, 2000b).

47

5 DESENVOLVIMENTO DO PROTÓTIPO

O protótipo desenvolvido neste trabalho é uma ferramenta de monitoração de

datagramas IP. Esta ferramenta deve ser utilizada em um host ligado a uma rede que utilize o

protocolo TCP/IP (a rede utilizada para desenvolver o protótipo foi a Internet).

Todos os datagramas que trafegarem entre o host e a Internet passarão pelo monitor,

que irá analisar os datagramas e informar o administrador da rede caso ocorram situações

suspeitas de ataque. Auxiliando assim o administrador de rede na segurança do host.

Neste capítulo serão demonstrados detalhes e considerações relevantes sobre o

desenvolvimento do protótipo.

5.1 REQUISITOS PRINCIPAIS DO PROTÓTIPO

Para a realização do processo de especificação, foram levantados alguns requisitos que

devem estar presentes no protótipo. Estes requisitos demonstram algumas características que

o protótipo precisa ter para que se alcance o resulta final desejado.

Os requisitos principais do protótipo são:

a) será desenvolvido para operar sobre o sistema operacional Windows 98;

b) irá monitorar uma conexão com a Internet através de acesso discado;

c) o acesso discado deve utilizar o protocolo PPP para controlar a comunicação serial;

d) utilizará a interface NDIS do Windows 98 para capturar os pacotes;

e) a rede física será considerada uma rede Ethernet, portanto os pacotes capturados

estarão no formado de um quadro Ethernet;

f) serão capturados todos os pacotes que passarem pela camada de interface de rede do

host em que o protótipo está instalado;

g) todos os pacotes capturados serão adicionados em um log;

h) haverá três níveis de visualização dos logs:

- simples: são visualizadas apenas as informações de origem e destino do pacote;

- parcial: além das informações de origem e destino, são visualizadas outras

informações relativas ao pacote;

- completo: são visualizadas todas as informações do cabeçalho do pacote;

i) haverá cinco formas de agrupamento dos dados do log:

48

- IP origem e porta origem;

- IP destino e porta destino;

- IP remoto e porta local;

- porta local e IP remoto;

- sem agrupamento;

j) o usuário poderá configurar situações de alerta;

k) serão consideradas duas variáveis na configuração de situações suspeitas:

- portas locais;

- endereços IP remotos;

l) todos os pacotes capturados devem ser submetidos às situações de suspeita

configuradas pelo usuário;

m) haverá um log à parte contendo somente pacotes que geraram alertas;

n) todos os tipos de log poderão ser salvos em arquivos e recuperados posteriormente,

caso haja necessidade.

5.2 ESPECIFICAÇÃO DO PROTÓTIPO

A especificação do protótipo foi realizada visando a divisão do mesmo em dois

módulos com funções bem distintas:

a) módulo aplicação: responsável pelo tratamento dos pacotes recebidos e pela

interface com o usuário;

b) módulo driver: responsável por interagir com o sistema operacional, de forma a

receber os pacotes de rede e passa-los para a aplicação.

A metodologia de especificação utilizada para representar os processos que formam o

protótipo foi a fluxogramação. Para auxiliar na construção dos fluxogramas utilizados na

especificação do protótipo foi utilizada a ferramenta Microsoft Visio 2000.

A seguir será apresentada a especificação primeiramente do módulo aplicação e

posteriormente do módulo driver.

49

5.2.1 ESPECIFICAÇÃO DO MÓDULO APLICAÇÃO

A especificação do módulo aplicação foi dividida em onze processos e sub-processos

que estão envolvidos nas funções principais de ativar o monitor, desativar o monitor e receber

e tratar pacotes.

Neste capítulo será apresentada a especificação detalhada dos principais processos do

módulo aplicação, os processos que não forem apresentados aqui poderão ser encontrados no

Anexo 1.

Na Tabela 3 são enumerados os processos do módulo aplicação juntamente com a

descrição de cada um deles.

Tabela 3: Processos do módulo aplicação.

Nome do processo Descrição do processo Processo A Ativar monitor Processo B Desativar monitor Processo C Leitura de pacotes Processo D Abrir adaptador Processo E Fechar adaptador Processo F Setar filtro Processo G Receber pacote Processo H Adicionar no log Processo I Verificar alertas Processo J Alocar pacote Processo K Desalocar pacote

Na Figura 10 é apresentada uma visualização geral do módulo aplicação. Nesta figura

podemos observar a relação entre os processos especificados para o módulo aplicação.

50

Figura 10: Visualização geral do módulo aplicação.

Os processos A, B e C são ativados diretamente pelo usuário e dão origem as

chamadas dos outros processos. De acordo com a Figura 10, o processo A, que trata da

ativação do monitor, está relacionado principalmente com os processos D, F e J. O processo

B, que trata da desativação do monitor, está relacionado com os processos E e K. E o processo

C, que trata da leitura de pacotes, está relacionado principalmente como os processos G, H e I.

As figuras abaixo apresentam a especificação detalhada dos processos A, D, B, E, C e

G, em forma de fluxograma. Após cada figura é apresentada uma descrição dos componentes

do respectivo processo.

51

Figura 11: Fluxograma do processo A (Ativar Monitor).

Descrição dos componentes do processo A:

a) abrir adaptador de rede: chamada do processo D, para que seja feita a conexão com

o adaptador de rede. Para maiores detalhes ver a Figura 12;

b) setar modo de filtragem do adaptador: chamada do processo F, informando o

mesmo que o adaptador de rede deve ser colocado em modo promíscuo. Para

maiores detalhes ver a Figura 31;

c) alocar pacote: chamada do processo J, para que seja feita a alocação da estrutura

que irá receber os pacotes. Para maiores detalhes ver a Figura 34;

d) fechar o adaptador de rede: caso ocorra algum erro e o adaptador já tenha sido

aberto será feita uma chamada do processo E, para que seja feita a desconexão com

o adaptador de rede. Para maiores detalhes ver a Figura 14;

e) inicializar dados do contexto: estabelece valores iniciais a serem utilizados

internamente pelo módulo aplicação;

f) ativar processo de leitura de pacotes: ativa o funcionamento do processo C, de

forma que o monitor comece a receber os pacotes que estão trafegando.

52

Figura 12: Fluxograma do processo D (Abrir Adaptador).

Descrição dos componentes do processo D:

a) alocar memória para o adaptador: aloca memória para uma estrutura que irá

armazenar informações sobre o adaptador que está sendo aberto;

b) carregar driver Monitor.vxd: inicia o funcionamento do driver monitor de pacotes,

que será utilizado também por outros processos;

c) criar evento: cria uma estrutura que irá controlar a comunicação assíncrona de

abertura do adaptador entre o módulo aplicação e o módulo driver;

d) enviar código para o módulo driver se conectar ao adaptador: solicita ao módulo

driver a conexão com o adaptador de rede, desta solicitação poderá retornar um

indicativo que o processo ainda está pendente, ou seja, o módulo driver ainda não

53

terminou a conexão com o adaptador de rede. Para maiores informações ver a

Figura 39, que faz parte da especificação do módulo driver;

e) aguardar término do processo (evento): caso a solicitação de conexão tenha ficado

pendente, o módulo aplicação ficará aguardando que o evento de controle da

comunicação assíncrona indique que a solicitação terminou de ser processada;

f) descarrega driver: caso ocorra algum erro após a carga do módulo driver

Monitor.vxd, o módulo driver será descarregado;

g) liberar memória do adaptador: caso ocorra algum erro após a alocação de memória

para o adaptador, esta memória será liberada.

Figura 13: Fluxograma do processo B (Desativar Monitor).

Descrição dos componentes do processo B:

a) encerrar processo de leitura: se o processo de leitura estiver ativo, ou seja, o módulo

monitor está recebendo pacotes, então o processo de leitura será encerrado, e o

módulo monitor não irá mais receber os pacotes que estão trafegando;

b) fechar adaptador: chamada do processo E, para que seja feita a desconexão com o

adaptador de rede. Para maiores informações ver a Figura 14;

c) liberar pacote: chamada do processo K, para seja feita a liberação da estrutura que

recebe os pacotes. Para maiores informações ver a Figura 35;

d) liberar estrutura do contexto: libera os recursos utilizado na estrutura de contexto do

módulo monitor;

e) liberar processo de leitura: finaliza totalmente o processo de leitura, retirando-o da

memória.

54

Figura 14: Fluxograma do processo E (Fechar Adaptador).

Descrição dos componentes do processo E:

a) criar evento: cria uma estrutura que irá controlar a comunicação assíncrona de

fechamento do adaptador entre o módulo aplicação e o módulo driver;

b) enviar código para o driver se desconectar do adaptador: solicita ao módulo driver a

desconexão com o adaptador de rede, desta solicitação poderá retornar um

indicativo que o processo ainda está pendente, ou seja, o módulo driver ainda não

terminou a desconexão com o adaptador de rede. Para maiores informações ver a

Figura 40, que faz parte da especificação do módulo driver;

c) aguarda término do processo (evento): caso a solicitação de desconexão tenha

ficado pendente, o módulo aplicação ficará aguardando que o evento de controle da

comunicação assíncrona indique que a solicitação terminou de ser processada;

d) descarrega driver: fecha o módulo driver e o retira da memória;

e) libera memória do adaptador: libera a memória utilizada para guardar informações

do adaptador de rede.

55

Figura 15: Fluxograma do processo C (Leitura dos pacotes).

Descrição dos componentes do processo C:

a) receber pacote: se o processo de leitura ainda não tiver sido encerrado, então é feita

uma chamada do processo G, para que seja recebido um pacote. Para maiores

detalhes ver a Figura 16;

b) adicionar pacote no log: após receber um pacote, se a estrutura que armazena o

pacote recebido ainda estiver alocada, então será feita uma chamada do processo H,

para que o pacote seja adicionado no log do monitor de pacotes. Para maiores

detalhes ver a Figura 32;

c) verificar condições de alerta: se o pacote recebido for um pacote IP, então será feita

uma chamada do processo I, para que seja verificado se este pacote deve gerar um

alerta. Para maiores detalhes ver a Figura 33.

56

Figura 16: Fluxograma do processo G (Receber Pacote).

Descrição dos componentes do processo G:

a) inicializa evento do pacote: seta o evento do pacote, que foi criado quando o pacote

foi alocado, para indicar que será iniciado um novo processo de comunicação

assíncrona com este evento;

b) envia código para o driver retornar um pacote: solicita ao módulo driver que retorne

um pacote interceptado por ele. Se o módulo driver não tiver nenhum pacote ainda

não lido pelo módulo aplicação esta solicitação irá retornar um indicativo de que o

processo ainda está pendente, pois o módulo driver irá ficar aguardando a chegada

de algum pacote para completar a solicitação que lhe foi feita. Para maiores

informações ver a Figura 21, que faz parte da especificação do módulo driver;

f) aguarda término do processo (evento): caso a solicitação para receber um pacote

tenha ficado pendente, o módulo aplicação ficará aguardando que o evento de

controle da comunicação assíncrona indique que a solicitação terminou de ser

processada.

5.2.2 ESPECIFICAÇÃO DO MÓDULO DRIVER

A especificação do módulo driver foi dividida em dezesseis processos e sub-processos

que estão envolvidos nas funções principais de inicializar o funcionamento do módulo driver,

57

tratar solicitações de conexão, desconexão, filtro e recebimento de pacotes, e finalizar o

funcionamento do módulo driver.

A seguir será apresentada a especificação detalhada dos principais processos do

módulo driver, os processos que não forem apresentados aqui poderão ser encontrados no

Anexo 2.

Na Tabela 4 são enumerados os processos do módulo driver juntamente com a

descrição de cada um deles.

Tabela 4: Processos do módulo driver.

Nome do processo Descrição do processo Processo A Carga do driver Processo B Procedimento de controle Processo C Inicialização Processo D Trata códigos de controle Processo E Trata código de conexão Processo F Trata código de desconexão Processo G Trata código para setar filtro Processo H Trata código para receber pacotes Processo I Protocolo se conecta ao adaptador Processo J Conecta adaptador completado Processo K Protocolo se desconecta ao adaptador Processo L Desconecta adaptador completado Processo M Requisição completada Processo N Protocolo recebe pacotes Processo O Transferência de dados completada Processo P Protocolo se descarrega

Na Figura 17 é apresentada uma visualização geral do módulo driver. Nesta figura

podemos observar a relação entre os principais processos especificados para o módulo driver.

Os processo B e P não estão descritos na visualização geral, pois o processo B é apenas

ponte para a chamada dos processos C e D (ver Figura 37) e o processo P é apenas a chamada

de uma função para finalizar o protocolo (ver Figura 46). Sendo assim ambos podem ser

omitidos neste momento, para favorecer a visualização geral do módulo.

58

Figura 17: Visualização geral do módulo driver.

Os processos do módulo driver são ativados pela carga do driver por parte do módulo

aplicação e por códigos enviados também do módulo aplicação para o módulo driver.

Os processos A e C são chamados um após o outro quando a aplicação realiza a carga

do módulo driver. O processo D é ativado quando o módulo aplicação envia um código de

solicitação para o módulo driver, este processo é responsável por chamar os processo E, F, G

e H. Os processos I, J, K, L e M são eventos do driver de protocolo definido pelo módulo

driver, e são chamados quando o respectivo evento ocorrer.

Finalmente, o processo N é chamado pelo driver do adaptador de rede quando um

pacote chega ao adaptador. Este processo é responsável pela chamada do processo O.

As figuras a seguir apresentam a especificação detalhada dos processos C, I, K, H, N e

O, em forma de fluxograma. Após cada figura é apresentada uma descrição dos componentes

do respectivo processo.

Figura 18: Fluxograma do processo C (Inicialização).

59

Descrição dos componentes do processo C:

a) seta características do driver de protocolo: seta informações necessárias para que o

driver de protocolo seja registrado na NDIS;

b) registra o driver de protocolo na NDIS: informa à NDIS que existe um driver de

protocolo ativo. A partir deste momento a NDIS irá considerar este driver nos seus

tratamentos.

Figura 19: Fluxograma do processo I (Protocolo se conecta ao adaptador).

60

Descrição dos componentes do processo I:

a) inicializa dados do contexto: inicializa informações utilizadas internamente por

outros processos do módulo driver;

b) aloca conjunto de pacotes para a NDIS: aloca uma estrutura utilizada pela NDIS

para receber seus pacotes;

c) aloca conjunto de buffers para a NDIS: aloca uma estrutura utilizada pela NDIS

para receber seus pacotes;

d) solicita à NDIS que se conecte ao adaptador: solicita à NDIS que estabeleça uma

conexão entre o driver de protocolo e o adaptador de rede;

e) chama a função do protocolo para completar a conexão: caso a solicitação de

conexão com o adaptador de rede não tenha retornado pendente, ou seja, a

solicitação foi completada por parte da NDIS, então é feita uma chamada do

processo J, que irá completar a conexão entre o protocolo e o adaptador. Se a

solicitação de conexão a NDIS retornar pendente, o processo I não deve fazer uma

chamada do processo J, pois esta chamada será feita internamente pela NDIS

quando a solicitação for completada. Para ver maiores detalhes sobre o processo J

61

consulte a Figura 42;

f) libera conjunto de pacotes da NDIS: se ocorrer algum erro após a alocação conjunto

de pacotes da NDIS, esta estrutura será desalocada;

g) libera memória do contexto: se ocorrer algum erro ao tentar se conectar ao

adaptador, a memória para o contexto do módulo driver, que foi alocada no

processo E (ver Figura 39), deve ser desalocada.

Figura 20: Fluxograma do processo K (Protocolo se desconecta do adaptador).

Descrição dos componentes do processo K:

a) solicita à NDIS que se desconecte do adaptador: solicita à NDIS que destrua a

conexão que existia entre o protocolo e o adaptador;

b) chama função do protocolo para completar a desconexão: caso a solicitação de

desconexão com o adaptador de rede não tenha retornado pendente, ou seja, a

solicitação foi completada por parte da NDIS, então é feita uma chamada do

processo L, que irá completar a desconexão entre o protocolo e o adaptador. Se a

solicitação de desconexão a NDIS retornar pendente, o processo K não deve fazer

uma chamada do processo L, pois esta chamada será feita internamente pela NDIS

quando a solicitação for completada. Para ver maiores detalhes sobre o processo L

consulte a Figura 43.

Figura 21: Fluxograma do processo H (Trata código para receber pacote).

62

Descrição dos componentes do processo H:

a) coloca o pacote em situação pendente: se a lista de pacotes recebidos pelo protocolo

estiver vazia o pacote que está fazer a solicitação irá ficar aguardando (pendente)

que algum pacote chegue para poder ser liberado;

b) copia um pacote da lista: se a lista de pacotes recebidos pelo protocolo não estiver

vazia, é copiado um pacote desta lista para o pacote que está fazendo a solicitação;

c) posiciona no próximo da lista: a lista é posicionada no próximo elemento, para

quando for feita uma nova solicitação de recebimento de pacote por parte da

aplicação.

Figura 22: Fluxograma do processo N (Protocolo recebe pacote).

63

Descrição dos componentes do processo N:

a) aloca um pacote para a NDIS: aloca uma estrutura (pacote) utilizada internamente

64

pela NDIS para transferência de dados;

b) aloca um buffer para a NDIS: aloca uma estrutura (buffer) utilizada internamente

pela NDIS para transferência de dados;

c) solicita à NDIS a transferência do resto dos dados do pacote: se o pacote recebido

pelo processo N ainda não havia chegado completamente (tamanho do pacote >

bytes existentes no buffer) então é necessário fazer esta solicitação à NDIS, para

que o resto dos dados do pacote sejam transferidos para o buffer;

d) chama a função do protocolo para completar a transferência: caso a solicitação de

transferência de dados não tenha retornado pendente, ou seja, a solicitação foi

completada por parte da NDIS, então é feita uma chamada do processo O, que irá

completar a transferência dos dados. Se a solicitação de transferência dos dados

feita a NDIS retornar pendente, o processo N não deve fazer uma chamada do

processo O, pois esta chamada será feita internamente pela NDIS quando a

solicitação for completada. Para ver maiores detalhes sobre o processo O consulte a

Figura 45;

e) reinicializa o pacote NDIS: caso ocorra algum erro após a alocação da estrutura de

pacote da NDIS, é necessário que esta estrutura seja reinicializada;

f) libera o pacote NDIS: após a estrutura de pacote da NDIS ser reinicializada, esta

estrutura pode ser liberada;

g) copia dados para o pacote pendente: se o pacote recebido pelo processo N já estiver

completo no buffer (tamanho do pacote <= bytes existentes no buffer), então este

pacote já pode ser utilizado. Sendo assim, caso exista um pacote do módulo

aplicação esperando a chegada de dados no módulo driver, os dados são copiados

para este pacote;

h) libera o pacote pendente: após a cópia dos dados, o pacote do módulo aplicação que

estava pendente é liberado;

i) copia dados para a lista de pacotes recebidos: caso não exista um pacote do módulo

aplicação pendente, então os dados que acabaram de ser recebidos pelo protocolo

do módulo driver são copiados para uma lista de pacotes recebidos;

j) posiciona no próximo elemento da lista: posiciona a lista de pacotes recebidos no

próximo elemento, para receber mais um pacote na próxima chamada do processo

N.

65

5.3 IMPLEMENTAÇÃO

A seguir serão apresentadas considerações sobre a implementação do protótipo, como

também as ferramentas que foram utilizadas na implementação, tanto do módulo aplicação

quanto do módulo driver. Também serão apresentadas as principais funções que compõem o

protótipo e o funcionamento do mesmo.

5.3.1 FERRAMENTAS UTILIZADAS NA IMPLEMENTAÇÃO

A implementação do módulo aplicação foi desenvolvida na linguagem ObjectPascal

utilizando para tal implementação o ambiente de desenvolvimento Borland Delphi 5.0. O

módulo aplicação utiliza funções da API do sistema operacional Windows 98 para realizar a

comunicação com o módulo driver.

A implementação do módulo driver obedece a um formato muito específico exigido

pelo sistema operacional, para tanto, parte do código foi escrita na linguagem assembly e

outra parte na linguagem C.

Na implementação do módulo driver foram utilizados recursos da ferramenta

Microsoft DDK (Driver Development Kit) 98. Esta ferramenta provê recursos para o

desenvolvimento de drivers para o sistema operacional Windows 98. Os principais recursos

oferecidos pelo Microsoft DDK 98 são:

a) exemplos dos tipos de driver e de funções disponíveis;

b) código-fonte de programas que são utilizados no desenvolvimento dos drivers;

c) documentações de como desenvolver os drivers e utilizar funções.

Maiores informações sobre o Microsoft DDK 98 podem ser encontradas em Microsoft

(1999b, 2000b).

Para desenvolver o driver também foi utilizado o ambiente de desenvolvimento

Microsoft Visual C++ 6.0.

5.3.2 PRINCIPAIS FUNÇÕES DO MÓDULO APLICAÇÃO

As funções apresentadas nesta seção correspondem a três processos que realizam

comunicação com o módulo driver, através destes três processos o módulo aplicação solicita

66

ao módulo driver a conexão com o adaptador de rede, a desconexão de tal dispositivo e o

recebimento de pacotes que tenham sido interceptados.

Quadro 2: Implementação referente ao processo D (Abrir adaptador)

//************************************************* ***************************** // AbrirAdaptador - (Processo D) //************************************************* ***************************** function AbrirAdaptador(const NomeAdaptador: String ): Pointer; var xPtrAdaptador: PADAPTADOR; QtdBytesRetornados :Longword; Evento: THANDLE; Ovrlapped: OVERLAPPED; Retorno: boolean; begin Result := nil; xPtrAdaptador := PADAPTADOR(GlobalAllocPtr(GMEM_M OVEABLE or GMEM_ZEROINIT, sizeof(RegAdaptador)) ); if xPtrAdaptador = nil then Exit; lstrcpy(xPtrAdaptador^.LigacaoSimbolica,'\\.\MONI TOR.VXD'); //Cria ou abre um objeto, retornando o handle uti lizado para acessar tal objeto xPtrAdaptador^.Handle := CreateFile( xPtrAdaptador^.LigacaoSimboli ca,//nome do objeto GENERIC_READ or GENERIC_WRITE , //modo de acesso 0, //modo de compartilhamento nil, //atributos de segurança OPEN_EXISTING, //como criar o objeto FILE_ATTRIBUTE_NORMAL or FILE _FLAG_DELETE_ON_CLOSE or FILE_FLAG_OVERLAPPED, //atributos do objeto 0); //h andle para copiar atributos if xPtrAdaptador^.Handle = INVALID_HANDLE_VALUE t hen GlobalFreePtr(xPtrAdaptador) else begin //Cria um objeto de evento Evento := CreateEvent(nil, //atributos de segur ança TRUE, //reset manual do ev ento FALSE,//estado inicial nil); //ponteiro para o no me do objeto if Evento = 0 then begin CloseHandle(xPtrAdaptador^.Handle); GlobalFreePtr(xPtrAdaptador); end else begin Ovrlapped.Internal := 0; Ovrlapped.InternalHigh := 0; Ovrlapped.Offset := 0; Ovrlapped.OffsetHigh := 0; Ovrlapped.hEvent := Evento; //Envia um código de controle para um driver específico Retorno := DeviceIoControl(xPtrAdaptador^.Han dle,//handle do driver IOCTL_MONITOR_LIGA, //código de controle PChar(NomeAdaptador), //buffer enviado Length(NomeAdaptador), //tamanh o do buffer enviado nil, //buffer recebido 0, //tamanh o do buffer recebido

67

QtdBytesRetornados, //qtd by tes retornados @Ovrlapped); //estrut ura de comunicação assíncrona if not Retorno then begin if GetLastError = ERROR_IO_PENDING then Retorno := GetOverlappedResult( //Agu arda o resultado da comunicação

// assíncr ona xPtrAdaptador^.Handle,//han dle do dispositivo Ovrlapped, //est rutura de comunicação assíncrona QtdBytesRetornados, //qtd de bytes aguardados true); //fla g "aguardar" if not Retorno then begin CloseHandle(xPtrAdaptador^.Handle); GlobalFreePtr(xPtrAdaptador); Result := nil; end; end else Result := (xPtrAdaptador); end; end; end;

A implementação apresentada no Quadro 2 é utilizada pelo módulo aplicação para

solicita ao módulo driver a conexão com o adaptador de rede. A especificação deste código-

fonte pode ser vista na Figura 12.

Primeiramente o módulo driver é carregado através do comando CreateFile, após isto

é enviado um código de controle para que o mesmo se conecte ao adaptador através do

comando DeviceIoControl. Se o módulo driver retornar um código de processo pendente o

módulo aplicação irá aguardar o final do processo através do comando GetOverlappedResult.

Quadro 3: Implementação referente ao processo E (Fechar adaptador)

//************************************************* ***************************** // FecharAdaptador - (Processo E) //************************************************* ***************************** procedure FecharAdaptador(Adaptador: PAdaptador); var Evento : THANDLE; Ovrlapped : OVERLAPPED; Retorno : BOOLEAN; QtdBytesRetornados: Longword; begin //Cria um objeto de evento Evento := CreateEvent(nil, //atributos de seguran ça TRUE, //reset manual do even to FALSE,//estado inicial nil); //ponteiro para o nome do objeto if Evento = 0 then raise Exception.Create('Não foi possível fechar adaptador'); Ovrlapped.Internal := 0; Ovrlapped.InternalHigh := 0; Ovrlapped.Offset := 0;

68

Ovrlapped.OffsetHigh := 0; Ovrlapped.hEvent := Evento; //Envia um código de controle para um driver específico Retorno := DeviceIoControl(Adaptador^.Handle, //h andle do driver IOCTL_MONITOR_DESLIGA,//código de co ntrole nil, //buffer enviad o 0, //tamanho do bu ffer enviado nil, //buffer recebi do 0, //tamanho do bu ffer recebido QtdBytesRetornados, //qtd bytes ret ornados @Ovrlapped); //estrutura de comunicação assíncrona if not Retorno then begin if GetLastError = ERROR_IO_PENDING then Retorno := GetOverlappedResult(Adaptador^.Han dle,//handle do dispositivo Ovrlapped, //estrutur a de comunicação assíncrona QtdBytesRetornados, //qtd de b ytes aguardados TRUE); //flag "a guardar" if not Retorno then raise Exception.Create('Ocorreu um erro ao te ntar fechar adaptador'); end; CloseHandle(Adaptador^.Handle); GlobalFreePtr(Adaptador); end;

A implementação apresentada no Quadro 3 é utilizada pelo módulo aplicação para

solicita ao módulo driver a desconexão do adaptador de rede. A especificação deste código-

fonte pode ser vista na Figura 14.

Nesta função o módulo aplicação envia um código de controle para o módulo driver se

desconecte do adaptador através do comando DeviceIoControl. Se o módulo driver retornar

um código de processo pendente o módulo aplicação irá aguardar o final do processo através

do comando GetOverlappedResult.

Quadro 4: Implementação referente ao processo G (Receber pacote)

//************************************************* ***************************** // ReceberPacote - (Processo G) //************************************************* ***************************** procedure ReceberPacote(Adaptador: PAdaptador; Paco te: PPacote); var Retorno: boolean; QtdBytesRetornados: Longword; begin Pacote^.OverLapped.Offset := 0; Pacote^.OverLapped.OffsetHigh := 0; if not ResetEvent(Pacote^.OverLapped.hEvent) then raise Exception.Create('Ocorreu um erro ao rece ber um pacote.'); Retorno := DeviceIoControl(Adaptador^.Handle, IOCTL_MONITOR_RECEBE, nil, 0, Pacote^.Buffer, Pacote^.Length, QtdBytesRetornados,

69

@Pacote^.OverLapped); if not Retorno then begin Retorno := GetOverlappedResult(Adaptador^.Handl e, Pacote^.OverLapp ed, QtdBytesRetornad os, TRUE); if not Retorno then raise Exception.Create('Ocorre uma erro ao re ceber um pacote.'); end; end;

A implementação apresentada no Quadro 4 é utilizada pelo módulo aplicação para

solicitar ao módulo driver o recebimento de um pacote. A especificação deste código-fonte

pode ser vista na Figura 16.

Após enviar um código de controle para o módulo driver solicitando um pacote, se o

processo não ficar pendente, um pacote será retornado no comando DeviceIoControl. Se o

módulo driver retornar um código de processo pendente o módulo aplicação irá aguardar o

final do processo através do comando GetOverlappedResult, ao final do processo será

retornado um pacote para o módulo aplicação em Pacote^.Buffer.

A implementação completa do módulo aplicação pode ser encontrada no Anexo 3.

5.3.3 PRINCIPAIS FUNÇÕES DO MÓDULO DRIVER

Nesta seção serão apresentadas três funções do módulo driver, que correspondem às

funções que tratam os códigos de controle de conexão, desconexão e recebimento de pacote,

enviados pelo módulo aplicação.

Quadro 5: Implementação do processo I (Conecta adaptador)

//************************************************* ***************************** // Proto_ConectaAdaptador - (processo I) //************************************************* ***************************** VOID NDIS_API Proto_ConectaAdaptador( OUT PNDIS_STATUS pStatus, IN NDIS_HANDLE BindContext, IN PNDIS_STRING AdapterName, IN PVOID SystemSpecific1, IN PVOID SystemSpecific2) { NDIS_STATUS CodigoErro; NDIS_MEDIUM MidiaProtocolo = NdisMedium802_3; UINT Indice, MidiaAdaptador; PTR_CONTEXTO PtrContexto = (PTR_CONTEXTO)BindCont ext;

70

//Inicializa pacote travado do contexto PtrContexto->PacoteTravado.Status = STATUS_LIVRE; PtrContexto->PacoteTravado.DadosBuffer = 0; PtrContexto->PacoteTravado.TamanhoBuffer = 0; PtrContexto->PacoteTravado.lpoOvrlapped = 0; //Aloca memoria para pacotes recebidos PtrContexto->Inicio_Lista = 0; PtrContexto->Final_Lista = 0; for (Indice = 0; Indice < TAMANHO_LISTA_RECEBIDOS ; Indice++) { PtrContexto->PacotesRecebidos[Indice].TamanhoBu ffer = 0; PtrContexto->PacotesRecebidos[Indice].Status = STATUS_LIVRE; PtrContexto->PacotesRecebidos[Indice].DadosBuff er = NULL; AlocaMemoria((PVOID *)&PtrContexto->PacotesRece bidos[Indice].DadosBuffer, TAMANHO_MAXIMO_BUFFER); if (PtrContexto->PacotesRecebidos[Indice].Dados Buffer == NULL) { LiberaMemoria((PVOID)PtrContexto); *pStatus = NDIS_STATUS_RESOURCES; return; } } // Aloca conjunto de Pacotes NdisAllocatePacketPool(pStatus, &PtrContexto->ConjuntoPaco tes, 15, sizeof(PACOTE_RESERVADO)); if (*pStatus != NDIS_STATUS_SUCCESS) { LiberaMemoria((PVOID)PtrContexto); return; } // Aloca conjunto de Buffers NdisAllocateBufferPool(pStatus, &PtrContexto->ConjuntoBuff ers, 15); if (*pStatus != NDIS_STATUS_SUCCESS) { NdisFreePacketPool(PtrContexto->ConjuntoPacotes ); LiberaMemoria((PVOID)PtrContexto); return; } NdisOpenAdapter( //Faz a ligação entre o protocol o e um outro driver ou NIC pStatus, //status &CodigoErro, //código do erro &PtrContexto->Adaptador, //handle do adaptado r &MidiaAdaptador, //tipo de mídia do a daptador &MidiaProtocolo, //tipo de mídia do p rotocolo 1, //qtd de mídias do p rotocolo ProtocoloMonitor, //handle do protocol o (NDIS_HANDLE)PtrContexto,//contexto do protoc olo AdapterName, //nome do adaptador - "0000" 0, //opções NULL); //informações do NIC if (*pStatus != NDIS_STATUS_PENDING) Proto_OpenAdapter_Completado((NDIS_HANDLE)PtrCo ntexto, *pStatus, CodigoErro); return; }

A implementação apresentada no Quadro 5 é utilizada pelo módulo driver para tratar o

código de controle de conexão enviado pelo módulo aplicação. Esta função trata dos detalhes

71

exigidos pela NDIS e solicita a mesma que conecte o driver de protocolo ao adaptador de rede

especificado. A especificação desta função pode ser vista na Figura 19.

Quadro 6: Implementação referente ao processo K (Desconecta adaptador)

//************************************************* ***************************** // Proto_DesconectaAdaptador - (processo K) //************************************************* ***************************** VOID NDIS_API Proto_DesconectaAdaptador( OUT PNDIS_STATUS pStatus,

IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE UnbindContext) { PTR_CONTEXTO PtrContexto = (PTR_CONTEXTO)Protoco lBindingContext; //Fecha uma ligação com um adaptador NdisCloseAdapter(pStatus, //retorn a o status PtrContexto->Adaptador);//handle do adaptador if (*pStatus != NDIS_STATUS_PENDING) Proto_CloseAdapter_Completado(PtrContexto, *pSt atus); return; }

A implementação apresentada no Quadro 6 é utilizada pelo módulo driver para tratar o

código de controle de desconexão enviado pelo módulo aplicação. A única função desta

implementação é solicitar à NDIS que feche o adaptador que foi aberto anteriormente pelo

protocolo. A especificação desta função pode ser vista na Figura 20.

Quadro 7: Implementação referente ao processo H (Trata receber pacote)

//************************************************* ***************************** // Trata_Recebe - (processo H) //************************************************* ***************************** DWORD __stdcall Trata_Recebe(PDIOCPARAMETERS Parame tros) { PTR_BUFFER_PACOTE PtrPacoteBuffer; PTR_PACOTE_TRAVADO PtrPacoteTravado; //Se a lista de pacotes recebidos estiver vazia if (Global_PtrContexto->PacotesRecebidos[Global_P trContexto->Inicio_Lista].Status == STATUS_LIVRE) { PtrPacoteTravado = &Global_PtrContexto->PacoteT ravado; //Se já havia um pacote pendente if (PtrPacoteTravado->Status == STATUS_PENDENTE ) { //Destrava o pacote pendente ((LPOVERLAPPED)PtrPacoteTravado->lpoOvrlapped )->O_InternalHigh = 0; VWIN32_CompletaEvento(((LPOVERLAPPED)PtrPacot eTravado->

lpoOvrlapped)-> O_Internal); TiraMemoriaGlobal(PtrPacoteTravado->DadosBuff er, PtrPacoteTravado->TamanhoBu ffer); TiraMemoriaGlobal(PtrPacoteTravado->lpoOvrlap ped, sizeof(OVERLAPPED)); } //Coloca o pacote em situação pendente PtrPacoteTravado->DadosBuffer = ColocaMemoriaGl obal(Parametros->lpvOutBuffer, Parametros->cbO utBuffer); PtrPacoteTravado->TamanhoBuffer = Parametros->c bOutBuffer;

72

PtrPacoteTravado->lpoOvrlapped = ColocaMemoriaG lobal( (DWORD )Parametros->lpoOverlapped, sizeo f(OVERLAPPED)); PtrPacoteTravado->Status = STATUS_PENDENTE; return STATUS_IO_PENDENTE; } //Copia os dados do pacote PtrPacoteBuffer = &Global_PtrContexto-> PacotesRecebidos[Global_PtrCont exto->Inicio_Lista]; memcpy((PVOID)Parametros->lpvOutBuffer, (PVOID)Pt rPacoteBuffer->DadosBuffer, PtrPacoteBuffer->Tamanh oBuffer/*nCount*/); *(LPDWORD)Parametros->lpcbBytesReturned = PtrPaco teBuffer->TamanhoBuffer; //Vai para o próximo da lista Global_PtrContexto->PacotesRecebidos[Global_PtrCo ntexto->Inicio_Lista].Status = STATUS_LIVRE; Global_PtrContexto->PacotesRecebidos[Global_PtrCo ntexto->Inicio_Lista]. TamanhoBuffer = 0; Global_PtrContexto->Inicio_Lista = INC_CIRCULAR( Gl obal_PtrContexto->Inicio_Lista); return STATUS_IO_SUCESSO; }

A implementação apresentada no Quadro 7 é utilizada pelo módulo driver para tratar o

código de recebimento de pacote enviado pelo módulo aplicação. Esta função acessa a lista de

pacotes recebidos pelo driver de protocolo e retorna um elemento desta lista para o módulo

aplicação. A especificação desta função pode ser vista na Figura 21.

A implementação completa do módulo driver pode ser encontrada no Anexo 4.

5.3.4 OPERACIONALIDADE DA IMPLEMENTAÇÃO

Nesta seção é apresentado o funcionamento do protótipo.

O protótipo é formado por três telas as quais são:

a) tela principal: tem o objetivo de apresentar ao usuário os pacotes que estão

trafegando entre o seu host local e a Internet. Nesta mesma tela são apresentados os

pacotes que geraram alertas;

b) configurações do log: tem o objetivo de permitir que o usuário escolha o nível de

visualização do log e também a forma de agrupamento do log;

c) configuração de alertas: tem o objetivo de permitir que o usuário defina que tipo de

situação deve gerar um alerta no monitor de pacotes.

Figura 23: Tela principal do protótipo.

73

A Figura 23 apresenta a tela principal do protótipo. As opções disponíveis no menu da

tela principal são:

a) funções / ativar monitor: ativa a monitoração de pacotes, também pode ser chamado

através do primeiro botão abaixo do menu;

b) funções / desativar monitor: suspende a monitoração de pacotes, também pode ser

chamado através do segundo botão abaixo do menu;

c) logs / configurações: abre a tela de configuração de logs, também pode ser chamado

através do terceiro botão abaixo do menu;

d) logs / salvar log atual: salva em um arquivo todo os dados que estão na página

“Logs”;

e) logs / ler arquivo de log: carrega para a página “Log” os dados de um arquivo de log

salvo anteriormente;

f) alertas / configurações: abre a tela de configuração de alertas, também pode ser

chamado através do quarto botão abaixo do menu;

g) alertas / salvar alertas atuais: salva em um arquivo todo os dados que estão na

página “Alertas”

h) alertas / ler arquivo de alerta: carrega para a página “Alertas” os dados de um

arquivo de alerta salvo anteriormente;

i) sair: sai do monitor de pacotes.

74

Abaixo dos botões existem duas páginas, a página “Logs” mostra os pacotes que estão

sendo interceptados pelo monitor e a página “Alertas” mostra os pacotes que geraram alertas

de acordo com as configurações de alerta.

No rodapé é apresentada a situação do monitor, a quantidade de pacotes recebido, a

quantidade de alertas gerados e o endereço local que host que está executando o monitor de

pacotes.

Figura 24: Tela de configuração do log.

A Figura 24 apresenta a tela de configurações de log, nesta tela o usuário pode

selecionar a quantidade de dados que deseja visualizar nos pacotes que são mostrados pelo

monitor, esta opção está dividida em simples, parcial ou completo. Nesta tela também é

possível configurar a forma de agrupamento dos pacotes no log.

Figura 25: Tela de configuração de alertas – IP Remoto.

75

A Figura 25 apresenta a página “IP Remoto” da tela de configuração de alertas, nesta

página o usuário monta uma lista de endereços IP remotos e informa ao monitor como devem

ser tratados os endereços da lista.

Figura 26: Tela de configuração de alertas – Porta Local.

76

A Figura 26 apresenta a página “Porta Local” da tela de configuração de alertas, nesta

página o usuário monta uma lista com números de portas locais e informa ao monitor como

devem ser tratados os números da lista.

O monitor de pacotes utiliza os dados da tela de configuração de alertas para decidir

quando deve gerar um alerta para os pacotes que estão sendo monitorados. A geração do

alerta consiste em adicionar o pacote, para o qual se deseja dar o alerta, na página “Alertas”

da tela principal.

5.4 TESTE E VALIDAÇÃO

No teste aplicado ao protótipo serão configuradas algumas situações de alertas, as

quais o usuário deseja ser informado quando ocorrerem. Em seguida o protótipo será

submetido a diversas situações de comunicação de pacotes, sendo que, deverá emitir alerta

para todas as situações de alerta cadastradas previamente pelo usuário, não emitindo alertas

para nenhuma outra situação fora do configurado.

Para a realização dos testes foram ativados dois serviços no host em que está instalado

o monitor de pacotes. Um serviço de FTP, que utiliza as portas 20 e 21 para o sua

comunicação, e um serviço de Telnet que utiliza a porta 23.

Para efeito de teste, nas configurações de alerta para IP remoto o protótipo foi

configurado para proibir apenas a comunicação com os endereços 200.135.24.66, que

corresponde ao site “www.inf.furb.br”, e 200.177.96.136, que corresponde ao site

“www.supra.com.br”. Caso ocorra comunicação com os dois endereços cadastrados, o

monitor deverá emitir um alerta. A comunicação com qualquer outro endereço deverá

transcorrer normalmente. Esta configuração de alerta para endereços remotos é demonstrada

na Figura 27.

77

Figura 27: Configuração de alerta para IP remoto.

Nas configurações de alerta para portas locais o protótipo foi configurado para permitir

a comunicação somente através da porta 23 e da porta 80, ou seja, a comunicação com

qualquer outra porta local deve gerar um alerta. De acordo com esta configuração, o serviço

de Telnet e um eventual serviço de HTTP poderiam ser utilizados normalmente, porém

qualquer tentativa de utilização do serviço de FTP deveria gerar um alerta no monitor de

pacotes. A configuração de alerta para portas locais é demonstrada na

Figura 28.

78

Figura 28: Configuração de alerta para portas locais.

Nas opções de log foram selecionados o nível de visualização parcial e a forma de

agrupamento “IP remoto por porta local”.

Após serem feitas todas as configurações, o monitor de pacotes é ativado e começa a

monitorar os pacotes que estão trafegando pelo host local. O monitor em funcionamento, de

acordo com as configurações definidas, é apresentado na Figura 29.

79

Figura 29: Monitor de pacotes em funcionamento.

Na Figura 29 pode-se observar a forma de agrupamento dos pacotes, no primeiro nível

estão as portas locais referentes aos pacotes que foram monitorados, no segundo nível estão os

endereços IP remotos, no terceiro nível é apresentado o cabeçalho do pacote IP e no quarto

nível o cabeçalho do pacote que transporte, que neste caso é TCP. O cabeçalho dos pacotes

está sendo exibido no nível de visualização parcial. Ao lado de cada linha é apresentada a

quantidade de pacote que está agrupada em cada nível.

De acordo com a Figura 29 ocorreu comunicação nas portas locais 23, 20, 21, 1079,

1072 e 1064. Esta comunicação aconteceu com os endereços IP remotos 200.135.24.235,

200.135.24.66, 200.177.96.136 e 200.135.24.5.

Para a comunicação apresentada acima o monitor de pacotes deveria ter emitido alerta

para as portas 1064, 1072, 1079, 21 e 20, e para os endereços IP 200.177.96.136 e

200.135.24.66. A Figura 30 apresenta os alertas gerados pelo monitor de pacotes.

80

Figura 30: Alertas gerados pelo monitor de pacotes.

De acordo com a Figura 30 o monitor de pacotes gerou corretamente os alertas para a

comunicação apresentada na Figura 29.

Tanto os dados apresentados na página “Logs”, quanto na página “Alertas” podem ser

salvos pelo usuário e carregados novamente no monitor de pacotes, possibilitando assim uma

análise posterior dos dados.

O teste apresentado nesta seção, valida a implementação do protótipo especificado e

comprova a eficácia do protótipo em:

a) interceptar e interpretar pacotes TCP/IP;

b) analisar os dados contidos nos pacotes;

c) identificar situações suspeitas e emitir alertas para tais situações;

d) armazenar as informações monitoradas.

Sendo assim, os objetivo específicos do presente trabalho, descritos na seção 1.1,

foram atingidos.

81

6 CONCLUSÕES

A área de segurança em redes de computadores é uma área que vem crescendo a cada

dia, juntamente com o crescimento da Internet e com o aumento da necessidade de diversas

empresas de abrirem suas redes para o mundo, oferecendo serviços e transmitindo dados

através da Internet.

Porém as técnicas e ferramentas existentes hoje para prover segurança em redes de

computadores não eliminam totalmente as chances de um ataque aos serviços ou dados de

uma empresa que utiliza a Internet para oferecer algum tipo de serviço ou transmitir seus

dados.

O protótipo desenvolvido neste trabalho comprovou, através de testes, ser uma

ferramenta capaz de monitorar pacotes em uma conexão TCP/IP, identificar situações

suspeitas definidas pelo usuário e emitir uma alerta para tais situações. Além disto, todas as

informações monitoradas, e os alertas emitidos podem ser salvos pelo usuário para posterior

consulta. Sendo assim os objetivos propostos inicialmente para este trabalho foram atingidos

com sucesso.

O protótipo se mostra uma ferramenta útil no auxílio à segurança de redes de

computadores, à medida que permite identificar rapidamente a ocorrência de um ataque ao

host em que está instalado. Analisando o log gerado pelo monitor de pacotes e os alertas

emitidos pelo mesmo, o usuário pode identificar também qual o tamanho dos prejuízos

causados pelo ataque e como o ataque foi feito, ou seja, que ponto vulnerável da segurança da

rede foi utilizado para realizar o ataque, com isto o usuário pode tomar providência para que

novos ataques da mesma natureza não ocorram novamente.

Para realizar o desenvolvimento do trabalho foi necessário o desenvolvimento de um

driver de dispositivo, pois esta foi a única forma encontrada para monitorar pacotes. Foi

necessário um estudo sobre as funções oferecidas pela NDIS, uma interface para

desenvolvimento de drivers de rede. A ferramenta Microsoft DDK foi de grande auxílio no

desenvolvimento do driver, provendo exemplo e documentações sobre o mesmo.

82

6.1 DIFICULDADES ENCONTRADAS

No decorrer do trabalho, foram encontradas algumas dificuldades, dentre as quais

pode-se destacar:

a) documentação sobre a NDIS somente em inglês;

b) pouca informação existente sobre o desenvolvimento de drivers utilizando NDIS;

c) dificuldade de depuração do driver de dispositivo;

d) complexidade no desenvolvimento do driver de dispositivo, que por ser um

programa que executa em uma camada mais baixa do sistema operacional, deve ser

desenvolvido sobre regras rígidas de funcionamento, e algumas vezes está sujeito a

problemas de difícil explicação e solução.

6.2 LIMITAÇÕES

Dentre as limitações apresentadas pelo protótipo, destacam-se as seguintes:

a) o protótipo roda apenas sobre o sistema operacional Windows 98;

b) o protótipo monitora apenas conexões através de acesso discado, utilizando para

tanto o protocolo PPP;

c) o protótipo reconhece apenas cabeçalhos dos protocolos IP, TCP e UDP;

d) as configurações de alerta se baseiam apenas nos campos de endereços IP, do

protocolo IP e portas, dos protocolos TCP e UDP;

6.3 EXTENSÕES

Durante o desenvolvimento do trabalho surgiram várias idéias que permitem a

extensão deste trabalho, entre elas:

a) desenvolver o suporte à outros sistemas operacionais, como Windows NT/2000 e

Linux;

b) implementar o reconhecimento do cabeçalho de outros protocolos, como ARP e

ICMP;

c) implementar o reconhecimento de protocolos de aplicação, como FTP, TelNet e

HTTP;

d) estender as configurações de alerta, para que possam se basear em outros campos,

como por exemplo, os dados transportados pelo protocolo de aplicação.

83

ANEXO 1

As figuras a seguir apresentam a especificação dos processos do módulo aplicação que

não foram vistos no capítulo 5.

Figura 31: Fluxograma do processo F (Setar Filtro).

Descrição dos componentes do processo F:

a) criar evento: cria uma estrutura que irá controlar a comunicação assíncrona entre a

módulo aplicação e o módulo driver, para a alteração do filtro do adaptador de rede;

b) enviar código para o driver setar filtro do adaptador: solicita ao módulo driver que

altera o filtro do adaptador de rede, desta solicitação irá retornar um indicativo

informando se o processo ainda está pendente, ou já foi completado. Para maiores

informações ver a Figura 41, que faz parte da especificação do módulo driver;

c) aguarda término do processo (evento): caso a solicitação para alteração do filtro do

adaptador de rede tenha ficado pendente, o módulo aplicação ficará aguardando que

o evento de controle da comunicação assíncrona indique que a solicitação terminou

84

de ser processada.

Figura 32: Fluxograma do processo H (Adicionar Log).

Descrição dos componentes do processo H:

a) agrupar pela origem do pacote: mostra os pacotes que foram recebidos agrupados

pelo campo origem do cabeçalho IP, e em um segundo nível pela porta de origem

do cabeçalho dos protocolos TCP ou UDP;

b) agrupar pelo destino do pacote: mostra os pacotes que foram recebidos agrupados

pelo campo destino do cabeçalho IP, e em um segundo nível pela porta de destino

do cabeçalho dos protocolos TCP ou UDP;

c) agrupar IP remoto por porta local: mostra os pacotes que foram recebidos agrupados

85

em um primeiro nível pela porta local, e em um segundo nível pelo IP remoto,

sempre em relação ao host em que está instalado o monitor de pacotes. Nesta forma

de agrupamento o usuário pode observar todas as portas do host que estão sendo

utilizadas e quais os endereços IP remotos que estão utilizando estas portas;

d) agrupar porta local por IP remoto: mostra os pacotes que foram recebidos agrupados

em um primeiro nível pelo IP remoto, e em um segundo nível pela porta local,

sempre em relação ao host em que está instalado o monitor de pacotes. Nesta forma

de agrupamento o usuário pode observar todos os IP remotos que estão conectados

ao seu host e que portas estes IPs estão utilizando;

e) adicionar diretamente sem agrupar: mostra para o usuário todos os pacotes que

estão sendo recebidos pelo módulo driver sem qualquer forma de agrupamento;

f) agrupar pacote por número ou descrição: os pacotes que não são reconhecidos pelo

módulo aplicação são agrupados apenas por uma descrição simples ou pelo seu

número de protocolo.

86

Figura 33: Fluxograma do processo I (Verificar Alertas).

Descrição dos componentes do processo I:

a) IP remoto = origem e porta local = destino: determina que o IP remoto considerado

será o IP origem do pacote que acabou de ser recebido, e a porta local será a porta

destino;

b) IP remoto = destino e porta local = origem: determina que o IP remoto considerado

87

será o IP destino do pacote que acabou de ser recebido, e a porta local será a porta

origem;

c) Adiciona alerta para este pacote: mostra para o usuário qual o pacote não está de

acordo com as configurações de alerta definidas, agrupando os pacotes pelo campo

responsável pela geração do alerta (IP remoto ou porta local).

Figura 34: Fluxograma do processo J (Alocar pacote).

Descrição dos componentes do processo J:

a) aloca memória para o pacote: aloca memória para a estrutura que irá receber os

pacotes do módulo driver;

b) cria evento para o pacote: cria uma estrutura que irá controlar a comunicação

assíncrona entre o módulo aplicação e o módulo driver, para o recebimento de cada

pacote;

c) libera memória do pacote: se ocorrer algum erro após a alocação de memória para o

pacote, esta memória será liberada.

Figura 35: Fluxograma do processo K (Desalocar pacote).

Descrição dos componentes do processo K:

88

a) finaliza o evento do pacote: libera a estrutura que controlava a comunicação

assíncrona entre o módulo aplicação e o módulo driver, no recebimento de pacotes;

b) libera memória do pacote: libera a memória alocada para a estrutura (pacote) que

recebia os pacotes do módulo driver.

89

ANEXO 2

As figuras a seguir apresentam a especificação dos processos do módulo driver que

não foram vistos no capítulo 5.

Figura 36: Fluxograma do processo A (Carregar Driver).

Descrição dos componentes do processo A:

a) Declaração do driver virtual: informa ao sistema operacional que um driver está

sendo carregado;

Figura 37: Fluxograma do processo B (Procedimento de controle).

Descrição dos componentes do processo B:

a) executa a inicialização do driver: chamada do processo C, para que sejam tomadas

as providências para a inicialização do driver de protocolo. Para maiores detalhes

ver a Figura 18;

b) trata código de controle recebido: chamada do processo D, para que seja feito o

tratamento de um código de controle enviado ao módulo driver. Para maiores

90

detalhes ver a Figura 38.

Figura 38: Fluxograma do processo D (Trata código de controle).

Descrição dos componentes do processo D:

a) trata código de conexão: chamada do processo E, para que seja feito o tratamento

91

específico para o código de conexão. Para maiores detalhes ver a Figura 39;

b) trata código de desconexão: chamada do processo F, para que seja feito o

tratamento específico para o código de desconexão. Para maiores detalhes ver a

Figura 40;

c) trata código para setar filtro: chamada do processo G, para que seja feito o

tratamento específico para o código de setar filtro. Para maiores detalhes ver a

Figura 41;

d) trata código para receber pacotes: chamada do processo H, para que seja feito o

tratamento específico para o código de receber pacote. Para maiores detalhes ver a

Figura 21.

Figura 39: Fluxograma do processo E (Trata código de conexão).

Descrição dos componentes do processo E:

a) aloca memória para o contexto do driver: aloca memória para uma estrutura que

contém vários valores utilizados internamente pelo módulo driver;

b) seta nome do adaptador: atribui o nome do adaptador que deve ser conectado, este

valor é passado para o módulo driver pelo módulo aplicação;

c) chama o protocolo para se conectar ao adaptador: chamada do processo I, é um

evento do protocolo que deve ser chamado para se conectar a um adaptador, o

92

retorno desta chamada é passado ao módulo aplicação. Para maiores detalhes ver a

Figura 19.

Figura 40: Fluxograma do processo F (Trata código de desconexão).

Descrição dos componentes do processo F:

a) libera o pacote pendente: se existir um pacote do módulo aplicação aguardando a

chegada de pacotes no módulo driver, o evento deste pacote é liberado;

b) chama o protocolo para se desconectar do adaptador: chamada do processo K, é um

evento do protocolo que deve ser chamado para se desconectar de um adaptador, o

retorno desta chamada é passado ao módulo aplicação. Para maiores detalhes ver a

Figura 20.

93

Figura 41: Fluxograma do processo G (Trata código para setar filtro).

Descrição dos componentes do processo G:

a) seta os dados da requisição: atribui os valores da requisição que será feita;

b) faz uma requisição de alteração de filtro à NDIS: envia uma requisição para a

NDIS, para que seja alterado o filtro do adaptador de rede;

c) chama o protocolo para completar a requisição: caso a requisição não tenha

retornado pendente, ou seja, ela foi completada por parte da NDIS, então é feita

uma chamada do processo M, que irá completar o processo de alteração do filtro. Se

a solicitação de conexão a NDIS retornar pendente, o processo G não deve fazer

uma chamada do processo M, pois esta chamada será feita internamente pela NDIS

quando a solicitação for completada. Para ver maiores detalhes sobre o processo M

ver a Figura 44.

94

Figura 42: Fluxograma do processo J (Conectar adaptador completado).

Descrição dos componentes do processo J:

a) libera evento da conexão: sinaliza ao módulo aplicação que o processo de conexão

está completado;

b) inicializa contexto global: inicializa o contexto que será utilizado internamente por

todo o módulo driver;

c) libera conjunto de pacotes da NDIS: libera a estrutura de pacotes da NDIS alocada

anteriormente;

d) libera conjunto de buffers da NDIS: libera a estrutura de buffers da NDIS alocada

anteriormente;

e) libera memória do contexto: libera memória alocada anteriormente para armazenar

o contexto do módulo driver.

95

Figura 43: Fluxograma do processo L (Desconecta adaptador completado).

Descrição dos componentes do processo L:

a) libera evento de desconexão: sinaliza ao módulo aplicação que o processo de

desconexão está completado;

b) libera estruturas do contexto: libera estruturas agregadas ao contexto utilizadas

internamente pelo módulo driver;

c) libera conjunto de pacotes da NDIS: libera a estrutura de pacotes da NDIS alocada

anteriormente;

d) libera conjunto de buffers da NDIS: libera a estrutura de buffers da NDIS alocada

anteriormente;

e) libera memória do contexto: libera memória alocada anteriormente para armazenar

o contexto do módulo driver.

Figura 44: Fluxograma do processo M (Requisição completada).

Descrição dos componentes do processo M:

a) libera evento da requisição: sinaliza ao módulo aplicação que a requisição para

96

alterar o filtro do adaptador de rede está completada.

Figura 45: Fluxograma do processo O (Transferência de dados completada).

Descrição dos componentes do processo O:

a) copia dados para o pacote pendente: se existir um pacote do módulo aplicação

pendente, os dados do pacote que acabou de ser transferido são copiados para este

pacote;

b) libera o pacote pendente: após a cópia dos dados, o pacote do módulo aplicação que

estava pendente é liberado;

c) adiciona os dados na lista de pacotes recebidos: caso não exista um pacote do

módulo aplicação pendente, então os dados que acabaram de ser transferidos são

copiados para uma lista de pacotes recebidos;

d) posiciona no próximo elemento da lista: posiciona a lista de pacotes recebidos no

próximo elemento, para receber mais um pacote na próxima chamada do processo

O;

e) reinicializa o pacote NDIS: após a utilização da estrutura de pacote da NDIS, está

estrutura precisa ser reinicializada;

f) libera o pacote NDIS: retira da memória a estrutura de pacote da NDIS alocada

anteriormente.

97

Figura 46: Fluxograma do processo P (Descarregar protocolo).

Descrição dos componentes do processo P:

a) Remove o registro do driver de protocolo da NDIS: solicita a NDIS a remoção deste

protocolo de seus tratamentos.

98

ANEXO 3

A seguir está listado o código fonte do módulo aplicação. Nesta listagem aparecem

apenas os arquivos que contém os processos mais importantes da aplicação, não foram

listados os arquivos que contém funções gerais, telas, tipos ou constantes utilizadas pelo

módulo aplicação.

//*********************************************** // FURB - BCC - NOTURNO - TRABALHO DE CONCLUSÃO DE CURSO // Autor - Paulo Fernando da Silva // Arquivo - UFMonitor.pas (Projeto Delphi) // Objetivo - Tela principal do monitor de pacotes //*********************************************** unit UFMonitor; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, ExtCtrls, UTipos, UFuncoes, UInternet, UTransporte, Menus, ToolWin, Buttons, Tabnotbk, Contnrs, UMonitor; type TFMonitor = class(TForm) Menu: TMainMenu; MSair: TMenuItem; MFuncoes: TMenuItem; MAtivarMonitor: TMenuItem; MDesativarMonitor: TMenuItem; MLogs: TMenuItem; MConfLog: TMenuItem; MSalvarLog: TMenuItem; PageControl1: TPageControl; TabSheet2: TTabSheet; Barra: TStatusBar; ToolBar1: TToolBar; Bevel1: TBevel; SBConAle: TSpeedButton; SBConLog: TSpeedButton; ToolButton1: TToolButton; SBDesativar: TSpeedButton; SBAtivar: TSpeedButton; Panel2: TPanel; TVLogs: TTreeView; MLerLog: TMenuItem; MAlertas: TMenuItem; MConfAlerta: TMenuItem; MSalvarAlerta: TMenuItem; MLerAlerta: TMenuItem; TabSheet3: TTabSheet; TVAlertas: TTreeView; ODLogs: TOpenDialog; SDLogs: TSaveDialog; ODAlertas: TOpenDialog; SDAlertas: TSaveDialog; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure MAtivarMonitorClick(Sender: TObject); procedure MDesativarMonitorClick(Sender: TObject); procedure MConfLogClick(Sender: TObject); procedure MSalvarLogClick(Sender: TObject); procedure MLerLogClick(Sender: TObject); procedure MConfAlertaClick(Sender: TObject); procedure MSalvarAlertaClick(Sender: TObject); procedure MLerAlertaClick(Sender: TObject);

procedure MSairClick(Sender: TObject); end; //Contexto do monitor RegContexto = record PAdaptador: PAdaptador; PPacote: PPacote; ProcLeitura: TProcLeitura; IPLocal: String; QtdPacote: Integer; QtdAlerta: Integer; //Dados do log Nivel: byte; Agrupamento: byte; //Dados do Alerta ListaIPRemoto: TStrings; OpcaoIPRemoto: byte; ListaPortaLocal: TStrings; OpcaoPortaLocal: byte; //TreeView's TreeViewLog: TTreeView; TreeViewAlerta: TTreeView; end; var Buffer: array[0..1520] of Char; FMonitor: TFMonitor; Con : RegContexto; implementation uses UConstantes, ULog, UAlerta, UFConLog, UFConAle; {$R *.DFM} procedure TFMonitor.FormCreate(Sender: TObject); begin Con.ProcLeitura := nil; Con.PAdaptador := nil; Con.PPacote := nil; Con.TreeViewLog := TVLogs; Con.TreeViewAlerta := TVAlertas; end; procedure TFMonitor.FormDestroy(Sender: TObject); begin if Con.ProcLeitura <> nil then DesativarMonitor; end; procedure TFMonitor.MAtivarMonitorClick(Sender: TObject); begin AtivarMonitor; Barra.Panels[0].Text := 'Situação: Ativado'; Barra.Panels[1].Text := 'Pacotes: 0'; Barra.Panels[2].Text := 'Alertas: 0'; MAtivarMonitor.Enabled := False; SBAtivar.Enabled := False; MDesativarMonitor.Enabled := True;

99

SBDesativar.Enabled := True; MLerLog.Enabled := False; MLerAlerta.Enabled := False; end; procedure TFMonitor.MDesativarMonitorClick(Sender: TObject); begin DesativarMonitor; Barra.Panels[0].Text := 'Situação: Desativado'; MAtivarMonitor.Enabled := True; SBAtivar.Enabled := True; MDesativarMonitor.Enabled := False; SBDesativar.Enabled := False; MLerLog.Enabled := True; MLerAlerta.Enabled := True; end; procedure TFMonitor.MConfLogClick(Sender: TObject); var xLog: TFLog; begin xLog := TFLog.Create(self); try if Con.ProcLeitura <> nil then xLog.PControles.Enabled := False; xLog.ShowModal; CarregaDadosLog; finally xLog.Free; end; end; procedure TFMonitor.MSalvarLogClick(Sender: TObject); begin if SDLogs.Execute then begin TVLogs.Items.AddFirst(nil, IntToStr(Con.QtdPacote)); TVLogs.SaveToFile(SDLogs.FileName); TVLogs.Items.Delete(TVLogs.Items.Item[0]); end; end; procedure TFMonitor.MLerLogClick(Sender: TObject); begin if ODLogs.Execute then begin TVLogs.LoadFromFile(ODLogs.FileName); try Con.QtdPacote := StrToInt(TVLogs.Items.Item[0].Text); Barra.Panels[1].Text := 'Pacotes: ' + IntToStr(Con.QtdPacote); TVLogs.Items.Delete(TVLogs.Items.Item[0]); except Raise EConvertError.Create('Não foi possível recuperar total de pacotes.'); end; end; end; procedure TFMonitor.MConfAlertaClick(Sender: TObject); var xAlerta: TFAlerta; begin xAlerta := TFAlerta.Create(self); try if Con.ProcLeitura <> nil then begin xAlerta.PIPRemoto.Enabled := False; xAlerta.PPortaLocal.Enabled := False; end; xAlerta.ShowModal; CarregaDadosAlerta; finally xAlerta.Free; end;

end; procedure TFMonitor.MSalvarAlertaClick(Sender: TObject); begin if SDAlertas.Execute then begin TVAlertas.Items.AddFirst(nil, IntToStr(Con.QtdAlerta)); TVAlertas.SaveToFile(SDAlertas.FileName); TVAlertas.Items.Delete(TVAlertas.Items.Item[0]); end; end; procedure TFMonitor.MLerAlertaClick(Sender: TObject); begin if ODAlertas.Execute then begin TVAlertas.LoadFromFile(ODAlertas.FileName); try Con.QtdAlerta := StrToInt(TVAlertas.Items.Item[0].Text); Barra.Panels[2].Text := 'Alertas: ' + IntToStr(Con.QtdAlerta); TVAlertas.Items.Delete(TVAlertas.Items.Item[0]); except Raise EConvertError.Create('Não foi possível recuperar o total de alertas.') end; end; end; procedure TFMonitor.MSairClick(Sender: TObject); begin Close; end; end.

//*********************************************** // FURB - BCC - NOTURNO - TRABALHO DE CONCLUSÃO DE CURSO // Autor - Paulo Fernando da Silva // Arquivo - UMonitor.pas (Projeto Delphi) // Objetivo - Contém processo para Ativar e Desativar o Monitor e uma // thread para receber pacotes //*********************************************** unit UMonitor; interface uses Classes; procedure AtivarMonitor; procedure DesativarMonitor; type TProcLeitura = class(TThread) procedure Execute; override; private procedure Recebimento; end; implementation uses Windows, SysUtils, UTipos, UInternet, UFMonitor, UFuncoes, UConstantes, ULog, UAlerta, U Driver; //*********************************************** // AtivarMonitor - (Processo A) //*********************************************** procedure AtivarMonitor; begin SetCurrentDir(cDirInstalacao);

100

//Abre adaptador

Con.PAdaptador := AbrirAdaptador('0000'); if Con.PAdaptador = nil then raise Exception.Create('Não foi possível abrir adaptador.'); //Seta fitro do adaptador if not SetarFiltro(Con.PAdaptador, NDIS_PACKET_TYPE_PROMISCUOUS) then begin FecharAdaptador(Con.PAdaptador); raise Exception.Create('Não foi possível setar filtro.'); end; //Aloca pacote Con.PPacote := PPacote(AlocarPacote(PAdaptador(Con.PAdaptador))); if (Con.PPacote = nil) then begin FecharAdaptador(Con.PAdaptador); raise Exception.Create('Não foi possível alocar pacote.'); end; //Inicializa contexto Con.IPLocal := ''; Con.QtdPacote := 0; Con.QtdAlerta := 0; Con.TreeViewLog.Items.Clear; Con.TreeViewAlerta.Items.Clear; CarregaDadosLog; CarregaDadosAlerta; //Inicializa Pacote do contexto Con.PPacote^.Buffer := @Buffer[0]; Con.PPacote^.Length := 1520; //Ativa processso de Leitura Con.ProcLeitura := TProcLeitura.Create(false); end; //*********************************************** // DesativarMonitor - (Processo B) //*********************************************** procedure DesativarMonitor; begin if Con.ProcLeitura <> nil then begin //Encerra processo de Leitura Con.ProcLeitura.Terminate; //Fecha adaptador FecharAdaptador(Con.PAdaptador); Con.PAdaptador := nil; //Libera Pacote LiberarPacote(Con.PPacote); Con.PPacote := nil; //Libera recursos do contexto Con.ListaIPRemoto.Free; Con.ListaPortaLocal.Free; //Libera processo de Leitura FreeAndNil(Con.ProcLeitura); end; end; //*********************************************** // Processo de Leitura dos dados - (Processo C) //*********************************************** procedure TProcLeitura.Execute; begin while (not Terminated) do begin ReceberPacote(Con.PAdaptador, Con.PPacote); if (not Terminated) then Synchronize(Recebimento); end; end; procedure TProcLeitura.Recebimento; var xPPacoteEthernet: PPacoteEthernet; xPPacoteIP: PPacoteIP; begin if (Con.PPacote <> nil) then begin

xPPacoteEthernet := PPacoteEthernet(Con.PPacote.Buffer); AdicionarLog(xPPacoteEthernet); if GetNumeroProtocolo(xPPacoteEthernet) = cProtocolo_IP then begin xPPacoteIP := PPacoteIP(@(xPPacoteEthernet^.Dados[0])); VerificarAlerta(xPPacoteIP); end; end; end; end.

//*********************************************** // FURB - BCC - NOTURNO - TRABALHO DE CONCLUSÃO DE CURSO // Autor - Paulo Fernando da Silva // Arquivo - U Driver.pas (Projeto Delphi) // Objetivo - Contém funções que utilizam o driver "MONITOR.VXD" //*********************************************** unit U Driver; interface uses Windows, UTipos; function AbrirAdaptador(const NomeAdaptador: String): Pointer; procedure FecharAdaptador(Adaptador: PAdaptador); function SetarFiltro(Adaptador: PAdaptador; Filtro: Cardinal): Boolean; procedure ReceberPacote(Adaptador: PAdaptador; Pacote: PPacote); implementation uses SysUtils, UControles; //*********************************************** // AbrirAdaptador - (Processo D) //*********************************************** function AbrirAdaptador(const NomeAdaptador: String): Pointer; var xPtrAdaptador : PADAPTADOR; QtdBytesRetornados :Longword; Evento: THANDLE; Ovrlapped: OVERLAPPED; Retorno: boolean; begin Result := nil; xPtrAdaptador := PADAPTADOR(GlobalAllocPtr(GMEM_MOVEABLE or GMEM_ZEROINIT, sizeof(RegAdaptador))); if xPtrAdaptador = nil then Exit; lstrcpy(xPtrAdaptador^.LigacaoSimbolica,'\\.\MONITOR.VXD'); //Cria ou abre um objeto, retornando o hanlde utilizado para acessar tal objeto xPtrAdaptador^.Handle := CreateFile( xPtrAdaptador^.LigacaoSimbolica,//nome do objeto GENERIC_READ or GENERIC_WRITE, //modo de acesso 0, //modo de compartilhamento nil, //atributos de segurança OPEN_EXISTING, //como criar o objeto FILE_ATTRIBUTE_NORMAL or FILE_FLAG_DELETE_ON_CLOSE or FILE_FLAG_OVERLAPPED, //atributos do objeto

101

0); //handle para copiar atributos if xPtrAdaptador^.Handle = INVALID_HANDLE_VALUE then GlobalFreePtr(xPtrAdaptador) else begin //Cria um objeto de evento Evento := CreateEvent(nil, //atributos de segurança TRUE, //reset manual do evento FALSE,//estado inicial nil); //ponteiro para o nome do objeto if Evento = 0 then begin CloseHandle(xPtrAdaptador^.Handle); GlobalFreePtr(xPtrAdaptador); end else begin Ovrlapped.Internal := 0; Ovrlapped.InternalHigh := 0; Ovrlapped.Offset := 0; Ovrlapped.OffsetHigh := 0; Ovrlapped.hEvent := Evento; //Envia um código de controle para um driver específico Retorno := DeviceIoControl(xPtrAdaptador^.Handle,//handle do driver IOCTL_MONITOR_LIGA, //código de controle PChar(NomeAdaptador), //buffer enviado Length(NomeAdaptador), //tamanho do buffer enviado nil, //buffer recebido 0, //tamanho do buffer recebido QtdBytesRetornados, //qtd bytes retornados @Ovrlapped); //estrutura de comunicação assíncrona if not Retorno then begin if GetLastError = ERROR_IO_PENDING then Retorno := GetOverlappedResult( //Aguarda o resultado da comunicação assíncrona xPtrAdaptador^.Handle,//handle do dispositivo Ovrlapped, //estrutura de comunicação assíncrona QtdBytesRetornados, //qtd de bytes aguardados true); //flag "aguardar" if not Retorno then begin CloseHandle(xPtrAdaptador^.Handle); GlobalFreePtr(xPtrAdaptador); Result := nil; end; end else Result := (xPtrAdaptador); end; end; end; //*********************************************** // FecharAdaptador - (Processo E) //*********************************************** procedure FecharAdaptador(Adaptador: PAdaptador); var Evento : THANDLE; Ovrlapped : OVERLAPPED;

Retorno : BOOLEAN; QtdBytesRetornados: Longword; begin //Cria um objeto de evento Evento := CreateEvent(nil, //atributos de segurança TRUE, //reset manual do evento FALSE,//estado inicial nil); //ponteiro para o nome do objeto if Evento = 0 then raise Exception.Create('Não foi possível fechar adaptador'); Ovrlapped.Internal := 0; Ovrlapped.InternalHigh := 0; Ovrlapped.Offset := 0; Ovrlapped.OffsetHigh := 0; Ovrlapped.hEvent := Evento; //Envia um código de controle para um driver específico Retorno := DeviceIoControl(Adaptador^.Handle, //handle do driver IOCTL_MONITOR_DESLIGA,//código de controle nil, //buffer enviado 0, //tamanho do buffer enviado nil, //buffer recebido 0, //tamanho do buffer recebido QtdBytesRetornados, //qtd bytes retornados @Ovrlapped); //estrutura de comunicação assíncrona if not Retorno then begin if GetLastError = ERROR_IO_PENDING then Retorno := GetOverlappedResult(Adaptador^.Handle,//handle do dispositivo Ovrlapped, //estrutura de comunicação assíncrona QtdBytesRetornados, //qtd de bytes aguardados TRUE); //flag "aguardar" if not Retorno then raise Exception.Create('Ocorreu um erro ao tentar fechar adaptador'); end; CloseHandle(Adaptador^.Handle); GlobalFreePtr(Adaptador); end; //*********************************************** // SetarFiltro - (Processo F) //*********************************************** function SetarFiltro(Adaptador: PAdaptador; Filtro: Cardinal): Boolean; var Evento : THANDLE; Ovrlapped: OVERLAPPED; QtdBytesRetornados: Longword; begin //Cria um objeto de evento Evento := CreateEvent(nil, //atributos de segurança TRUE, //reset manual do evento FALSE,//estado inicial nil); //ponteiro para o nome do objeto if Evento = 0 then Result := false else begin Ovrlapped.Internal := 0; Ovrlapped.InternalHigh := 0;

102

Ovrlapped.Offset := 0; Ovrlapped.OffsetHigh := 0; Ovrlapped.hEvent := Evento; //Envia um código de controle para um driver específico Result := DeviceIoControl(Adaptador^.handle, //handle do driver IOCTL_MONITOR_SETAFILTRO,//código de controle @Filtro, //buffer enviado sizeof(Longword), //tamanho do buffer enviado nil, //buffer recebido 0, //tamanho do buffer recebido QtdBytesRetornados, //qtd bytes retornados @Ovrlapped); //estrutura de comunicação assíncrona if not Result then begin if GetLastError = ERROR_IO_PENDING then Result := GetOverlappedResult(//Aguarda o Retorno da comunicação assíncrona Adaptador^.handle, //handle do dispositivo Ovrlapped, //estrutura de comunicação assíncrona QtdBytesRetornados,//qtd de bytes aguardados TRUE); //flag "aguardar" end; end; end; //*********************************************** // ReceberPacote - (Processo G) //*********************************************** procedure ReceberPacote(Adaptador: PAdaptador; Pacote: PPacote); var Retorno: boolean; QtdBytesRetornados: Longword; begin Pacote^.OverLapped.Offset := 0; Pacote^.OverLapped.OffsetHigh := 0; if not ResetEvent(Pacote^.OverLapped.hEvent) then raise Exception.Create('Ocorreu um erro ao receber um pacote.'); Retorno := DeviceIoControl(Adaptador^.Handle, IOCTL_MONITOR_RECEBE, nil, 0, Pacote^.Buffer, Pacote^.Length, QtdBytesRetornados, @Pacote^.OverLapped); if not Retorno then begin Retorno := GetOverlappedResult(Adaptador^.Handle, Pacote^.OverLapped, QtdBytesRetornados, TRUE); if not Retorno then raise Exception.Create('Ocorre uma erro ao receber um pacote.'); end; end; end.

//*********************************************** // FURB - BCC - NOTURNO - TRABALHO DE CONCLUSÃO DE CURSO // Autor - Paulo Fernando da Silva // Arquivo - ULog.pas (Projeto Delphi) // Objetivo - Funções para adicionar e agrupar log's na TreeView e // inicializar dados do log no contexto //*********************************************** unit ULog; interface uses Classes, SysUtils, ComCtrls, IniFiles, UInternet, UConstantes, UTipos, UTransporte; procedure CarregaDadosLog; procedure AdicionarLog(aPacote: PPacoteEthernet); procedure AgruparDestino(aPacote: PPacoteIP); procedure AgruparIPRemotoPorPortaLocal(aPacote: PPacoteIP); procedure AgruparOrigem(aPacote: PPacoteIP); procedure AgruparPortaLocalPorIPRemoto(aPacote: PPacoteIP); procedure NaoAgrupar(aPacote: PPacoteIP); implementation uses UFMonitor, UFuncoes; procedure CarregaDadosLog; var xIniLog: TIniFile; begin xIniLog := TIniFile.Create(cDirInstalacao + '\IniLog.ini'); try Con.Nivel := xIniLog.ReadInteger('CONFIG', 'NIVEL', 0); Con.Agrupamento := xIniLog.ReadInteger('CONFIG', 'AGRUPAR', 0); finally xIniLog.Free; end; end; //*********************************************** // AdicionarLog - (Processo H) //*********************************************** procedure AdicionarLog(aPacote: PPacoteEthernet); var xPacoteIP: PPacoteIP; begin case GetNumeroProtocolo(apacote) of cProtocolo_IP: begin xPacoteIP := PPacoteIP(@(aPacote^.Dados[0])); case Con.Agrupamento of 1: AgruparOrigem(xPacoteIP); 2: AgruparDestino(xPacoteIP); 3: AgruparIPRemotoPorPortaLocal(xPacoteIP); 4: AgruparPortaLocalPorIPRemoto(xPacoteIP); else //0: qualquer outro NaoAgrupar(xPacoteIP); end; end; cProtocolo_ARP: AgruparNo(Con.TreeViewLog, nil, 'Pacotes do protocolo ARP'); cProtocolo_SNMP: AgruparNo(Con.TreeViewLog, nil, 'Pacotes do protocolo SNMP'); else AgruparNo(Con.TreeViewLog, nil, 'Pacotes do protocolo ' + InttoStr(GetNumeroProtocolo(aPacote)));

103

end; Inc(Con.QtdPacote); FMonitor.Barra.Panels[1].Text := 'Pacotes: ' + IntToStr(Con.QtdPacote); end; //*********************************************** // Funções de agrupamento //*********************************************** procedure NaoAgrupar(aPacote: PPacoteIP); var xItemPai: TTreeNode; begin xItemPai := Con.TreeViewLog.Items.AddFirst(Con.TreeViewLog.TopItem, DadosIP_Str(aPacote)); Con.TreeViewLog.Items.AddChildFirst(xItemPai, DadosTransp_Str(aPacote)); end; procedure AgruparOrigem(aPacote: PPacoteIP); var xItemPai: TTreeNode; begin xItemPai := AgruparNo(Con.TreeViewLog, nil, 'IP Origem ' + IPOrigem_Str(aPacote)); xItemPai := AgruparNo(Con.TreeViewLog, xItemPai, 'Porta Origem ' + PortaOrigem_Str(aPacote)); xItemPai := Con.TreeViewLog.Items.AddChildFirst(xItemPai, DadosIP_Str(aPacote)); Con.TreeViewLog.Items.AddChildFirst(xItemPai, DadosTransp_Str(aPacote)); end; procedure AgruparDestino(aPacote: PPacoteIP); var xItemPai: TTreeNode; begin xItemPai := AgruparNo(Con.TreeViewLog, nil, 'IP Destino ' + IPDestino_Str(aPacote)); xItemPai := AgruparNo(Con.TreeViewLog, xItemPai, 'Porta Destino ' + PortaDestino_Str(aPacote)); xItemPai := Con.TreeViewLog.Items.AddChildFirst(xItemPai, DadosIP_Str(aPacote)); Con.TreeViewLog.Items.AddChildFirst(xItemPai, DadosTransp_Str(aPacote)); end; procedure AgruparPortaLocalPorIPRemoto(aPacote: PPacoteIP); var xItemPai: TTreeNode; begin if SentidoPacote(aPacote) = spEntrando then begin xItemPai := AgruparNo(Con.TreeViewLog, nil, 'IP Remoto - ' + IPOrigem_Str(aPacote)); xItemPai := AgruparNo(Con.TreeViewLog, xItemPai, 'Porta Local - ' + PortaDestino_Str(aPacote)); end else if SentidoPacote(aPacote) = spSaindo then begin xItemPai := AgruparNo(Con.TreeViewLog, nil, 'IP Remoto - ' + IPDestino_Str(aPacote)); xItemPai := AgruparNo(Con.TreeViewLog, xItemPai, 'Porta Local - ' + PortaOrigem_Str(aPacote)); end else xItemPai := AgruparNo(Con.TreeViewLog, nil, 'Sem relação com IP Local'); xItemPai := Con.TreeViewLog.Items.AddChildFirst(xItemPai, DadosIP_Str(aPacote)); Con.TreeViewLog.Items.AddChildFirst(xItemPai, DadosTransp_Str(aPacote));

end; procedure AgruparIPRemotoPorPortaLocal(aPacote: PPacoteIP); var xItemPai: TTreeNode; begin if SentidoPacote(aPacote) = spEntrando then begin xItemPai := AgruparNo(Con.TreeViewLog, nil, 'Porta Local - ' + PortaDestino_Str(aPacote)); xItemPai := AgruparNo(Con.TreeViewLog, xItemPai, 'IP Remoto - ' + IPOrigem_Str(aPacote)); end else if SentidoPacote(aPacote) = spSaindo then begin xItemPai := AgruparNo(Con.TreeViewLog, nil, 'Porta Local - ' + PortaOrigem_Str(aPacote)); xItemPai := AgruparNo(Con.TreeViewLog, xItemPai, 'IP Remoto - ' + IPDestino_Str(aPacote)); end else xItemPai := AgruparNo(Con.TreeViewLog, nil, 'Sem relação com IP Local'); xItemPai := Con.TreeViewLog.Items.AddChildFirst(xItemPai, DadosIP_Str(aPacote)); Con.TreeViewLog.Items.AddChildFirst(xItemPai, DadosTransp_Str(aPacote)); end; end.

//*********************************************** // FURB - BCC - NOTURNO - TRABALHO DE CONCLUSÃO DE CURSO // Autor - Paulo Fernando da Silva // Arquivo - UAlerta.pas (Projeto Delphi) // Objetivo - Funções para submeter os pacotes as condições de alerta e para // inicializar dados de alerta no contexto //*********************************************** unit UAlerta; interface uses Classes, SysUtils, ComCtrls, IniFiles, UInternet, UConstantes, UTransporte, UTipos; procedure CarregaDadosAlerta; procedure VerificarAlerta(aPacote: PPacoteIP); implementation uses UFMonitor, UFuncoes; procedure CarregaDadosAlerta; var xIniAle: TIniFile; begin Con.ListaPortaLocal := TStringList.Create; Con.ListaIPRemoto := TStringList.Create; xIniAle := TIniFile.Create(cDirInstalacao + '\IniAle.ini'); try xIniAle.ReadSection('IPREMOTO', Con.ListaIPRemoto); Con.OpcaoIPRemoto := xIniAle.ReadInteger('OPCAO', 'IPREMOTO', 0); xIniAle.ReadSection('PORTALOCAL', Con.ListaPortaLocal); Con.OpcaoPortaLocal:= xIniAle.ReadInteger('OPCAO', 'PORTALOCAL', 0); finally

104

xIniAle.Free; end; end; //*********************************************** // VerificarAlerta - (Processo I) //*********************************************** procedure VerificarAlerta(aPacote: PPacoteIP); procedure AdicionaAlerta(const s: string); var xItemPai: TTreeNode; begin xItemPai := AgruparNo(Con.TreeViewAlerta, nil, s); if xItemPai = nil then xItemPai := Con.TreeViewAlerta.Items.AddFirst(Con.TreeViewAlerta.TopItem, 'Alerta em ' + s); xItemPai := Con.TreeViewAlerta.Items.AddChildFirst(xItemPai, DadosIP_Str(aPacote)); Con.TreeViewAlerta.Items.AddChildFirst(xItemPai, DadosTransp_Str(aPacote)); Inc(Con.QtdAlerta); FMonitor.Barra.Panels[2].Text := 'Alertas: ' + IntToStr(Con.QtdAlerta); end; var xIPRemoto: String; xPortaLocal: String; begin case SentidoPacote(aPacote) of spEntrando: begin xIPRemoto := IPOrigem_Str(aPacote); xPortaLocal := PortaDestino_Str(aPacote); end; spSaindo: begin xIPRemoto := IPDestino_Str(aPacote); xPortaLocal := PortaOrigem_Str(aPacote); end; else

Exit; //Não tem relação, sai !!! end; case Con.OpcaoIPRemoto of //0: não faz nada 1:begin //Permitir somente a lista if (Con.ListaIPRemoto.IndexOf(xIPRemoto) = -1) then AdicionaAlerta('IP Remoto - ' + xIPRemoto); end; 2:begin //Proibir somente a lista if (Con.ListaIPRemoto.IndexOf(xIPRemoto) > -1) then AdicionaAlerta('IP Remoto - ' + xIPRemoto); end; end; case Con.OpcaoPortaLocal of //0: não faz nada 1:begin //Permitir somente a lista if (Con.ListaPortaLocal.IndexOf(xPortaLocal) = -1) then AdicionaAlerta('Porta Local - ' + xPortaLocal); end; 2:begin //Proibir somente a lista if (Con.ListaPortaLocal.IndexOf(xPortaLocal) > -1) then AdicionaAlerta('Porta Local - ' + xPortaLocal); end; end; end; end.

105

ANEXO 4

A seguir está listado o código fonte do módulo driver. Nesta listagem aparecem apenas

os arquivos que contém os processos mais importantes do módulo driver, não foram listados

os arquivos que contém funções gerais, tipos ou constantes utilizadas pelo módulo driver.

;------------------------------------------------ ; FURB - BCC - NOTURNO - TRABALHO DE CONCLUSÃO DE CURSO ; Autor - Paulo Fernando da Silva ; Arquivo - Instalar.asm (Projeto VXD) ; Objetivo - Driver de protocolo NDIS que se conecta a um adaptador e ; copia os dados de seus pacotes ; - Declarar o driver MONITOR.VXD e instalar ;------------------------------------------------ name MONITOR .386p include vmm.inc include ndis.inc include netvxd.inc EXTRN _Trata_SysDynamicDeviceInit@0:PROC ; proc que inicializa o driver ;------------------------------------------------ ; Registra o VXD no VMM - (processo A) ;------------------------------------------------ Declare_Virtual_Device MONITOR, \ ; Nome do VxD 1, \ ; Versão 1, \ ; Versão MONITOR_Control, \ ; Procedimento de controle Undefined_Device_ID, \; ID do VXD PROTOCOL_Init_Order ; Ordem de inicializacao ;------------------------------------------------ ; Procedimento de controle ; Sempre que o VMM chamar o VXD, irá executar este código ; (processo B) ;------------------------------------------------ VxD_LOCKED_CODE_SEG Begin_Control_Dispatch MONITOR Control_Dispatch Sys_Dynamic_Device_Init, Inicializacao Control_Dispatch W32_DeviceIoControl, Trata_W32DeviceIoControl, sCall, <ecx, ebx, edx, esi> End_Control_Dispatch MONITOR VxD_LOCKED_CODE_ENDS ;------------------------------------------------ ; Trata "Inicializacao" do driver, mensagem Sys_Dynamic_Device_Init ; (processo C) ;------------------------------------------------ BeginProc Inicializacao, init ; Chama proc de inicializacao call _Trata_SysDynamicDeviceInit@0 cmp eax, NDIS_STATUS_SUCCESS jne ERRO ; Sai sem erro clc

ret ERRO: ; Sai com erro stc ret EndProc Inicializacao END

/************************************************ / FURB - BCC - NOTURNO - TRABALHO DE CONCLUSÃO DE CURSO / Autor - Paulo Fernando da Silva / Arquivo - Monitor.c (Projeto VXD) / Objetivo - Tratar as mensagens Sys_Dynamic_Device_Init e W32_DeviceIOControl /************************************************ #include <ndis.h> #include <vmm.h> #include <vwin32.h> #include <string.h> #pragma intrinsic(memcpy, memset, strlen) #include "Controles.h" #include "Protocolo.h" #include "Funcoes.h" /************************************************ // Trata a inicialização do driver, mensagem Sys_Dynamic_Device_Init // processo (C) /************************************************ #pragma VxD_ICODE_SEG #pragma VxD_IDATA_SEG NDIS_STATUS __stdcall Trata_SysDynamicDeviceInit(void) { return DriverEntry(NULL, NULL); } #pragma VxD_LOCKED_CODE_SEG #pragma VxD_LOCKED_DATA_SEG DWORD __stdcall Trata_Liga(PDIOCPARAMETERS Parametros); DWORD __stdcall Trata_Desliga(PDIOCPARAMETERS Parametros); DWORD __stdcall Trata_Filtro(PDIOCPARAMETERS Parametros); DWORD __stdcall Trata_Recebe(PDIOCPARAMETERS Parametros); /************************************************ // Trata chamadas de IOControl, mensagem W32_DeviceIoControl // processo (D) /************************************************ DWORD __stdcall Trata_W32DeviceIoControl( //Serviço pedido pelo DeviceIOControl DWORD Servico, DWORD dwDDB, DWORD hDevice, //Parametros passados pelo DeviceIOControl PDIOCPARAMETERS Parametros)

106

{

//parâmetro vazio if (!Parametros) return STATUS_IO_ERRO; switch(Servico) { case DIOC_OPEN: //Permite a abertura do driver return STATUS_IO_SUCESSO; case IOCTL_MONITOR_LIGA: //Trata a ligação do adaptador return Trata_Liga(Parametros); case IOCTL_MONITOR_DESLIGA: //Trata o desligamento do adaptador return Trata_Desliga(Parametros); case IOCTL_MONITOR_SETAFILTRO: //Trata a alteração do filtro return Trata_Filtro(Parametros); case IOCTL_MONITOR_RECEBE: //Trata a requisição de pacotes return Trata_Recebe(Parametros); default: return STATUS_IO_ERRO; } } /************************************************ // Trata_Liga (processo E) /************************************************ DWORD __stdcall Trata_Liga(PDIOCPARAMETERS Parametros) { PTR_CONTEXTO PtrContexto; NDIS_STRING NomeAdaptador; NDIS_STATUS Status; DWORD nCount; AlocaMemoria((PVOID *)&PtrContexto, sizeof(CONTEXTO)); if (PtrContexto == NULL) return STATUS_IO_ERRO; NdisZeroMemory((UCHAR *)PtrContexto, sizeof(CONTEXTO)); //Seta lpoOverlapped recebido PtrContexto->Abrir_Ovrlapped = ColocaMemoriaGlobal((DWORD)Parametros->lpoOverlapped, sizeof(OVERLAPPED)); //Pega o nome do adaptador nCount = strlen((CHAR *)Parametros->lpvInBuffer); NomeAdaptador.Length = (int)nCount; NomeAdaptador.MaximumLength = (int)nCount; NomeAdaptador.Buffer = (CHAR *)Parametros->lpvInBuffer; Proto_ConectaAdaptador(&Status, PtrContexto, &NomeAdaptador, NULL, NULL); if (Status == NDIS_STATUS_PENDING) return STATUS_IO_PENDENTE; if (Status == NDIS_STATUS_SUCCESS) return STATUS_IO_SUCESSO; return STATUS_IO_ERRO; }; /************************************************ // Trata_Desliga - (processo F) /************************************************ DWORD __stdcall Trata_Desliga(PDIOCPARAMETERS Parametros) { PTR_PACOTE_TRAVADO PtrPacoteTravado; NDIS_STATUS Status; //Seta lpoOverlapped recebido Global_PtrContexto->Fechar_Ovrlapped = ColocaMemoriaGlobal((DWORD)Parametros->lpoOverlapped, sizeof(OVERLAPPED));

PtrPacoteTravado = &Global_PtrContexto->PacoteTravado; if (PtrPacoteTravado->Status == STATUS_PENDENTE) { //Libera o evento do pacote que estava travado no contexto VWIN32_CompletaEvento(((OVERLAPPED *)PtrPacoteTravado->lpoOvrlapped)->O_Internal); TiraMemoriaGlobal(PtrPacoteTravado->DadosBuffer, PtrPacoteTravado->TamanhoBuffer); TiraMemoriaGlobal(PtrPacoteTravado->lpoOvrlapped, sizeof(OVERLAPPED)); PtrPacoteTravado->Status = STATUS_LIVRE; } Proto_DesconectaAdaptador(&Status, Global_PtrContexto, NULL); if (Status == NDIS_STATUS_PENDING) return STATUS_IO_PENDENTE; if (Status == NDIS_STATUS_SUCCESS) return STATUS_IO_SUCESSO; return STATUS_IO_ERRO; } /************************************************ // Trata_Filtro - (processo G) /************************************************ DWORD __stdcall Trata_Filtro(PDIOCPARAMETERS Parametros) { NDIS_REQUEST Requisicao; NDIS_STATUS Status; UINT Indice; //Seta lpoOverlapped recebido Global_PtrContexto->Requisicao_Ovrlapped = ColocaMemoriaGlobal((DWORD)Parametros->lpoOverlapped, sizeof(OVERLAPPED)); //Seta dados requisição Requisicao.RequestType = NdisRequestSetInformation; Requisicao.DATA.SET_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER; Requisicao.DATA.SET_INFORMATION.InformationBuffer = (PVOID)ColocaMemoriaGlobal((DWORD)Parametros->lpvInBuffer, Parametros->cbInBuffer); Requisicao.DATA.SET_INFORMATION.InformationBufferLength = (UINT)Parametros->cbInBuffer; //Envia uma requisição para o adaptador especificado NdisRequest(&Status, //retorna o status Global_PtrContexto->Adaptador,//handle do adaptador &Requisicao); //dados da requisição if (Status == NDIS_STATUS_PENDING) return STATUS_IO_PENDENTE; Proto_Request_Completado((NDIS_HANDLE)Global_PtrContexto, &Requisicao, Status); if (Status == NDIS_STATUS_SUCCESS) return STATUS_IO_SUCESSO; return STATUS_IO_ERRO; } /************************************************ // Trata_Recebe - (processo H) /************************************************ DWORD __stdcall Trata_Recebe(PDIOCPARAMETERS Parametros) { PTR_BUFFER_PACOTE PtrPacoteBuffer; PTR_PACOTE_TRAVADO PtrPacoteTravado; //Se a lista de pacotes recebidos estiver vazia

107

if (Global_PtrContexto->PacotesRecebidos[Global_PtrContexto->Inicio_Lista].Status == STATUS_LIVRE) {

PtrPacoteTravado = &Global_PtrContexto->PacoteTravado; //Coloca o pacote em situação pendente PtrPacoteTravado->DadosBuffer = ColocaMemoriaGlobal(Parametros->lpvOutBuffer, Parametros->cbOutBuffer); PtrPacoteTravado->TamanhoBuffer = Parametros->cbOutBuffer; PtrPacoteTravado->lpoOvrlapped = ColocaMemoriaGlobal((DWORD)Parametros->lpoOverlapped, sizeof(OVERLAPPED)); PtrPacoteTravado->Status = STATUS_PENDENTE; return STATUS_IO_PENDENTE; } //Copia os dados do pacote PtrPacoteBuffer = &Global_PtrContexto->PacotesRecebidos[Global_PtrContexto->Inicio_Lista]; memcpy((PVOID)Parametros->lpvOutBuffer, (PVOID)PtrPacoteBuffer->DadosBuffer, PtrPacoteBuffer->TamanhoBuffer); *(DWORD *)Parametros->lpcbBytesReturned = PtrPacoteBuffer->TamanhoBuffer; //Vai para o próximo da lista Global_PtrContexto->PacotesRecebidos[Global_PtrContexto->Inicio_Lista].Status = STATUS_LIVRE; Global_PtrContexto->PacotesRecebidos[Global_PtrContexto->Inicio_Lista].TamanhoBuffer = 0; Global_PtrContexto->Inicio_Lista = INC_CIRCULAR(Global_PtrContexto->Inicio_Lista); return STATUS_IO_SUCESSO; }

/************************************************ / FURB - BCC - NOTURNO - TRABALHO DE CONCLUSÃO DE CURSO / Autor - Paulo Fernando da Silva / Arquivo - Protocolo.c (Projeto VXD) / Objetivo - Definição e funções do driver de protocolo /************************************************ #include <basedef.h> #include <vmm.h> #include <ndis.h> #include <vwin32.h> #include <string.h> #pragma intrinsic(memcpy, memset) #include "Protocolo.h" #include "Funcoes.h" #pragma VxD_LOCKED_CODE_SEG #pragma VxD_LOCKED_DATA_SEG PTR_CONTEXTO Global_PtrContexto; NDIS_HANDLE ProtocoloMonitor; /************************************************ // DriverEntry - Chamado na "criação do driver" // (processo C ... continuação) /************************************************ NTSTATUS NDIS_API DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { NDIS_PROTOCOL_CHARACTERISTICS DadosProtocolo; NDIS_STRING NomeProtocolo = NDIS_STRING_CONST((PUCHAR)("MONITOR")); NDIS_STATUS Status; NdisZeroMemory((UCHAR*)&DadosProtocolo, sizeof(NDIS_PROTOCOL_CHARACTERISTICS)); //Seta dados do protocolo

DadosProtocolo.Name = NomeProtocolo; DadosProtocolo.MajorNdisVersion = 0x03; DadosProtocolo.MinorNdisVersion = 0x0A; DadosProtocolo.Reserved = 0; DadosProtocolo.BindAdapterHandler = Proto_ConectaAdaptador; DadosProtocolo.UnbindAdapterHandler = Proto_DesconectaAdaptador; DadosProtocolo.OpenAdapterCompleteHandler = Proto_OpenAdapter_Completado; DadosProtocolo.CloseAdapterCompleteHandler= Proto_CloseAdapter_Completado; DadosProtocolo.SendCompleteHandler = Proto_Send_Completado; DadosProtocolo.TransferDataCompleteHandler= Proto_TransferData_Completado; DadosProtocolo.ResetCompleteHandler = Proto_Reset_Completado; DadosProtocolo.RequestCompleteHandler = Proto_Request_Completado; DadosProtocolo.ReceiveHandler = Proto_Receber; DadosProtocolo.ReceiveCompleteHandler = Proto_ReceberCompletado; DadosProtocolo.StatusHandler = Proto_Status; DadosProtocolo.StatusCompleteHandler = Proto_StatusCompletado; DadosProtocolo.UnloadProtocolHandler = Proto_DescarregarProtocolo; NdisRegisterProtocol( //Registra um protocolo NDIS &Status, //retorna status &ProtocoloMonitor, //handle do protocolo &DadosProtocolo, //características do protocolo sizeof(NDIS_PROTOCOL_CHARACTERISTICS));//tamanho das características return (Status); } /************************************************ // Proto_ConectaAdaptador - (processo I) /************************************************ VOID NDIS_API Proto_ConectaAdaptador( OUT PNDIS_STATUS pStatus, IN NDIS_HANDLE BindContext, IN PNDIS_STRING AdapterName, IN PVOID SystemSpecific1, IN PVOID SystemSpecific2) { NDIS_STATUS CodigoErro; NDIS_MEDIUM MidiaProtocolo = NdisMedium802_3; UINT Indice, MidiaAdaptador; PTR_CONTEXTO PtrContexto = (PTR_CONTEXTO)BindContext; //Inicializa pacote travado do contexto PtrContexto->PacoteTravado.Status = STATUS_LIVRE; PtrContexto->PacoteTravado.DadosBuffer = 0; PtrContexto->PacoteTravado.TamanhoBuffer = 0; PtrContexto->PacoteTravado.lpoOvrlapped = 0; //Aloca memoria para pacotes recebidos PtrContexto->Inicio_Lista = 0; PtrContexto->Final_Lista = 0; for (Indice = 0; Indice < TAMANHO_LISTA_RECEBIDOS; Indice++) { PtrContexto->PacotesRecebidos[Indice].TamanhoBuffer = 0; PtrContexto->PacotesRecebidos[Indice].Status = STATUS_LIVRE;

108

PtrContexto->PacotesRecebidos[Indice].DadosBuffer = NULL; AlocaMemoria((PVOID *)&PtrContexto->PacotesRecebidos[Indice].DadosBuffer, TAMANHO_MAXIMO_BUFFER); if (PtrContexto->PacotesRecebidos[Indice].DadosBuffer == NULL) { LiberaMemoria((PVOID)PtrContexto); *pStatus = NDIS_STATUS_RESOURCES; return; } } // Aloca conjunto de Pacotes NdisAllocatePacketPool(pStatus, &PtrContexto->ConjuntoPacotes, 15, sizeof(PACOTE_RESERVADO)); if (*pStatus != NDIS_STATUS_SUCCESS) { LiberaMemoria((PVOID)PtrContexto); return; } // Aloca conjunto de Buffers NdisAllocateBufferPool(pStatus, &PtrContexto->ConjuntoBuffers, 15); if (*pStatus != NDIS_STATUS_SUCCESS) { NdisFreePacketPool(PtrContexto->ConjuntoPacotes); LiberaMemoria((PVOID)PtrContexto); return; } NdisOpenAdapter( //Faz a ligação entre o protocolo e um outro driver ou NIC pStatus, //status &CodigoErro, //código do erro &PtrContexto->Adaptador,//handle do adaptador &MidiaAdaptador, //tipo de mídia do adaptador &MidiaProtocolo, //tipo de mídia do protocolo 1, //qtd de mídias do protocolo ProtocoloMonitor, //handle do protocolo (NDIS_HANDLE)PtrContexto,//contexto do protocolo AdapterName, //nome do adaptador - "0000" 0, //opções NULL); //informações do NIC if (*pStatus != NDIS_STATUS_PENDING) Proto_OpenAdapter_Completado((NDIS_HANDLE)PtrContexto, *pStatus, CodigoErro); return; } /************************************************ // Proto_OpenAdapter_Completado - (processo J) /************************************************ VOID NDIS_API Proto_OpenAdapter_Completado( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status, IN NDIS_STATUS OpenErrorStatus) { PTR_CONTEXTO PtrContexto = (PTR_CONTEXTO)ProtocolBindingContext; // Isto está causando problemas !!! // Completa a conexão do adaptador // NdisCompleteBindAdapter(ProtocolBindingContext,//contexto da conexão // Status, // OpenErrorStatus);*/

// // Sinaliza que o Ovrlap está completado if (PtrContexto->Abrir_Ovrlapped != 0) { VWIN32_CompletaEvento(((OVERLAPPED *)PtrContexto->Abrir_Ovrlapped)->O_Internal); TiraMemoriaGlobal(PtrContexto->Abrir_Ovrlapped, sizeof(OVERLAPPED)); } if (Status != NDIS_STATUS_SUCCESS ) { NdisFreePacketPool(PtrContexto->ConjuntoPacotes); NdisFreeBufferPool(PtrContexto->ConjuntoBuffers); LiberaMemoria((PVOID)PtrContexto); return; } Global_PtrContexto = PtrContexto; return; } /************************************************ // Proto_DesconectaAdaptador - (processo K) /************************************************ VOID NDIS_API Proto_DesconectaAdaptador( OUT PNDIS_STATUS pStatus, IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE UnbindContext) { PTR_CONTEXTO PtrContexto = (PTR_CONTEXTO)ProtocolBindingContext; //Fecha uma ligação com um adaptador NdisCloseAdapter(pStatus, //retorna o status PtrContexto->Adaptador);//handle do adaptador if (*pStatus != NDIS_STATUS_PENDING) Proto_CloseAdapter_Completado(PtrContexto, *pStatus); return; } /************************************************ // Proto_CloseAdapter_Completado - (processo L) /************************************************ VOID NDIS_API Proto_CloseAdapter_Completado( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status) { PTR_CONTEXTO PtrContexto = (PTR_CONTEXTO)ProtocolBindingContext; UINT Indice; // Sinaliza que o Ovrlap está completado if (PtrContexto->Fechar_Ovrlapped != 0) { VWIN32_CompletaEvento(((OVERLAPPED *)PtrContexto->Fechar_Ovrlapped)->O_Internal); TiraMemoriaGlobal(PtrContexto->Fechar_Ovrlapped, sizeof(OVERLAPPED)); } if (Status == NDIS_STATUS_SUCCESS) { //Completa a desconexão do adaptador NdisCompleteUnbindAdapter(ProtocolBindingContext,//contexto da conexão Status); //retorna o status //Trata lista de pacotes recebidos PtrContexto->Inicio_Lista = 0; PtrContexto->Final_Lista = 0; for (Indice = 0; Indice < TAMANHO_LISTA_RECEBIDOS; Indice++) { LiberaMemoria((PVOID)PtrContexto->PacotesRecebidos[Indice].DadosBuffer);

109

PtrContexto->PacotesRecebidos[Indice].TamanhoBuffer = 0;

PtrContexto->PacotesRecebidos[Indice].Status = STATUS_NULO; } NdisFreePacketPool(PtrContexto->ConjuntoPacotes); NdisFreeBufferPool(PtrContexto->ConjuntoBuffers); LiberaMemoria((PVOID)PtrContexto); } return; } /************************************************ // Proto_Request_Completado - (processo M) /************************************************ VOID NDIS_API Proto_Request_Completado( IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_REQUEST PtrRequisicaoNdis, IN NDIS_STATUS Status) { PTR_CONTEXTO PtrContexto = (PTR_CONTEXTO)ProtocolBindingContext; //Seta bytes retornados para Requisicao_Ovrlapped if (PtrContexto->Requisicao_Ovrlapped != 0) { VWIN32_CompletaEvento(((OVERLAPPED *)PtrContexto->Requisicao_Ovrlapped)->O_Internal); TiraMemoriaGlobal(PtrContexto->Requisicao_Ovrlapped, sizeof(OVERLAPPED)); } //Tira buffer da memória global if ((DWORD)PtrRequisicaoNdis->DATA.SET_INFORMATION.InformationBuffer != 0) TiraMemoriaGlobal((DWORD)PtrRequisicaoNdis->DATA.SET_INFORMATION.InformationBuffer, (DWORD)PtrRequisicaoNdis->DATA.SET_INFORMATION.InformationBufferLength); return; } /************************************************ // Proto_Receber - Chamado quando o NIC indica a chegada de dados // (processo N) /************************************************ NDIS_STATUS NDIS_API Proto_Receber ( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE MacReceiveContext, IN PVOID HeaderBuffer, //cabeçalho do pacote IN UINT HeaderBufferSize, //tamanho do cabeçalho IN PVOID LookAheadBuffer, //buffer de dados IN UINT LookAheadBufferSize, //tamanho do buffer de dados IN UINT PacketSize) //tamanho total do pacote, sem o cabeçalho { PTR_CONTEXTO PtrContexto = (PTR_CONTEXTO)ProtocolBindingContext; PTR_PACOTE_TRAVADO PtrPacoteTravado; PCHAR pDadosBuffer; UINT Final_Lista; NDIS_STATUS Status; PTR_PACOTE_RESERVADO PtrPacoteReservado; PNDIS_PACKET PtrPacoteNids; PNDIS_BUFFER PtrBufferNids; UINT BytesTransferidos; // Buffer Ethernet inválido if (HeaderBufferSize != 14) return (NDIS_STATUS_NOT_ACCEPTED);

//Se o tamanho total dos dados é maior do que exite no buffer if (PacketSize > LookAheadBufferSize) { //Aloca um pacote NDIS NdisAllocatePacket(&Status, //Retorna o status &PtrPacoteNids, //pacote a ser alocado PtrContexto->ConjuntoPacotes);//conjunto de pacotes que pertence if (Status != NDIS_STATUS_SUCCESS) return NDIS_STATUS_NOT_ACCEPTED; //Copia o cabeçalho recebido para o último elemento da lista Final_Lista = PtrContexto->Final_Lista; pDadosBuffer = PtrContexto->PacotesRecebidos[Final_Lista].DadosBuffer; memcpy((PVOID)pDadosBuffer, (PVOID)HeaderBuffer, HeaderBufferSize); PtrPacoteReservado = ((PTR_PACOTE_RESERVADO)((PtrPacoteNids)->ProtocolReserved)); PtrPacoteReservado->DadosBuffer = (DWORD)pDadosBuffer; PtrPacoteReservado->TamanhoBuffer = HeaderBufferSize + PacketSize; PtrPacoteReservado->lpoOvrlapped = 0; PtrPacoteReservado->BytesRetornados = 0; //Mapeia um buffer NDIS em uma posição de memória já alocada NdisAllocateBuffer(&Status, //Retorna o status &PtrBufferNids, //Buffer descritor a ser alocado PtrContexto->ConjuntoBuffers,//conjunto de buffers a que pertence (PVOID)(pDadosBuffer + HeaderBufferSize), //início do buffer mapeado PacketSize); //Quantidade de bytes a mapear if (Status != NDIS_STATUS_SUCCESS) { NdisReinitializePacket(PtrPacoteNids); NdisFreePacket(PtrPacoteNids); return NDIS_STATUS_NOT_ACCEPTED; } //Faz a ligação entre um pacote e um buffer NdisChainBufferAtFront(PtrPacoteNids, PtrBufferNids); //Copia os dados recebidos de um NIC para dentro de um pacote do protocolo NdisTransferData(&Status, //retorna o status PtrContexto->Adaptador,//adaptador MacReceiveContext, //recebido do NIC e passado para o mesmo 0, //byte inicial da trasnferência PacketSize, //qtd de bytes para transferência PtrPacoteNids, //pacote que recebe a copia dos dados &BytesTransferidos); //qtd de bytes transferidos if (Status != NDIS_STATUS_PENDING) Proto_TransferData_Completado( ProtocolBindingContext, PtrPacoteNids, Status, BytesTransferidos); } else { PtrPacoteTravado = &PtrContexto->PacoteTravado; //Se o pacote pendente do contexto está pendente if (PtrPacoteTravado->Status == STATUS_PENDENTE) { //Copia os dados para o pDadosBuffer pDadosBuffer = (PCHAR)PtrPacoteTravado->DadosBuffer; memcpy((PVOID)pDadosBuffer, (PVOID)HeaderBuffer, HeaderBufferSize);

110

memcpy((PVOID)(pDadosBuffer + HeaderBufferSize), (PVOID)LookAheadBuffer, LookAheadBufferSize); //Libera pacote travado VWIN32_CompletaEvento(((OVERLAPPED *)PtrPacoteTravado->lpoOvrlapped)->O_Internal); TiraMemoriaGlobal(PtrPacoteTravado->DadosBuffer, PtrPacoteTravado->TamanhoBuffer); TiraMemoriaGlobal(PtrPacoteTravado->lpoOvrlapped, sizeof(OVERLAPPED)); PtrPacoteTravado->Status = STATUS_LIVRE; return (NDIS_STATUS_SUCCESS); } // Atualiza o início da lista Final_Lista = PtrContexto->Final_Lista; if (PtrContexto->PacotesRecebidos[Final_Lista].Status == STATUS_LIDO) PtrContexto->Inicio_Lista = INC_CIRCULAR(PtrContexto->Inicio_Lista); //Copia os dados para o pDadosBuffer / Lista pDadosBuffer = PtrContexto->PacotesRecebidos[Final_Lista].DadosBuffer; memcpy((PVOID)pDadosBuffer, (PVOID)HeaderBuffer, HeaderBufferSize); memcpy((PVOID)(pDadosBuffer + HeaderBufferSize), (PVOID)LookAheadBuffer, LookAheadBufferSize); //Adiciona na lista de pacotes recebidos PtrContexto->PacotesRecebidos[Final_Lista].TamanhoBuffer = LookAheadBufferSize + HeaderBufferSize; PtrContexto->PacotesRecebidos[Final_Lista].Status = STATUS_LIDO; PtrContexto->Final_Lista = INC_CIRCULAR(Final_Lista); } return NDIS_STATUS_SUCCESS; } /************************************************ // Proto_TransferData_Completado - (processo O) /************************************************ VOID NDIS_API Proto_TransferData_Completado( IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET PtrPacoteNids, IN NDIS_STATUS Status, IN UINT BytesTransfered) { PTR_CONTEXTO PtrContexto = (PTR_CONTEXTO)ProtocolBindingContext; PTR_PACOTE_RESERVADO PtrPacoteReservado; PNDIS_BUFFER PtrBufferNids; PCHAR pDadosBuffer; UINT Final_Lista; PTR_PACOTE_TRAVADO PtrPacoteTravado; //Remove a ligação entre o descritor de buffer e o pacote NDIS NdisUnchainBufferAtFront(PtrPacoteNids, &PtrBufferNids); if (PtrBufferNids != NULL)

NdisFreeBuffer(PtrBufferNids); if (Status == NDIS_STATUS_SUCCESS) { PtrPacoteReservado = ((PTR_PACOTE_RESERVADO)((PtrPacoteNids)->ProtocolReserved)); PtrPacoteTravado = &PtrContexto->PacoteTravado; if (PtrPacoteTravado->Status == STATUS_PENDENTE) { //Copia os dados para o pDadosBuffer pDadosBuffer = (PCHAR)PtrPacoteTravado->DadosBuffer; memcpy((PVOID)pDadosBuffer, (PVOID)PtrPacoteReservado->DadosBuffer, PtrPacoteReservado->TamanhoBuffer); //pacote travado VWIN32_CompletaEvento(((OVERLAPPED *)PtrPacoteTravado->lpoOvrlapped)->O_Internal); TiraMemoriaGlobal(PtrPacoteTravado->DadosBuffer, PtrPacoteTravado->TamanhoBuffer); TiraMemoriaGlobal(PtrPacoteTravado->lpoOvrlapped, sizeof(OVERLAPPED)); PtrPacoteTravado->Status = STATUS_LIVRE; } else { // Atualiza o início da lista Final_Lista = PtrContexto->Final_Lista; if (PtrContexto->PacotesRecebidos[Final_Lista].Status == STATUS_LIDO) PtrContexto->Inicio_Lista = INC_CIRCULAR(PtrContexto->Inicio_Lista); // Atuliza lista de pacotes recebidos PtrContexto->PacotesRecebidos[Final_Lista].TamanhoBuffer = PtrPacoteReservado->TamanhoBuffer; PtrContexto->PacotesRecebidos[Final_Lista].Status = STATUS_LIDO; PtrContexto->Final_Lista = INC_CIRCULAR(Final_Lista); } } NdisReinitializePacket(PtrPacoteNids); NdisFreePacket(PtrPacoteNids); return; } /************************************************ // Proto_DescarregarProtocolo - (processo P) /************************************************ VOID NDIS_API Proto_DescarregarProtocolo() { NDIS_STATUS Status; NdisDeregisterProtocol(&Status, ProtocoloMonitor); return; }

111

REFERÊNCIAS BIBLIOGRÁFICAS

BERNSTEIN, Terry et al. Segurança na Internet. Rio de Janeiro: Campus, 1997.

BINGHAM, John E. Manual de análise de sistemas. Rio de Janeiro: Ed. Interciência, 1977.

CANTU, Marco. Dominando o Delphi 5: a bíblia. São Paulo: Makron Books, 2000.

COMER, Douglas E. Interligação de rede com TCP/IP: princípios, protocolos e arquitetura.

Rio de Janeiro: Campus, 1998.

COMER, Douglas E; STEVENS, David L. Interligação de rede com TCP/IP: projeto,

implementação e detalhes internos. Rio de Janeiro: Campus, 1999.

CHIOZZOTO, Mauro; SILVA, Luíz Antônio Pinto. TCP/IP tecnologia e implementação.

São Paulo: Érica, 1999.

CYCLADES BRASIL. Guia Internet de conectividade. São Paulo: Ed. SENAC, 2000.

GOMES, Olavo José Anchieschi. Segurança total. São Paulo: Makron Books, 2000.

HONEYCUTT, Jerry. Usando a Internet. Rio de Janeiro: Campus, 1998.

JANSA, Kris. Microsoft C. São Paulo: Makron Books, 1992.

STARLIN, Gorki. Manual completo do hacker. Rio de Janeiro: Book Express, 2000.

McCLURE, Stuart; SCAMBRAY, Joel; KURTZ, Georg. Hackers expostos: segredos e

soluções para a segurança de redes. São Paulo: Makron Books, 2000.

MENDONÇA, Alexandre; ZELENOVSKY, Ricardo; FRANÇA, Paulo R. Programação de

hardware em windows 9x/2000 – 1o parte. Developer’s, Rio de Janeiro, v. 5, n. 57, p 38-41,

maio 2001.

MENDONÇA, Alexandre; ZELENOVSKY, Ricardo; FRANÇA, Paulo R. Programação de

hardware em Windows 9x/2000 – 2o parte. Developer’s, Rio de Janeiro, v. 5, n. 58, p 42-44,

jun. 2001.

112

MICROSOFT PRESS. Microsoft Windows 98 resource kit. Rio de Janeiro: Campus, 1999.

MICROSOFT CORPORATION. Microsoft developer network, 2000. Disponível em

<http://msdn.microsoft.com/default.asp>. Acesso em: 20 set. 2001.

MICROSOFT CORPORATION. Microsoft Windows 2000 DDK, 2000. Disponível em

<http://www.microsoft.com/ddk/W2kDDK.asp>. Acesso em: 8 jun. 2001.

MICROSOFT CORPORATION. Microsoft Windows 1998 DDK, 1999. Disponível em

<http://www.microsoft.com/ddk/ddk98.asp>. Acesso em: 8 jun. 2001.

OLIVEIRA, Wilson José. Hackers: invasão e proteção. Florianópolis: Visual Books, 2000.

PROENÇA JR. Mário Lemes. TCP/IP, Londrina, [2000?]. Diponível em

<http://proenca.uel.br/curso-redes-graduacao/1998/trab-08/equipe-01/indice.htm>. Acesso em

5 set. 2001.

SCHILDT, Herbert. C completo e total. São Paulo: Makron Books, 1991.

SEGURANÇA máxima. Rio de Janeiro: Campus, 2000.

STARLIN, Gorki. TCP/IP completo. Rio de Janeiro: Book Express, 1998.