elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.


 


Tema destacado: Píldoras formativas en seguridad de la información


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse)
| | |-+  Pequeño sniffer en C
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: 1 2 3 4 5 6 7 [8] 9 10 Ir Abajo Respuesta Imprimir
Autor Tema: Pequeño sniffer en C  (Leído 30,182 veces)
Leber


Desconectado Desconectado

Mensajes: 338


"Fracta, non verba"


Ver Perfil WWW
Re: Pequeño sniffer en C
« Respuesta #70 en: 12 Enero 2009, 13:20 »

Código:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>

#define SIZE 2048
#define ICMP IPPROTO_ICMP
#define TCP  IPPROTO_TCP

const char *ip_format(int ip);

int
main(void)
{
struct iphdr *__ip;
struct tcphdr *tcp;
struct udphdr *udp;
int _dfs;
int bytes_read = 0;
unsigned char *information;

if( getuid() != 0)
{
fprintf(stderr,"You must be root\n");
exit(-1);
}

if((_dfs = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) == -1)
{
fprintf(stderr,"Socket Error-> (%s)\n",strerror(errno));
exit(-1);
}

information = (unsigned char *)calloc(SIZE+1,sizeof(char));
__ip = (struct iphdr *)information;

printf("Waiting packets...\n");


while(1)
{
bytes_read = recv(_dfs, information, SIZE, 0);
if(bytes_read == -1)
{
fprintf(stderr,"Recv error-> (%s)\n",strerror(errno));
break;
}
else if(bytes_read > 0)
{
switch(__ip->protocol)
{
case ICMP:
printf("-ICMP \n");
break;
case TCP:
printf("S\t ip: %s\n",ip_format(__ip->saddr));
printf("D\t ip: %s\n",ip_format(__ip->daddr));
break;
default:
printf("Protocol: %d\n",__ip->protocol);
printf("Not yet, protocol not supported\n");
break;
}
memset(information,0,SIZE);
}
else
{
printf("Any packet\n");
continue;
}
}

free(information);

return 0;
}

const char *ip_format(int ip)
{
unsigned char *fmt;
static char buffer[1024];

       memset(buffer,0,sizeof(buffer)-1);

fmt = NULL;
fmt = ( unsigned char *)&ip;

snprintf(buffer,sizeof(buffer)-1,"%d.%d.%d.%d.",fmt[0],fmt[1],fmt[2],fmt[3]);

return buffer;
}

De momento tengo esto, como ya digo, parece ser que las ip's son validas, pero se cuela alguna a veces que no entiendo por que, pe:

Recargo pagina de elhacker.net, de esta:

Código:
bash-3.1# ./sniffer
Waiting packets...
S        ip: 63.246.146.121.
D        ip: 10.0.0.2.
S        ip: 63.246.146.121.
D        ip: 10.0.0.2.
S        ip: 63.246.146.121.
D        ip: 10.0.0.2.
S        ip: 63.246.146.121.
D        ip: 10.0.0.2.
S        ip: 63.246.146.121.
D        ip: 10.0.0.2.
S        ip: 63.246.146.121.
D        ip: 10.0.0.2.
S        ip: 63.246.146.121.
D        ip: 10.0.0.2.
S        ip: 63.246.146.121.
D        ip: 10.0.0.2.
S        ip: 63.246.146.121.
D        ip: 10.0.0.2.
S        ip: 63.246.146.121.
D        ip: 10.0.0.2.
S        ip: 63.246.146.121.
D        ip: 10.0.0.2.
S        ip: 63.246.146.121.
D        ip: 10.0.0.2.
S        ip: 63.246.146.121.
D        ip: 10.0.0.2.
S        ip: 63.246.146.121.
D        ip: 10.0.0.2.
S        ip: 63.246.146.121.
D        ip: 10.0.0.2.
S        ip: 63.246.146.121.
D        ip: 10.0.0.2.
S        ip: 63.246.146.121.
D        ip: 10.0.0.2.
S        ip: 63.246.146.121.
D        ip: 10.0.0.2.
S        ip: 63.246.146.121.
D        ip: 10.0.0.2.
S        ip: 63.246.146.121.
D        ip: 10.0.0.2.
S        ip: 63.246.146.121.
D        ip: 10.0.0.2.
S        ip: 63.246.146.121.
D        ip: 10.0.0.2.
S        ip: 63.246.146.121.
D        ip: 10.0.0.2.
S        ip: 63.246.146.121.
D        ip: 10.0.0.2.

Al parecer todo marcha bien, pero..

Código:
S        ip: 194.116.187.18.
D        ip: 10.0.0.2.
S        ip: 38.99.77.152. <-- ImageShack? Que hace ahi?!
D        ip: 10.0.0.2.
S        ip: 66.196.98.175. <--Yahoo?!
D        ip: 10.0.0.2.
S        ip: 63.246.146.121. <--elhacker
D        ip: 10.0.0.2.
S        ip: 63.246.146.121. <--elhacker
D        ip: 10.0.0.2.
S        ip: 63.246.146.121.<-- elhacker
S        ip: 74.125.45.127. <--- google?! lo mismo, que hace ahi?!
D        ip: 10.0.0.2.

Como ya ven, no acaba de ir fino del todo, habra que hacerle unos retoques, a ver que le podemos sacar.
10.0.0.2 es la ip privada de mi pc ;)

Saludos y vamos adelante a ver





En línea

"Solo los tontos carecen de preucupaciones." Johann Wolfgang Goethe
Leber


Desconectado Desconectado

Mensajes: 338


"Fracta, non verba"


Ver Perfil WWW
Re: Pequeño sniffer en C
« Respuesta #71 en: 12 Enero 2009, 13:22 »

An IPPROTO_RAW socket is send only. If you really want to receive all IP packets use a packet(7) socket with the ETH_P_IP protocol. Note that packet sockets don't reassemble IP fragments, unlike raw sockets.

RAW sockets are generally rather unportable and should be avoided in programs intended to be portable.

http://linux.die.net/man/7/raw
http://linux.die.net/man/7/packet

Gracias Eternet_Idol, lo mirare y a ver que tal, pero muchas gracias  ;)

Saludos


En línea

"Solo los tontos carecen de preucupaciones." Johann Wolfgang Goethe
Makiz0rz

Desconectado Desconectado

Mensajes: 208


Pero guat de fak?


Ver Perfil
Re: Pequeño sniffer en C
« Respuesta #72 en: 12 Enero 2009, 13:32 »

Es normal que salgan otras IPs, sobre todo la de Google puede ser porque tengas el gmail abierto, etc. La de imageshack porque hayas cargado alguna imagen hosteada ahí mientras recargas el foro. Lo raro es que aparezcan IPs que no existan, pero al menos por esa parte, el sniffer está correcto xD.

El resto me lo miro mejor cuando llegue a casa.

un saludow
En línea

AlbertoBSD
💻🌎🌍🌏🌐 NWO📱
Colaborador
***
Desconectado Desconectado

Mensajes: 3.114


Libertad!!!!!


Ver Perfil WWW
Re: Pequeño sniffer en C
« Respuesta #73 en: 12 Enero 2009, 16:57 »

Si es normal lo las IP.

Voy a probar ver los manuales que puso Eternet_Idol, ademas de ver si existe su contraparte en FreeBSD

Saludos.
En línea

Crackeame si puedes Wallet.dat
Makiz0rz

Desconectado Desconectado

Mensajes: 208


Pero guat de fak?


Ver Perfil
Re: Pequeño sniffer en C
« Respuesta #74 en: 17 Enero 2009, 19:28 »

Aun sigo con esto xD, he encontrado sniffers y cosas que ya podrían hacer que mi tema funcionase, pero eso no me vale, quiero programarlo yo para entenderlo todo bien y que me sirva de algo.

He modificado un poco el código y lo he estado probando y comparando.

De momento está así:

Código
  1.  
  2. #include <netinet/in.h>
  3. #include <fcntl.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <errno.h>
  8. //#include <unistd.h>
  9. //#include <sys/types.h>
  10. //#include <sys/socket.h>
  11. #include <netinet/ip.h>
  12. #include <netinet/tcp.h>
  13.  
  14.  
  15. #include <linux/if_ether.h>
  16. #include <linux/if_packet.h>
  17.  
  18. //#include <linux/tcp.h>
  19.  
  20. #define ERROR -1
  21. #define KB 1024
  22.  
  23.  
  24.  
  25. int main(int argc, char *argv[]){
  26.  
  27. if(geteuid() != 0) {
  28. fprintf(stderr,"\nTienes que ser root.\n");
  29. exit(ERROR);
  30. }
  31.  
  32.  
  33. if (argc < 2 ){
  34. printf("+==============================================+\n");
  35. printf("| Sniffer. Modo de uso: ./porsnif start        |");
  36. printf("\n| Se añadirán más opciones, menú provisional.  |\n");
  37. printf("+==============================================+\n");
  38. exit(1);
  39.  
  40. }
  41. int diff;
  42. char st[6]="start";
  43. diff = strcmp(st, argv[1]);
  44.  
  45.  
  46. if (diff==0){
  47.  
  48. int s,r;
  49. struct ethhdr *ethhead;
  50. struct iphdr *iphead;
  51. struct tcphdr *tcphead;
  52. struct icmphdr *icmphead;
  53. unsigned char *buff = (char*) calloc(65 * KB,sizeof(char));
  54.  
  55.  
  56.  
  57. if ((s = socket(AF_INET, SOCK_RAW, 6)) <0 ){
  58. printf ("Error al crear el socket!!!1111!11111!\nS: %d\n", s);
  59. exit (-1);
  60. }
  61.  
  62.  
  63.  
  64. iphead = (struct iphdr *)buff;
  65. printf("Esperando paquetes...\n");
  66. while(1){
  67. r = recv(s, buff, 64* KB, 0);
  68.  
  69. if(r > 0){
  70. switch(iphead->protocol) {
  71. case IPPROTO_ICMP:
  72. printf(">> ICMP, ip_src: %s ->",inet_ntoa(iphead->saddr));
  73. printf("\t ip_dst: %s\n", inet_ntoa(iphead->daddr));
  74. break;
  75. case IPPROTO_TCP:
  76.  
  77.                                  //POSIBLE FALLO:
  78.                                        tcphead=(struct tcphdr*)(buff + sizeof(struct ethhdr) + sizeof(struct iphdr));
  79.  
  80. printf(">> TCP, src: %s :%d",inet_ntoa(iphead->saddr), ntohs(tcphead->source));
  81. printf("  ->\t dst: %s :%d\n", inet_ntoa(iphead->daddr), ntohs(tcphead->dest));
  82.  
  83.  
  84. break;
  85. default:
  86. fprintf (stderr,"Fixme: unsupported protocol\n");
  87. break;
  88. }
  89. memset(buff,0,64 * KB);
  90. tcphead = NULL;
  91. }else{
  92. fprintf(stderr,"recv(): %s\n",strerror(errno));
  93. }
  94. }
  95. return 0;
  96.  
  97.  
  98.  
  99. }
  100. else{
  101. printf("\nParámetros incorrectos. Escribe ./porsnif sólamente para ver la ayuda.\n");
  102.  
  103. }
  104.  
  105.  
  106. }
  107.  
  108.  

Todo está en plan provisional, por supuesto y el código bastante guarro lleno de zonas que he estado probando y las he dejado comentadas (antes había muchas más). Cuando lo termine del todo lo limpiaré un poco. :'D

Bueno, las cuestiones ahora más importantes son:

1) El puerto por el que conecta. He estado viendo códigos y probando este y llego a la conclusión de que seguramente el fallo esté por:

tcphead=(struct tcphdr*)(buff + sizeof(struct ethhdr) + sizeof(struct iphdr));


2) Recibir cualquier tipo de protocolo. No me deja poner un 0 en

s = socket(AF_INET, SOCK_RAW, 6)

Tengo que poner un 6 para capturar TCP y si quiero capturar los ICMP, pongo un 1 y hago ping y todo me sale correcto.


3) Ver también los paquetes que envío. De momento sólo veo los recibidos, como puedo hacer para que se vean los que envío también?
-Edito- Va, hay un post arriba de Eternal Idol acerca de los paquetes saientes, lo miraré más a fondo, aunque como digo, de C ando bastante cortito, por eso quiero aprender más.

Bueno, muchas gracias a todos, a ver si al final consigo lo que me propongo xD.

Un saludo
« Última modificación: 17 Enero 2009, 19:31 por Makiz0rz » En línea

AlbertoBSD
💻🌎🌍🌏🌐 NWO📱
Colaborador
***
Desconectado Desconectado

Mensajes: 3.114


Libertad!!!!!


Ver Perfil WWW
Re: Pequeño sniffer en C
« Respuesta #75 en: 18 Enero 2009, 05:34 »

  //POSIBLE FALLO:
                                        tcphead=(struct tcphdr*)(buff + sizeof(struct ethhdr) + sizeof(struct iphdr));

mmm estas haciendo el calculo mal.

Yo la verdad de momento lo he dejado, no puedo ni recibir TCP, tengo problemas con 2 Discos duros, y he decidido de momento volver a libnet y libpcap.
En línea

Crackeame si puedes Wallet.dat
Eternal Idol
Moderador
***
Desconectado Desconectado

Mensajes: 5.512


La mano invisible del mercado me robo la billetera


Ver Perfil WWW
Re: Pequeño sniffer en C
« Respuesta #76 en: 18 Enero 2009, 12:56 »

Concuerdo con Anon, esto no tiene logica: tcphead=(struct tcphdr*)(buff + sizeof(struct ethhdr) + sizeof(struct iphdr));

Si iphead = (struct iphdr *)buff; entonces tcphead=(struct tcphdr*)(buff + sizeof(struct iphdr));
En línea

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón
Makiz0rz

Desconectado Desconectado

Mensajes: 208


Pero guat de fak?


Ver Perfil
Re: Pequeño sniffer en C
« Respuesta #77 en: 18 Enero 2009, 18:02 »

Esta mañana he estado mirando y cambiando cosas y casi casi tenía eso que has puesto, que claro, visto ahora sí me parece lo más lógico xD.
Muchísimas gracias, ya rulan los puertos también :'D.

A ver si soluciono los otros problemillas también, aunque con esto que tengo ya puedo ir haciendo cosas mucho más interesantes. Pongo el código definitivo por si a alguien le puede servir de algo:

Código
  1. #include <netinet/in.h>
  2. #include <fcntl.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <errno.h>
  7. #include <netinet/ip.h>
  8. #include <netinet/tcp.h>
  9.  
  10.  
  11. #define ERROR -1
  12. #define KB 1024
  13.  
  14.  
  15.  
  16. int main(int argc, char *argv[]){
  17.  
  18. if(geteuid() != 0) {
  19. fprintf(stderr,"\nTienes que ser root.\n");
  20. exit(ERROR);
  21. }
  22.  
  23.  
  24. if (argc < 2 ){
  25. printf("+==============================================+\n");
  26. printf("| Sniffer. Modo de uso: ./porsnif start        |");
  27. printf("\n| Se añadirán más opciones, menú provisional.  |\n");
  28. printf("+==============================================+\n");
  29. exit(1);
  30.  
  31. }
  32. int diff;
  33. char st[6]="start";
  34. diff = strcmp(st, argv[1]);
  35.  
  36.  
  37. if (diff==0){
  38.  
  39. int s,r;
  40.  
  41. struct iphdr *iphead;
  42. struct tcphdr *tcphead;
  43. struct icmphdr *icmphead;
  44. unsigned char *buff = (char*) calloc(65 * KB,sizeof(char));
  45.  
  46.  
  47.  
  48. if ((s = socket(AF_INET, SOCK_RAW, 6)) <0 ){
  49. printf ("Error al crear el socket!!!1111!11111!\nS: %d\n", s);
  50. exit (-1);
  51. }
  52.  
  53.  
  54.  
  55. iphead = (struct iphdr *)buff;
  56. printf("Esperando paquetes...\n");
  57. while(1){
  58. r = recv(s, buff, 64* KB, 0);
  59.  
  60. if(r > 0){
  61. switch(iphead->protocol) {
  62. case IPPROTO_ICMP:
  63. printf(">> ICMP, ip_src: %s ->",inet_ntoa(iphead->saddr));
  64. printf("\t ip_dst: %s\n", inet_ntoa(iphead->daddr));
  65. break;
  66. case IPPROTO_TCP:
  67.  
  68.  
  69.  
  70. tcphead=(struct tcphdr*)(buff+sizeof(struct iphdr));
  71. printf(">> TCP, src: %s :%d",inet_ntoa(iphead->saddr), ntohs(tcphead->source));
  72. printf("  ->\t dst: %s :%d\n", inet_ntoa(iphead->daddr), ntohs(tcphead->dest));
  73.  
  74.  
  75. break;
  76. default:
  77. fprintf (stderr,"Fixme: unsupported protocol\n");
  78. break;
  79. }
  80. memset(buff,0,64 * KB);
  81. tcphead = NULL;
  82. }else{
  83. fprintf(stderr,"recv(): %s\n",strerror(errno));
  84. }
  85. }
  86. return 0;
  87.  
  88.  
  89.  
  90. }
  91. else{
  92. printf("\nParámetros incorrectos. Escribe ./porsnif sólamente para ver la ayuda.\n");
  93.  
  94. }
  95.  
  96.  
  97. }
  98.  
  99. //Aún en desarrollo, se añadirán muchas más cosas.
  100.  
  101.  

Un saludo gente, muchas gracias a todos, seguiré añadiéndole más cosas al código y pondré aquí lo más interesante. Lo mismo si llego a controlar de sockets y eso, me curro un buen resumen en español de las cosas más importantes, pero eso será cuando lo domine xD.

Taluegoww
En línea

rodriguezjorge75

Desconectado Desconectado

Mensajes: 1


Ver Perfil
Re: Pequeño sniffer en C
« Respuesta #78 en: 20 Enero 2009, 20:01 »

muy bueno tu aporte. 

he bajado las librerias a las que haces mencion de
 http://www.die.net

pero no las consigo todas o me dan unos errores.

de donde sacas tu tus librerias ???
En línea

AlbertoBSD
💻🌎🌍🌏🌐 NWO📱
Colaborador
***
Desconectado Desconectado

Mensajes: 3.114


Libertad!!!!!


Ver Perfil WWW
Re: Pequeño sniffer en C
« Respuesta #79 en: 20 Enero 2009, 20:11 »

Hola que tal, los header vienen por defecto en el sistema, Me imagino que no te funcionan por que estas en windows.

Sinceramente ahí no se como funcione o se pueda portar este sistema, mmm, Bájate un CD-Live de linux y practica desde ahi.

Saludos.
En línea

Crackeame si puedes Wallet.dat
Páginas: 1 2 3 4 5 6 7 [8] 9 10 Ir Arriba Respuesta Imprimir 

Ir a:  
Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines