sábado, 18 de junho de 2011

Tutorial de Winsocket em C (Parte I)

Ao longo de aproximadamente 7 matérias irei mostrar para vocês a funcionalidade de sockets no windows com a linguagem C. Será necessário um conhecimento considerável em C para o uso desta matéria. Usaremos o DEV C++, disponível no site do bloodshed, para compilar todos os exemplos aqui expostos.

Lembrando que ensinarei apenas o socket “puro”. Não passarei pela parte de Raw-Sockets nestas matérias.

Tudo que se comunica com algo fora do seu pc faz-se necessário o uso de um “tipo” de programação especial que se chama socket. Eu imagino que todas as linguagens de programação tenham programação em socket. C/C++, Delphi, PHP, Perl, Pascal, até Assembly tem programação em socket.

A partir do momento que você sabe sockets, você conseguirá facilmente fazer servidores/clientes, backdoors, portscanner, e quase tudo relacionado a internet. E é exatamente isso que ensinarei com essas matérias.

Um grande problema para quem quer entrar nesta área é achar uma documentação sobre isso na internet… Pois todos os grandes tutoriais são voltados para Unixes likes. O que é, na verdade, uma grande utopia. Pois se a intenção de um tutorial como esse é que todos conheçam e saibam fazer seus próprios programas, commo postam tutorias em Unixes já que a maioria dos usuários usam Windows? Por isso decidi postar um tutorial que abrirá muitas portas a vocês.

Na internet tudo tem sua família e seu respectivo protocolo. As família que você mais encontrará são:

AF_INET (Arpa Internet Protocols) – É a que agente mais vai usar, talvez a única.
AF_UNIX (Unix Internet Protocols)
AF_ISSO (Iso Protocols)
AF_NS (Xerox Network System Protocols)
E os protocolos são baseados no TCP (SOCK_STREAM) e UDP (SOCK_DGRAM) e podem ser estes:
0 – IP – Internet Protocol
1 – ICMP – Internet Control Message Protocol
2 – IGMP – Internet Group Multicast Protocol
3 – GGP – Gateway-Gateway Protocol
6 – TCP – Transmission Control Protocol
17 – UDP – User Datagram Protocol
Para se começar a programar em sockets no C é necessário declarar a biblioteca winsock.h. Vamos a um esboço agora de como começaria um programa:
#include
#include //Biblioteca para se programar em sockets

int main(){
int sock; //declaramos no socket como sendo uma variável inteira
structure sockaddr_in alvo; /*declaramos que o alvo é uma variável de structure sockaddr_in. Vamos ver isso mais a frente*/

WSADATA wsaData;
WSAStartup(MAKEWORD(1, 1), &wsaData); /*estas duas linhas fazem o windows entender que é para iniciar a dll e ocx responsável por comunicação na internet. Todo o programa de socket deve conter essas linhas. Mais a frente vamos ver isso melhor*/

sock=socket(AF_INET, SOCK_STREAM, 0); /*declaração do socket que é da seguinte forma: socket(família, tipo do protocolo, número do protocolo);*/
alvo.sin_family=AF_INET; //Família que usaremos para conectar no alvo
alvo.sin_port=htons(80); //porta que conectaremos
alvo.sin_addr.s_addr=inet_addr(“10.100.23.2″); //meu ip na minha rede, mude para outro qualquer
memset(&(alvo.sin_zero), ‘/0′, 8); //zera a estrutura(sin_zero) e copia na memória(memset)
.
.
.
}

Bem, esse é o início do nosso primeiro programa. Vamos entender tudo por partes. A structure sockaddr_in tem a seguinte estrutura segundo o winsock.h:
struct sockaddr_in {
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};

Então você deve declarar cada uma dessas coisas quando você declara algo do tipo struct sockaddr_in.

Outra coisa foi a seguinte linha:

WSAStartup(MAKEWORD(1, 1), &wsaData);

Nessa linha agente inicia as dll’s responsáveis por conexões a internet (winsock.dll se não me engano e algumas outras) e usamos a versão 1.1. Essa versão pode ser alterar para 2.0 e 2.2. Mas como a matérias serão feitas para todos os windows, usaremos a versão 1.1.

Outra linha importante foi a linha:

alvo.sin_port=htons(80);

Essa linha transforma o número 80 para um network short. Nos protocolos, as máquinha se comunicam através de números de rede, podem ser short ou long, depende do tipo. Tudo está descrito na biblioteca Winsock.h.

Connect( )

A função connect tem por objetivo conectar no alvo. Sua sintaxe segundo a biblioteca winsock.h é:

int PASCAL connect(SOCKET,const struct sockaddr*,int);
Isso significa: connect(socket_que_declaramos, (struct sockaddr *)&alvo (usa algumas coisas que especificamos lá em cima do alvo), e um valor inteiro que define o tamanho da struct do destino);

Quando o valor de connect retorna 0, significa que a conexão foi feita. Se retorna um número negativo, a conexão não foi feita.

Vamos a um pequeno exemplo agora?
#include
#include

int main(){
int sock, conecta;
struct sockaddr_in alvo;

WSADATA wsaData;
WSAStartup(MAKEWORD(1, 1), &wsaData);

if ((sock=socket(AF_INET, SOCK_STREAM, 0))<0){
perror(“Erro em socket!”);
exit(1);
}

alvo.sin_family=AF_INET;
alvo.sin_port=htons(80);
alvo.sin_addr.s_addr=inet_addr(“200.221.2.45″); //Esse é o IP da UOL!
memset(&(alvo.sin_zero), ‘/0′, 8);

conecta=connect(sock, (struct sockaddr *)&destino, sizeof(struct sockaddr));

if (conecta<0) printf(“Porta fechada”);
else printf(“Porta aberta!”);

getch();

closesocket(sock); //Fecha o socket
WSACleanup(); //Limpa a estrutura WSA
return 0;
}
É possível que dê erro ao compilar. Para Isso você deve fazer o seguinte: Clique em Tools, Compiler Options, ative a checkbox que diz Add the following commands when calling compiler, e digite o seguinte comando “-l wsock32″ sem as aspas!.

Bem, este é um exemplo bem remoto de um pequeno portscanner, já que ele escaneia a porta 80. Deixo um pequeno desafio a vocês, faça um programa que escaneie das portas 10 a 8080.

0 comentários:

Postar um comentário