[Portuguese] Winsockets In C

EDB-ID:

13567

CVE:

N/A


Platform:

Multiple

Published:

2009-12-22

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 <stdio.h>
#include <winsock2.h> // 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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <winsock2.h>
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 <porta>\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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#include <winsock2.h>//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 <ip> <porta_inicial> \
<porta_final>\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