sábado, 18 de junho de 2011

Delphi | Port Scaner Super Simples

Port Scanner

Port Scanner é um programa capaz de varrer um sistema, remoto ou local, a procura de portas abertas. Estas portas por sua vez, quando abertas, podem estar disponibilizando alguns serviços para utilização remota e é fundamental para qualquer administrador de rede (segurança) ou “usuário malicioso” (cracker) saber quais portas estão sendo utilizadas pelo sistema, tanto para a proteção, pelo lado do administrador, quanto pela invasão, pelo lado do cracker.

Saber quais portas estão abertas no sistema e quais serviços estão ativos nestas portas é muito importante, pois é o passo principal para qualquer invasão de sistema. É sabendo qual serviço está ativo em uma porta que se pode começar a verificar se este serviço em questão é vulnerável a alguma técnica de exploração conhecida, como explorá-la, como ganhar acesso ao sistema, etc.

Como funciona?

Teoricamente o funcionamento de um Port Scanner é bem simples. Basicamente ele tenta se conectar com o servidor desejado em uma porta desejada. Se a conexão for estabelecida, o programa imprime uma mensagem para o usuário confirmando o estado da porta testada como “Aberta”. Caso a conexão não se estabeleça, a mensagem de “Porta Fechada” é enviada. Bem simples não? Pois é, porém, com a incrível capacidade intelectual dos Hackers, algumas outras formas de Port Scanner foram desenvolvidas a partir da dificuldade de detecção do scanner pelo lado dos Administradores de Redes. O método que desenvolveremos no nosso programa é o TCP Full Connect, ou seja, uma conexão TCP completa com o servidor em questão. Este método é o mais primitivo e também o mais fácil de ser detectado pelo administrador, porém como o nosso artigo não tem o intuito de formar Cracker de sistemas, este método é mais que o necessário para você se inteirar sobre como construir um Port Scanner no Delphi. Outras formas de Port Scanner são:

TCP SYN (Half Open): Este já é um método mais complexo de Port Scanner, pois não abre uma conexão TCP completa com a máquina alvo e se torna assim mais difícil de se identificar um scanning deste tipo. O que programas deste tipo fazem é enviar uma pacote SYN para a máquina alvo. Caso seja recebido um pacote SYN-ACK, significa que a porta está aberta. Porém, caso seja recebido um pacote RST, indica que a porta está fechada. Após este processo, o programa exibe para o usuário o estado da porta e prossegue em sua verificação.
TCP FIN: Este é o método mais apreciado pelos atacantes, pois é chamado de modo STEALTH, ou invisível, não sendo detectado pelos sistemas de defesa. Consiste em enviar um pacote FIN para a porta alvo. Caso o pacote recebido seja um RST, indica que a porta está fechada, mas caso o pacote FIN seja ignorado, significa que a porta está aberta.
UDP SCAN: Neste método são enviados pacotes UDP de 0 bytes para cada porta alvo. Caso seja recebida a mensagem “ICMP port unreachable”, indica que a porta está fechada. Caso contrário, o programa imprime a mensagem alegando a porta como em estado de aberta.

TCP Full Connect no Delphi

Criar um Port Scanner TCP Full Connect do Delphi é relativamente simples. O Delphi já vem com alguns componentes para a criação e utilização de sockets. Ele provê uma enorme gama de componentes para criação de Clientes FTP, Telnet, Finger, Web, POP, SMTP, servidores HTTP, etc.

Para a criação deste tipo de Port Scanner, o TCP Full, utilizaremos o componente chamado TTCPClient, que fica localizado na paleta Internet. É com este componente que será possível se conectar com um endereço especificado nas portas pré-definidas para a verificação de seus estados (aberta ou fechada).

No componente TTCPClient temos as seguintes propriedades que são as fundamentais para o entendimento do funcionamento do nosso port scanner. As propriedades de nosso interesse são:

  • RemoteHost = Esta propriedade define o endereço do servidor que se deseja conectar.
  • RemotePort = A porta que se deseja conectar. Esta porta poderá ser alterada diversas vezes durante a execução do Port Scanner, pois é justamente esta capacidade que torna o programa funcional.
  • Connect = Conecta o TTCPClient com o servidor definido na propriedade RemoteHost com a porta definida em RemotePort.
  • Disconnect = Desconecta o TTCPClient do servidor.

Com estas propriedades já podemos iniciar a construção do nosso programa.

Criando a Interface do Port Scanner

Inicie o Delphi e crie um novo projeto chamado psc.dpr (a unit você poderá salvar como unit_psc.pas). No formulário inicial que abrir, mude as seguintes propriedades do Form1 no ObjectInspector como seguem abaixo:

  • Caption = Port Scaner v1.0b
  • BorderStyle = bsToolWindow
  • WindowState = Normal

Após estas modificações o antigo Form1 ficará desta forma:

www.invasao.com.br

Post Scanner Fig.1 – form1 do Port Scanner

Agora, neste nosso formulário, adicionaremos os seguintes componentes que serão os responsáveis pela interação do Port Scanner com o usuário.

Quantidade Tipo
5 TLabel
1 TEdit
2 TSpinEdit
1 TMemo
1 TTCPClient
2 TButton

Após a adição destes componentes, altere as propriedades dos mesmos para as que seguem abaixo:

Componente Propriedade Conteúdo
Tlabel1 Caption Servidor
Tlabel2 Caption Porta Inicial
Tlabel3 Caption Porta Final
Tlabel4 Caption Verificando a porta:
Tlabel5 Caption 0
TspinEdit1 Name Inicio
TspinEdit2 Name Fim
Tmemo1 Name Listagem
Tbutton1 Caption Iniciar
Tbutton2 Caption Parar
Tedit1 Text endereco

Com estas modificações, arrume os componentes no formulário para que fiquem mais ou menos com esta Interface:

www.invasao.com.br
Port Scanner 2 – Fig.2 – Nova form1 do Port Scanner

Neste ponto, falta muito pouco para o nosso Port Scanner ficar pronto. Temos agora que programar o funcionamento do nosso programa para que ele seja funcional e corresponda às nossas expectativas.

Programando os componentes

Nesta parte da nossa criação iremos adicionar programação aos componentes utilizados no programa para que este realmente funcione. Iremos começar da seguinte maneira:

  • Vamos cria uma variável global que será a responsável por parar a execução da verificação no servidor remoto quando o usuário clicar no botão Parar.
  • No código fonte do programa vamos adicionar, na sessão correspondente as variáveis globais, a nossa variável Stop.

...
Var
Form1: TForm1;
Stop: integer; // a nossa variável entra aqui!

Implementation
...

Agora iremos inserir a programação no nosso botão correspondente ao início da varredura de portas no servidor remoto, o nosso botão Iniciar. Dê um duplo clique neste botão para inserirmos o código responsável pelo seu funcionamento.

O código responsável é o que segue abaixo:

Var i : integer;
Begin
Try

Listagem.clear;
Stop:= 0 ;
TCPClient1.remotehost:=edit1.text;
For I:= inicio.value to fim.value do
Begin
If Stop = 1 then break;

Label5.caption:=inttostr(i);
Application.ProcessMessages;
TCPCLiente1.remoteport:= inttostr(i);
TCPClient.Active:=true;

If TCPClient1.connect then
Listagem.lines.add('A Porta ['+ inttostr(i)+ '] está aberta.');
TCPClient1.disconnect;
End;


Except
On E:Exception do Begin
Listagem.lines.add('Erro: ' + E.Message);
End;
End;


Listagem.lines.add('Verificação Terminada.');

End;

Feita a adição do código responsável pelo funcionamento do nosso botão Iniciar, resta-nos agora adicionar o código relativo ao botão Parar, para que depois possamos analisar as linhas de código do nosso programa Port Scanner.

Para adicionar a programação ao nosso botão Parar, dê um duplo clique no mesmo e adicione o código abaixo:

Stop:=1;

Pronto! A codificação do nosso programa está terminada e ele já está pronto para ser executado. Mas, antes disto, vamos analisar a programação.

Entendendo o Código

Como podemos ver, foi bem simples a construção da interface do programa assim como a adição de seu código-fonte. Vamos agora entender as linhas de código adicionadas e as suas respectivas funções.

Na parte de programação referente ao nosso botão Iniciar temos inicialmente a linha:

Var i: Integer;

Esta linha corresponde à criação da variável i, que será a responsável por auxiliar no loop For para a contagem das portas a serem verificadas.

A seguir, na linha:

Listagem.clear;

Limpamos o nosso Tmemo1.

Na linha:

Stop:=0;

Iniciamos o valor desta variável para 0, pois desta forma o programa continuará a varredura através das portas selecionadas pelo usuário até que o loop For acabe ou que o usuário pressione o nosso botão Parar.

Em

TCPClient1.Remotehost:=Edit1.text;

Repassamos para a propriedade RemoteHost do nosso TTCPClient o conteúdo do componente Edit1.text, que será o servidor repassado pelo usuário.

Temos então o início do loop For baseado nas portas Inicial e Final escolhidas pelo usuário nos componentes TspinEdit.

For i:= inicio.value to fim.value do

A seguir, verifica-se se o botão Parar foi acionado, solicitando o cancelamento da verificação (loop).

If Stop=1 then break;

Agora, exibimos na Interface a porta que está sendo verificada no momento

Label5.caption:=inttostr(i);

Pedimos ao sistema operacional que processe as informações do programa, evitando assim que o mesmo não tenha o efeito de congelamento evidente.

Application.ProcessMessages;

Agora, nas linhas a seguir, definimos para a propriedade RemotePort o nosso TCPClient1 qual porta devera ser verificada no momento, depois ativamos o nosso TCPClient1 e, em seguida, verificamos se foi obtido sucesso.Caso o sucesso seja obtido, adicionamos no nosso Memo1 uma linha contendo a porta que foi encontrada com o estado de aberta. Depois, independente do estado da porta, pedimos sua desconexão.

TCPCLient1.remoteport:= inttostr(i);
TCPClient.Active:=true;

If TCPClient1.connect then
Listagem.lines.add('A Porta ['+ inttostr(i)+ '] está aberta.');
TCPClient1.disconnect;
End;

Em seguida, terminamos o loop e tratamos todas as exceções que possam ocorrer entre os blocos protegidos try.

Except
On E:Exception do Begin
Listagem.lines.add('Erro: ' + E.Message);
End;
End;

Por fim, escrevemos no nosso Memo1 a mensagem de que a verificação foi terminada e finalizamos a execução do programa.

Listagem.lines.add('Verificação Terminada.');

End;

Para concluir, no nosso botão Parar temos a linha de código:

Stop:=1;

Esta linha é responsável por colocar o valor 1 na variável Stop, para que quando o usuário clique no botão Parar, o loop de verificação das portas pare graças ao trecho de código do botão Iniciar abaixo:

If Stop=1 then Break;

Concluindo

Bem pessoal, agora é só salvar todo o projeto e executá-lo. Faça testes em algum servidor que você tenha acesso e/ou saiba que não irá prejudicar ninguém e muito menos incomodar. Vale relembrar que, se deu tudo certo com o seu Port Scanner, você tem uma ferramenta poderosíssima nas mãos e cabe a você usá-la de forma segura e principalmente com intuitos educacionais.

Sobre o Autor

T. J. Nogueira é escritor da Ciência Moderna, editora de livros de informática. Já tem dois livros publicados: Invasão de Redes: Ataques e Defesas, como os Hackers utilizam a linguagem de programação C para efetuar invasões via Internet, e Tudo Sobre buffer overflow. No momento está terminando seu terceiro livro, Como tornar o Windows XP seguro: passo a passo e ainda encontra tempo para trabalhar em mais três livros e de elaborar artigos aqui para a Aldeia

Meu amigo TJ, aldeense de carteirinha, é fanático por leitura. É dele a frase “o que eu mais quero é simplesmente que as pessoas leiam e leiam e leiam cada vez mais sobre qualquer tipo de coisa, desde de budismo até engenharia reversa”. Este é seu primeiro artigo publicado aqui na Aldeia, mas preparem-se… já tem coisa nova saindo do forno e é sobre Gerenciadores Remotos!

Da minha parte, quero dar as boas vindas ao nosso mais novo colaborador e tornar públicos os meus mais sinceros agradecimentos. Além disso, como de costume, um grande abraço da vovó para todos, especialmente para o TJ.

Abraço!
-bRx-

0 comentários:

Postar um comentário