Starting .. ! ####################################################### ## NEMESIZ SECURITY GROUP ## ## www.nemesiz.forum.st ## ## ## ## Winsockets Em C - Por Felix_Poison ## ####################################################### ! ####################################################### Estou aqui mais uma vez, desta vez, escrevendo sobre algo que muitos chamam de bicho de 7 cabeças : Winsockets em C .. nao temos muitos documentos sobre isso em portugues, e muito excasso em ingles, entao, espero que esse meu texto te sirva ! Autor : Felix_Poison A.k.A : Félix Costa D. S. E-mail : elodia_superstar[at]hotmail[dot]com Data : Agosto de 2009, Brasil ****************************************************************** INDICE: 00 - OBJETIVO 01 - PRE-REQUISITO 02 - INTRODUÇAO (preparaçao e notas) 03 - PROGRAMANDO COM WINSOCKETS 03.1 - iniciando DLL 03.2 - criando socket 03.3 - configurando socket 03.4 - entendendo as estruturas 04 - FUNÇOES 04.1 - connect () 04.2 - gethostbyname() 04.3 - bind() 04.4 - listen() 04.5 - accept() 04.6 - send() e recv() 04.7 - shutdown() 04.8 - funçoes de conversao (ordenamento de bytes) 05 - ENTENDENDO E TRATANDO ERROS DE WINSOCKETS 06 - TERMINANDO 07 - LINKS E REFERECIAS 08 - CONSIDERAÇOES FINAIS #################################################################### ################### ## 00 - OBJETIVO ## o objetivo desse texto é aprender a mecher com sockets em C para windows. se praticarmos e estudarmos nao só C mas tambem o sistema windows poderemos criar ferramentas tao poderosas quanto no unix like. hoje em dia eh importante tambem deixar os seus sources o mais 'portavel' possivel, sendo de facil uso em varios sistemas diferentes. ######################## ## 01 - PRE-REQUISITO ## é necessario que voce tenha um certo conhecimento sobre C (intermediario), saiba de cor oque é e como funciona o TCP/IP. como ja disse, se voce ja souber programar sockets para Linux,otimo! se nao sabe, nao tem problema,aqui abordaremos tudo minunsiosamente. é fato que pode ser mais facil pra Unix, mas oque muda é muito pouco, e nao é nada complicado,cara.. as funçoes mesmo,seguem o mesmo modelo tanto de declaraçao quanto de uso. nao é necessario ter conhecimento da API do windows, por hora,trataremos do basico apenas. ########################################## ## 02 - INTRODUÇAO (preparaçao e notas) ## bem, sendo breve, uma das diferenças de programar sockets em c pra Windows é que precissamos botar uma DLL pra rodar. a winsock.dll e algumas outras coisas ae que esqueci (xP). existem versoes pra essa dll,a winsock 1.1 que roda de windows 95 pra baixo e a versao nova, winsock 2.0 que roda de um 98 pra cima e tals. ah,usaremos o DevC++ para compilar nossos projetos,visto que ele é a melhor IDE pra windows, apesar de ser baseado no GCC(Unix),o Dev tem algumas frescuras, como todo bom windows tem Uma coisa,é possivel que de erro ao compilar os sources com winsockets, para resolver isso faça o seguinte: abra o DevC++,va na opçao Ferramentas (tools),depois Opçoes do compilador e na aba compilador,onde tem escrito para adicionar alguma linha voce poem " -lwsock32 " e pronto, da ok lá . ##################################### ## 03 - PROGRAMANDO COM WINSOCKETS ## ************************** ** 03.1 - iniciando DLL ** para programar em winsockets, precissamos incluir o header "winsock.h" (versao 1.1) ou "winsock2.h" (versao 2.0),so lembrando que isso e regra! outra coisa, devemos botar a DLL para iniciar,isso nos fazemos com as funçoes WSAStartup () . Sintaxe: WSAStartup(MAKEWORD(2,0),&wsaData); bem, acho que nao vou conseguir explicar assim,vamos comentar em algum code: ---CUT HERE--- int main (int argc, char *argv[]) { int meusock; struct sockaddr_in maneh; // declaraçao da nossa estrutura WSADATA dados; // declramos a função WSADATA com o nome 'dados' ..... // isso quer dizer que tem code depois,sacou? if (WSAStartup(MAKEWORD(2,0),&dados == SOCKET_ERROR) { ..... ---cut here--- calma, vamos entder essas duas linhas,cada funçao e que diabos é esse de WSAStartup: WSAStartup -> a funçao que verefica a versao da dll e a inicia MAKEWORD -> é a versao da dll,no caso,se fosse a versao 1.1 da dll ficaria : "MAKEWORD(1,1) &dados -> como podem ver,esse é o nome que damos a funçao WSADATA SOCKET_ERROR -> só frescurite, caso a funçao desse erro esqueci de explicar sobre "struct sockaddr_in maneh", bem isso é uma estrutura, pra quem nao sabe,se voce nao sabe como funciona uma estrutura aconselho a voce aprender antes,aqui o texto é apenas sobre winsockets. maaaaaaaas,como eu sou bonzinho ja ja falaremos sobre oque diabos é isso espero que voces tenham entendido bem a funçao WSADATA, serve para iniciar a dll responsavel pela conexao,isso éregra, sem ela sem conexao! sigam,se voce ainda nao pegou ira pegar Wink Ah, deve-se usar a funçao WSACleanup () no final de cada chamada de WSAStartup bem sucedida, pois ela limpa a estrutura WSA =) *************************** ** 03.2 - criando socket ** assim como no Unix, é muito facil declarar um socket: 'int meusock;" logicamente um socket é do tipo inteiro,agora para iniciarmos um socket tambem é a mesma coisa dos Unix Likes: " meusock=socket(int af,int tipo,int protocolo); " onde: meusock -> declarando que meusock' é um socket int AF_ -> é o adress family,utilizamos sempre no começo a macro AF_ seguido dos seus valores,vamos ver quais valores sao esses: Citação: ===extraido de winsock.h do dev-c++=== #define AF_UNSPEC 0 #define AF_UNIX 1 #define AF_INET 2 #define AF_IMPLINK 3 #define AF_PUP 4 #define AF_CHAOS 5 #define AF_IPX 6 #define AF_NS 6 #define AF_ISO 7 #define AF_OSI AF_ISO #define AF_ECMA 8 #define AF_DATAKIT 9 #define AF_CCITT 10 #define AF_SNA 11 #define AF_DECnet 12 #define AF_DLI 13 #define AF_LAT 14 #define AF_HYLINK 15 #define AF_APPLETALK 16 #define AF_NETBIOS 17 #define AF_VOICEVIEW 18 ===extraido de winsock.h do dev-c++=== int tipo -> é onde especificamos o tipo de socket usado,como no unix eles podem ser: SOCK_STREAM (TCP), SOCK_DGRAM(UDP),SOCK_RAW(raw) só lembrando que winsock 1.1 nao roda Raw Sockets. OBS:mais informaçoes sobre os tipos,pesquise sobre conceito de sockets. os tipos podem ser,de acordo com o Dev: Citação: ===extraido de winsock.h do dev-c++=== #define SOCK_STREAM 1 #define SOCK_DGRAM 2 #define SOCK_RAW 3 #define SOCK_RDM 4 #define SOCK_SEQPACKET 5 ===extraido de winsock.h do dev-c++=== int prtocolo -> tipo de protocolo que usaremos. podem ser: Citação: ===extraido de winsock.h do dev-c++=== #define IPPROTO_IP 0 #define IPPROTO_ICMP 1 #define IPPROTO_GGP 2 #define IPPROTO_TCP 6 #define IPPROTO_PUP 12 #define IPPROTO_UDP 17 #define IPPROTO_IDP 22 #define IPPROTO_ND 77 #define IPPROTO_RAW 255 #define IPPROTO_MAX 256 ===extraido de winsock.h do dev-c++=== ah, pra ficar mais 'biito',use apenas o numero de cada um,no caso se fosse IPPROTO_IP ficaria apenas o numero dele,que é o '0'. beleza, entao ficaria assim: "meusock=socket(AF_INET,SOCK_STREAM,0);" pronto,declaramos e iniciamos 'meusock' =) vamo ver como está ficando so pra nao restar duvidas.. ---CUT HERE--- #include #include // header obrigatorio para uso de winsockets int main (int argc,char *argv[]){ int meusock; // declaraçao de nosso socket struct sockaddr_in nsg; // nossa estrutura,calma voce entenderá WSADATA dados; // declraçao da funçao WSADATA .... // pra dizer que tem mais code depois desses exemplos rs.. if(WSAStartup(MAKEWORD(2,0),&nsg == SOCKET_ERROR)// inicializaçao da dll winsock ....//mais code rs.. meusock=socket(AF_INET,SOCK_STREAM,0);// inicializao de nosso socket ..... closesocket(meusock); /* uma coisa,sempre que nao quisermos mais usar o nosso socket, devemos usar a funçao closesocket(),isso ira destruir a conexao e liberar a memoria.*/ WSACleanup();//limpamdo a estrutura WSA return (0);} ---CUT HERE--- Mano,se voce nao entendeu algo,aconselho a voce reeler isso ate entender,ae pode continuar,pode ficar a vontade pra tirar suas duvidas no forum ******************************** ** 03.3 - configurando socket ** digamos que voce desej 'alterar' o organismo de um socket normal, existem duas funçoes para isso,getsockopt() e setsockopt(). lembrando,isso nao se faz necessario,apenas se voce ja manjar bem winsock e quiser mecher em algo da configuraçao do socket. -*getsockopt() sintaxe: int getsockopt(meusock,int level,int optname,char *optval,int *optlen) meusock -> socket a ser alterado,configurado e tals int level -> nivel em que optaremos definir a configuraçao,pode ser:SOL_SOCKET ou IPPROTO_TCP. int optname -> nome da opçao que queremos usar. char *optval -> buffer que armazenará o valor da opçao int *optlen -> ponteiro que indica o tamanho de optval. -*setsockopt() sintaxe: int setsockopt(meusock,int level,int optname,char *optval,int optlen) meusock -> socket a ser alterado e configurado e tals.. int level -> nivel da opçao que queremos usar,pode ser SOL_SOCKET ou IPPROTO_TCP int optname -> nome da opçao que queremos usar char *optval -> buffer onde está o novo valor da opçao escolhida int optlen -> tamanho do buffer de optval. $ - Opçoes de int optname. como podemos ver,int optname é a opçao que usaremos na configuraçao do nosso socket a ser alterado,elas mudam de acordo com int level,ou seja, SOL_SOCKET ou IPPROTO_TCP. -*opcoes para SOL_SOCKET: Citação: === retirado do texto do x86config === VALOR TIPO SO_ACCEPTCONN BOOL Socket estah escutando conexoes. SO_BROADCAST BOOL Socket estah configurado para a transmissao de mensagens broadcast. SO_DEBUG BOOL Debugging estah habilitado. SO_DONTLINGER BOOL Se TRUE, entao a opcao SO_LINGER estah desabilitado. SO_DONTROUTE BOOL Roteamento desabilitado. SO_ERROR int Retorna status de erro e zera. SO_GROUP_ID GROUP O identificado do grupo ao qual o socket pertence. Esta opcao nao pode ser alterada por setsockopt. SO_GROUP_PRIORITY int Prioridade relativa para sockets de um mesmo grupo. SO_KEEPALIVE BOOL Evitar queda de conexao por timeout. SO_LINGER struct linger Retorna as opcoes linger atuais. SO_MAX_MSG_SIZE unsigned int Tamanho maximo de uma mensagem para sockets orientados a mensagens (ex.: SOCK_DGRAM). SO_OOBINLINE BOOL Dados fora de banda (oob) estah sendo recebido na data stream normal. SO_PROTOCOL_INFO WSAPROTOCOL_INFO Descricao do protocolo que estah atribuido este socket. SO_RCVBUF int Tamanho do buffer para recebimentos. SO_REUSEADDR BOOL O socket pode ser usado para um endereco local que jah estah em uso. Toda conexao eh unicamente identificada por uma combinacao de enderecos locais e enderecos remotos, nao ha nenhum problema em ter dois sockets compartilhando o mesmo endereco local, desde que os enderecos remotos sejam distintos. SO_SNDBUF int Tamanho do buffer para envios. SO_TYPE int Tipo de socket (exemplo: SOCK_STREAM, SOCK_RAW, etc) PVD_CONFIG Service Provider Dependent Uma estrutura de dados 'opaca' do provedor de servicos associado ao socket s. Este objeto armazena informacoes de configuracao correntes do provedor de servico. O formato especifico desta estrutura de dados eh especifico ao provedor de servico. -*Opçoes de optname para IPPROTO_TCP Citação: === retirado do texto do x86config === TCP_NODELAY BOOL Disabilita o algoritmo Nagle no envio. Opcoes no estilo BSD que nao sao suportadas para getsockopt sao: SO_RCVLOWAT int Receber baixa marca-dagua SO_RCVTIMEO int Receber timeout SO_SNDLOWAT int Enviar baixa marca-dagua SO_SNDTIMEO int Enviar timeout TCP_MAXSEG int Retorna tamanho maximo de segmento (maximum segment size, mss) Tipos BOOL (booleano) podem ser TRUE ou FALSE (1 ou 0, respectivamente). A opcao linger controla a acao tomada quando dados nao enviados entra em espera (queue) num socket e um closesocket() eh chamado neste socket. ************************************** ** 03.4 - entendendo as estruturas! ** vamos a um code é uma boa explicaçao -- cut -- ..... int meusock,connecta;// declaraçao de meusock e connecta struct sockaddr_in nsg;// declaraçao da nossa estrutura WSADATA poison;//declaraçao de WSADATA .... if(WSAStartup(MAKEWORD(2,0),&poison==SOCKET_ERROR){// inicializao de winsock.dll .... meusock=socket(AF_INET,SOCK_STREAM,0); // inicializaçao do socket nsg.sin_family=AF_INET; /*sao nas estruturas onde ficaram os dados da conexao,tais como endereço,porta e etc,explicarei mais a baixo*/ nsg.sin_port=htons(atoi(argv[2])); //onde ficará a porta da conexao .. nsg.sin_addr.s_addr=inet_addr(atoi(argv[1])); //onde ficará o endereço da conexao memset(&(nsg.sin_zero),0,Cool; //zeramos a estruturas aqui. .... -- cut -- vamos explicar melhor oque corresponde cada um: sin_family -> é a mesma coisa de quando declaramos o nosso socket,lembra? o adressa family e tals,da mesma forma ele pode ser: sin_family eh uma das seguintes opcoes: #define AF_UNSPEC 0 #define AF_UNIX 1 #define AF_INET 2 #define AF_IMPLINK 3 #define AF_PUP 4 #define AF_CHAOS 5 #define AF_IPX 6 #define AF_NS 6 #define AF_ISO 7 #define AF_OSI AF_ISO #define AF_ECMA 8 #define AF_DATAKIT 9 #define AF_CCITT 10 #define AF_SNA 11 #define AF_DECnet 12 #define AF_DLI 13 #define AF_LAT 14 #define AF_HYLINK 15 #define AF_APPLETALK 16 #define AF_NETBIOS 17 #define AF_VOICEVIEW 18 sin_port -> é a porta da conexao,a qual voce se conctará ou escutará uma conexao,exemplo. elas podem ser: #define IPPORT_ECHO 7 #define IPPORT_DISCARD 9 #define IPPORT_SYSTAT 11 #define IPPORT_DAYTIME 13 #define IPPORT_NETSTAT 15 #define IPPORT_FTP 21 #define IPPORT_TELNET 23 #define IPPORT_SMTP 25 #define IPPORT_TIMESERVER 37 #define IPPORT_NAMESERVER 42 #define IPPORT_WHOIS 43 #define IPPORT_MTP 57 #define IPPORT_TFTP 69 #define IPPORT_RJE 77 #define IPPORT_FINGER 79 #define IPPORT_TTYLINK 87 #define IPPORT_SUPDUP 95 #define IPPORT_EXECSERVER 512 #define IPPORT_LOGINSERVER 513 #define IPPORT_CMDSERVER 514 #define IPPORT_EFSSERVER 520 #define IPPORT_BIFFUDP 512 #define IPPORT_WHOSERVER 513 #define IPPORT_ROUTESERVER 520 #define IPPORT_RESERVED 1024 sin_addr -> é o endereço da conexao e tals memset -> é usado pára zerar a estrutura (ver uso de memset em texto sobre C) bem, acho que deu pra voces pegarem o uso das estruturas em sockets. ################## ## 04 - FUNÇOES ## bem, falarei de algumas apenas, visto que a declaraçao e uso delas é o mesmo para Unix, e como ja foi postado no forum um texto sobre sockets do Nash, apenas abordarei aqui algumas para nao restar duvidas em relaçao ao modo de uso dos mesmos, quer uma dica? va analizando sources que usem winsockets, t enha certeza,isso ajudará voce a entender como funciona mais o negocio. ********************** ** 04.1 - CONNECT() ** funçao usada para conectar em algo,dã sintaxe:"connecta=connect(meusock,(struct sockaddr *)&nsg,sizeof(nsg)); " meusock -> socket que declaramos que será usado para conexao nsg -> nome da estrutura que contem dados da conexao ---CUT HERE--- ..... nsg.sin_family = AF_INET; nsg.sin_port = htons (21); // estrutura definindo a porta 21 nsg.sin_addr.s_addr = inet_addr(atoi(argv[1])); // definindo o endereço da conexao memset(&(nsg.sin_zero),0,Cool;//zera a estrutura connecta=connect(meusock,(struct sockaddr *)&nsg,sizeof(nsg));// declaraçao de connect () if(connecta<0){ // apenas checagem de erro printf("erro,cara"); exit(1);} ..... ---CUT HERE--- **************************** ** 04.2 - GETHOSTBYNAME() ** muitos sources pedem "digite ip do host" e coisa e tal, com o uso dessa funçao ao inves de pormos o IP botaremos o DNS dele, sacou? sintaxe de gethostbyname() : "struct hostent * gethostbyname(char *name);" assim, antes devemos especificar uma estrutura do tipo hostent como um ponteiro, ae mais a frente no code usamos o ponteiro para indicar a funçao gethostbyname() exemplo: "strucut hostent *ip " //primeiro declaramos aqui " ip==gethostbyname(argv[1]) " //depois usamos aqui onde ip é o nosso ponteiro da estrutura hostent. ******************* ** 04.3 - BIND() ** sendo claro, essa funçao é usada para ser associada a uma porta na maquina local, ou seja, abri-la. sintaxe:> " bind(meusock,(struct sockaddr *)&local,sizeof(local)) " meusock-> socket a ser usado local-> estrutura voltada a maquina local,obvio ********************* ** 04.4 - LISTEN() ** usada para 'escutar' uma conexao,é usada junto com bind(),ela tambem indica quantes conexoes serao permitidas ao mesmo tempo, o tal do backlog sintaxe: " listen(meusock,5); " meusock->nosso amigo socket 5 -> numero de conexoes permitidas ao mesmo tempo,ou seja se uma 6 pessoa for se conectar ela nao conseguirá ********************* ** 04.5 - ACCEPT() ** A função accept(), como já é de se imaginar, aceita uma conexão quando ela é detectado pelo programa. Sua declaração vêm como: " SOCKET accept(novosock, struct sockaddr* addr, int* addrlen); " novosock -> é o Socket usado para aceitar a conexao. addr -> é um ponteiro pra uma estrutura do tipo sockaddr(Tipo o bind() ), nela, ficam armazenados as informações da estrutura e do cliente que requisitou a conexão. Você não é obrigado a armazená-las, para isso, coloque NULL em seu lugar. addrlen -> é um ponteiro onde a função vai colocar o tamanho em bytes da estrutura addr recebida do cliente. Se você colocou um NULL no addr, o addrlen também retornará vazio. Esta função, fica esperando por uma conexão para aceitá-la, enquanto ela espera, o programa ficará parado, se você precisar fazer com que o seu programa execute outra função, você precisa fazê-lo assíncrono. Se ocorrer algum erro na conexão, ele vai lhe devolver um estado de INVALID_SOCKET. só para irmos acompanhando ae vai uma parte de uma backdoor que estou fazendo em C para Windows aguardem pois em breve estará pronta, amigos ah,lembrando que eu alterei o source original para ficar mais facil de voces entenderem, logo, esse nao é o code original Código: -- cut here -- .... #include #include #include #include int main (int argc,char *argv[]){ int s0ck,s1ck,tamanho; WSADATA poison; struct sockaddr_in local; struct sockaddr_in hacker; if(argc != 2){ printf("Backdoor usando Winsockets,Para artigo sobre winsockets\n"); printf("Coded By Felix_Poison\n - Proof Of Concept\n"); printf("Uso %s \n",argv[0]); exit(1);} WSAStartup(MAKEWORD(2,0),&poison); local.sin_family = AF_INET; local.sin_port = htons(atoi(argv[1])); local.sin_addr.s_addr = INADDR_ANY; memset(&(local.sin_zero),0,8); s0ck = socket(AF_INET,SOCK_STREAM,0); bind(s0ck,(struct sockaddr *)&local,sizeof(local)); listen(s0ck,5); tamanho = sizeof(struct sockaddr_in); if((s1ck = accept(s0ck,(struct sockaddr *)&hacker,&tamanho)));// accept () { ..... -- cut, bro -- **************************** ** 04.6 - SEND() e RECV() ** send() é usada para enviar dados para um socket e recv() é usado para receber dados. sintaxe de send(): " send(novosock,"Felix_Poison\n",13,0); " novosock -> um novo socket,usado para enviar os dados "Felix_Poison\n" -> mensagem que será enviada,o modo de declarar os dados é de gosto seu,voce que sabe manjar C deve saber como usar,eu espero =) 13 -> ae é o numero de bytes da msg "Felix_Poison",claro ae contem 12 apenas,mas lembre-se que é contado tambem o terminador nulo,logo é 13 bytes! 0 - > flags,parametros adicionais, se nao sabe nem mecha,deixa assim mesmo. sintaxe de recv(): " recv(meusock,buffer,strlen(buffer),0) " meusock -> socket usado para receber os dados buffer -> endereço da area do buffer strlen(buffer) -> tamanho do buffer,ae eu fiz uso de strlen para ficar mais 'leet',se voce nao sabe o uso de strlen,recomendo que procure 0 -> flags,parametros adicionais ********************** ** 04.7- SHUTDOWN() ** se tivermos usado send() e/ou recv(), é bom usar a funçao shutdown() antes de closesocket(), shutdown() irá encerrar o envio de dados, ae depois usa-se closesocket(). sintaxe: " shutdown(meusock,int how) " meusock -> socket que será encerrado o envio de dados int how -> how tem os seguintes valores,ou seja,ele pode ser: SD_RECEIVE = recebimento de dados é encerrado SD_SEND = envio de dados é encerrado SD_BOTH = envio e recebimento de dados é encerrado ficaria assim entao: shutdown(meusock,SD_SEND); ******************************************************** ** 04.8 - Funçoes de conversao (ordenamento de bytes) ** voces devem ter percebido o uso de algo como htons,inet_addr, etc. "nsg.sin_addr.s_addr = inet_addr(atoi(argv[1])); " inet_addr é usado para converter um IP no formato decimal (127.0.0.1) para in_addr(formato entendido pela rede), caso algum erro for maior que 255 é retornado erro. já inet_ntoa faz o contrario,converte de in_addr para o formato legivel para nois. temos tambem as funçoes Xtoy,que sao elas: htons,htonl,ntohl e ntohs. tipo assim,cara.. oo pc pode armazenar bytes em uma ordem diferente da ordem normal que é a Network Byte Order, mas isso causaria problemas no envio dos dados,para contonar isso, usamos essas funçoes de conversao de bytes para o ordenamento correto. #################################################### ## 05 - ENTENDENDO E TRATANDO ERROS DE WINSOCKETS ## só pra voce ficar por dentro dos erros que podem ser retornados por funçoes WSA *erros retornados por WSAStartup() $WSASYSNOTREADY = rede nao esta pornta para conexao $WSAVERNOTSUPPORT = versao da dll winsock exigida nao suportada ou errada. $WSAEINPROGRESS = bloqueamento de winsock.dll $WSAEPROCLIM = numero de tarefas suportadas pelo winsock alcançado. *erros retornados por WSACleanup() $WSANOTINITIALISED = chamada de WSACleanup() bem sucedida é necessaria $WSAENETDOWN = falha na rede $WSAEINPROGRESS = bloqueamento de winsock.dll *tratando de erros usa-se a funçao WSAGetLastError() e WSASetLastError(). sintaxe: void WSASetLastError(int) ou int WSAGetLastError(). elas retornam um codigo que representa o ultimo erro que aconteceu. ##################### ## 06 - TERMINANDO ## bem, ae esta,amigo, procurei deixar o texto o mais simples e "entendivel" (Oo) possivel, mas de uma forma bem avançada, assim dizendo. trabalhar com socket pode ser algo meio dificil no começo, mas depois que voce pegar é muito,muito facil mesmo,cara. nada é impossivel,se voce procurar se esforçar e correr atras,voce conseguirá! existem muitissimos poucos materiais sobre winsockets em portugues, como eu ja disse,espero que esse texto te ajude de alguma forma e te abra muitas portas ae nesse mundo. espero ver voces programando logo,fazendo a cena crescer, e contribuindo,é claro! afinal,para poder matar um inimigo,devemos antes conhece-lo espero que voces tenham gostado do artigo. Qualquer correçao de algum erro meu, sugestao ou duvidas seram super bem vindas,claro fiquem a vontade,pois sem voces o forum nao é nada. como bonus,postarei um scanner feito em C para windows feito pelo 6_bl4ck9_f0x6. nao irei modificar nada, apenas comentar as linhas do que aprendemos hoje nesse artigo. porque podem haver pessoas que pensem assim: "beleza,eu sei declarar e tals,mas onde por esse troço?", pode parecer meio bobo,mas tem gente que fica meio perdido, entao pra finalizarmos essa primeira parte com chave de ouro,la vai o code: Código: --- cut here -- #include #include #include #include #include //header de uso de winsock #define BADSTAT -1 #define BACKLOG 10 #define MINDHUNTER "http/footprint" int tsuder (void){ printf (" 6"); Sleep (200); printf ("_"); Sleep (100); printf ("B"); Sleep (200); printf ("l"); Sleep (100); printf ("4"); Sleep (200); printf ("c"); Sleep (100); printf ("k"); Sleep (200); printf ("9"); Sleep (100); printf ("_"); Sleep (200); printf ("f"); Sleep (100); printf ("0"); Sleep (200); printf ("x"); Sleep (200); printf ("6\n\n"); Sleep (100); } WSADATA dados; struct sockaddr_in vitima;/*olha aqui a declaraçao das estruturas*/ struct sockaddr_in list_ing; char banner[255], my_footprint[255]; char buffer_received[255];/*definiçao do buffer usado em recv posteriomente*/ char httpfoot[sizeof (MINDHUNTER)]; int main (int argc, char *argv[]){ int x=0, i=0, size, check; int my_sock, connectx, door;//declaraçao de socket char about[]=" Emperial[ScanneR] \n\n\ BY\n"; system ("cls"); if (argc==1){goto Smile;} /* Anti Stack Overflow: */ strncpy (httpfoot, argv[1], strlen (MINDHUNTER)); printf ("[%d] Protegido contra Stack Overflow\n", strlen (httpfoot)); if (strcmp (httpfoot, MINDHUNTER) == 0){ system ("cls"); system ("title HTTP FootPrint"); printf ("HTTP FootPrint by 6_Bl4ck9_f0x6\n\ Copyright 2006-2008 Viper Corp.\n\n"); printf ("======================================================\n"); printf ("%s\n", about); tsuder (); if (WSAStartup (MAKEWORD (1,1),&dados) == SOCKET_ERROR)//inicializaçao de winsock.dll na versao 1.1 { fprintf (stderr, "Erro ao iniciar dll's de socket!\n"); WSACleanup();//limpando WSA exit (BADSTAT);} my_sock = socket (AF_INET, SOCK_STREAM, 0);//inicializao de socket if (my_sock == -1){ perror ("Error socket!"); WSACleanup (); exit (BADSTAT);} list_ing.sin_family = AF_INET;/*estrutua com os dados da conexao como porta,endereço e tals..*/ list_ing.sin_port = htons (80); list_ing.sin_addr.s_addr = INADDR_ANY; memset(&list_ing.sin_zero,0,8);//zerar a estrutura if (bind(my_sock, (struct sockaddr *)&list_ing, sizeof (list_ing)) == -1)/*declaraçao e uso de bind()*/ { fprintf (stderr, "Erro ao Bindear porta!\n"); exit (BADSTAT);} fprintf (stdout, "Porta %d em Listening...", 80); if ((listen (my_sock, BACKLOG)) == -1)//inicializao de listen() { system ("cls"); puts ("Ops! Nao consegui escutar\n"); return 0;} check = accept (my_sock,0,0);//accept() if (check==-1){ puts ("Problemas na conexao!\n"); return 1;} printf ("\n\nO endereco IP [%s] estabeleceu uma conexao na porta [%d]\n", inet_ntoa (list_ing.sin_addr), ntohs (list_ing.sin_port)); /* Fazer um looping para ele sempre voutar a escutar na porta e gravar no file os log's =) */ FILE *foot_log; if ((foot_log = fopen ("Foot_log.log", "a")) == NULL){ puts ("Nao consegui criar o arquivo de log,\n"); puts ("possivelmente por fauta de espaco no disco\n"); // Mas da pra visualizar na shell -> puts (buffer_received =) <- return (1);} recv (my_sock, buffer_received, strlen (buffer_received),0);/*uso de recv() com o buffer ja definido la em cima ;)*/ fprintf (foot_log, "%d", buffer_received); puts ("\nArquivo de log criado com sucesso!\n"); fclose (foot_log); printf ("\n======================================================\n"); exit (BADSTAT);} Smile: if ((argc < 4) || (argc > 4)){ printf ("\nx===x==x=====x===x=====x==x===x==x==x==x===x\ ===xx==x==\n"); printf ("%s\n", about); tsuder (); fprintf (stderr, "Uso: %s \ \n\n", argv[0]); printf ("x===x==x=====x===x=====x==x===x==x==x==x===x\ ===xx==x==\n"); Sleep (200); exit (BADSTAT);} door = atoi (argv[2]); if (WSAStartup (MAKEWORD (1,1),&dados) == SOCKET_ERROR)*/inicializao da dll winsock*/ { puts ("Problemas -> WSAStartup"); exit (BADSTAT);} printf ("%s\n", about); tsuder (); fprintf (stderr, "[X] ============X==============X===== [X]\n\n"); for (door;door<= atoi (argv[3]);door++){ my_sock = socket (AF_INET, SOCK_STREAM, 0);//declarao de socket() if (my_sock == -1){ perror ("Error socket!"); WSACleanup (); exit (BADSTAT);} vitima.sin_family = AF_INET;//olha ae elas outra vez =) vitima.sin_port = htons (door); vitima.sin_addr.s_addr = inet_addr (argv[1]); for (x;x<8;x++){ vitima.sin_zero[x]=(char)0;} size = sizeof (vitima); SetConsoleTitle ("Varrendo usando TCP -> SYN "); connectx = connect (my_sock, (struct sockaddr *)&vitima, size);//uso de connect() if (connectx == SOCKET_ERROR){ fprintf (stderr, "Porta [%d] fechada\n", door);} else { fprintf (stdout, "Porta [%d] Aberta <-- \n", door); puts ("\nBanner:\n"); if (recv (my_sock, banner, sizeof (banner), 0) < 0)//outra vez uso de recv() { fprintf (stderr, "Erro ao recever banner!\n"); exit (BADSTAT);} puts (banner); FILE *scan_log; scan_log=fopen ("scan_log.txt", "a"); if (!scan_log){ perror ("\nErro ao abrir arquivo de log -> "); printf ("\n"); continue;} fprintf (scan_log, "Porta [%d] em [%s] Aberta\ \n", door, inet_ntoa (vitima.sin_addr)); fclose (scan_log);}} fprintf (stderr, "\n[X] ============X==============X===== [X]\n"); closesocket (my_sock);//fechamento do socket WSACleanup ();//limpando de vez WSA return (0); } -- cut here -- ############################## ## 07 - LINKS E REFERENCIAS ## http://www.ataliba.eti.br/sections/old-hacking/unsekurity/texto1/winsocks.txt - Bom texto http://nemesiz.forum.st/c-c-c-f20/programacao-de-sockets-em-c-para-linux-t234.htm - texto do Nash Leon sobre sockets para Linux,realmente uma preciosidade de texto. ############################### ## 08 - CONSIDERAÇOES FINAIS ## espero que tenham gostado do artigo de hoje,espero que ajudem voces ae, e faça a cena crescer aguardem, pois continuarei sim o texto, nos aprofundando mais na API do windows tambem. Gostarei de agradeçer a Deus primeiramente, ao Fzero por me abrir as portas do Hacking Puro e da Programaçao;ao ReatoR que apesar de nunca mais ter falado com ele,ele sempre me ajuda; a mim mesmo,a minha mae por ser a melhor do mundo,ao meu mp4 por estar sempre ao meu lado,em todas as horas.. a todo o pessoal da NSG e a todos voces que estao lendo esse texto e que sempre nos ajudam, sem nem mesmo perceber,pois sem voces lendo nao seriamos nada.. ah,é claro,a uma pessoa muito especial,a razao por escrever =) "Hey,esse texto é para voce,Truta Wink " Até []'s,Felix_Poison ~ Nemesiz Security Group