El principio SNIFF de olfatear

Debemos saber que en Ethernet todas las comunicaciones se transmiten, lo que significa que todas las interfaces de red (generalmente ubicadas en el mismo segmento de red) pueden acceder a todos los datos transmitidos en el medio físico, cada interfaz de red tiene un único Dirección de hardware, que es la dirección MAC de la tarjeta de red. La mayoría de los sistemas utilizan una dirección de 48 bits para representar cada dispositivo en la red. La mayoría de los sistemas utilizan una dirección de 48 bits para representar cada dispositivo en la red. En términos generales, cada NIC tiene una dirección MAC diferente y cada fabricante de NIC recibe un bloque de direcciones y luego usa esa dirección para asignar una dirección a cada NIC que produce. Los protocolos ARP y RARP se utilizan para traducir entre direcciones de hardware y direcciones IP.

En circunstancias normales, la interfaz de red solo debe responder a los siguientes dos tipos de tramas de datos:

1. Tramas de datos que coinciden con su propia dirección de hardware.

2. Transmitir tramas de datos enviadas a todas las máquinas.

En el sistema real, la tarjeta de red completa el envío y la recepción de datos. Después de que la tarjeta de red recibe los datos enviados, el programa del microcontrolador en la tarjeta de red recibirá la trama de datos de la MAC de destino. dirección Según la solicitud de la computadora para la tarjeta de red El modo de recepción establecido por el controlador determina si se debe recibir la recepción, es decir, se recibe cuando se recibe y se genera una señal de interrupción para notificar a la CPU cuando se recibe. recibido, es decir, se ignora si no se recibe, por lo que los datos recibidos por la tarjeta de red que no deberían recibirse se truncarán. La CPU genera una interrupción después de recibir la señal de interrupción. El sistema operativo llamará al controlador para recibir datos de acuerdo con la dirección del programa de interrupción de la tarjeta establecida por el controlador de la tarjeta. Una vez que el controlador reciba los datos, se colocará en la pila de señales. procesamiento por parte del sistema operativo. La NIC generalmente tiene cuatro modos de recepción:

Modo de transmisión: la NIC en este modo puede recibir información de transmisión desde la red. Modo de multidifusión: una NIC configurada en este modo puede recibir datos de multidifusión.

Modo directo: En este modo, solo la NIC de destino puede recibir estos datos. Modo mixto: En este modo, la NIC recibe todos los datos que pasan a través de ella, independientemente de si se le entregan o no.

Bien, ahora resumamos. En primer lugar, sabemos que Ethernet transmite datos en función de la transmisión, es decir, todas las señales físicas deben pasar a través de mi máquina. De manera similar, la tarjeta de red se puede colocar. en un modo llamado "promiscuo" (promiscuo), una tarjeta de red que funciona en este modo puede recibir todos los datos que pasan a través de ella, independientemente de si la dirección de destino real de los datos no es la suya. En realidad, este es el principio básico de cómo funciona SNIFF: la tarjeta de red recibe todos los datos que puede recibir.

Veamos un ejemplo simple, que se muestra en la Figura 1, donde las máquinas A, B y C están conectadas a un concentrador que accede a la red externa a través de un enrutador. Esta es una situación muy simple y común. Por ejemplo, en el edificio de una empresa, varias máquinas en la oficina del departamento de red donde estoy ubicado están conectadas a través de un concentrador. Lo mismo ocurre con el departamento de red, el departamento de desarrollo y el departamento de marketing. Los concentradores de varios departamentos están conectados a través de enrutadores. Volviendo a nuestra Figura 1, vale la pena señalar que las máquinas A, B y C están conectadas mediante HUB comunes, no SWITCH ni ROUTER. Usar SWITCH y ROUTER es mucho más complicado que esto.

Supongamos que el administrador de la máquina A utiliza el comando FTP para iniciar sesión de forma remota en la máquina C para mantener la máquina C. Primero, la contraseña FTP ingresada por el administrador en la máquina A para iniciar sesión en la máquina C debe pasar por el protocolo FTP en la capa de aplicación, el protocolo TCP en la capa de transporte, el protocolo IP en la capa de red y el controlador Ethernet en la capa de enlace de datos, y luego omitir capa tras capa, hasta llegar finalmente a la capa física, que es nuestro cable de red. A continuación, la trama de datos se envía al HUB, y el HUB transmite la trama de datos enviada por la máquina A a cada nodo. Después de que la máquina B reciba el marco de datos transmitido por HUB, verificará si la dirección en el marco de datos es consistente con su propia dirección. Si encuentra que la dirección del marco de datos no está en su propia dirección, descartará los datos. encuadre e ignórelo. La máquina C también recibe el marco de datos y lo analiza después de compararlo con su propio marco de datos.

En el ejemplo simple anterior, el administrador de la máquina B quisiera saber cuál es la contraseña FTP para iniciar sesión en la máquina C. Todo lo que tenía que hacer era configurar la NIC de su máquina en modo promiscuo y luego analizar los marcos de datos entrantes para encontrar la información de contraseña contenida en los marcos de datos.

Práctica de olfateo

En la sección anterior, hemos entendido los principios básicos de SNIFF. En esta sección, haremos el olfateo nosotros mismos. Después de todo, es más fácil profundizar la comprensión hablando con el código del programa que hablando con otras cosas.

Recordando los principios anteriores, debemos hacer lo siguiente:

1. Configurar la NIC en modo promiscuo. 2. Capturar paquetes. 3. Analice el paquete de datos.

Nota: El siguiente código fuente proviene del artículo Basic Packet-SnifferConstruction from the Ground Up de Chad Renfro

/****************** ****** *******Tcp_sniff_2.

c****** ****************/

1.#include

2.#include

3.#incluir

4.#incluir

5.#incluir

6.#incluir

7. p>

8.#include

9.#include headers.h

#define INTERFAZ eth0

/*Área de prototipo*/

1 0 int Open_Raw_Socket( void);

11 int Set_Promisc(char *interface,intsock);

12 int main() {

13int sock,bytes_recieved,fromlen;

14.char buffer[65535];

15.struct sockaddr_in from;

16.struct ip *ip;

17.struct tcp *tcp;

18.sock = Open_Raw_Socket();

19.set_Promisc(INTERFACE,sock);

20.mientras (1)

22.{fromlen = sizeof from;

24. bytes_recieved = recvfrom(sock, buffer,sizeofbuffer,0,(struct sockaddr *)&from,& fromlen);

25.printf(\nBytes recibidos :::%5d\n,bytes_recieved);

26. printf(Dirección de origen :::%s\n,inet_ntoa (from.sin_addr));

27. ip = (struct ip *)buffer;

/*Ver si se trata de un paquete TCP*/

28.if( ip->ip_protocol == 6) {

29. printf(Longitud del encabezado IP :::%d\n,ip->ip_length);

30. ::%d\n,ip->ip_protocol);

31.printf(Puerto de origen :::%d\n,ntohs(tcp->tcp_source_port));

33. printf(Puerto destino :::%d\n,ntohs(tcp->tcp_dest_port));

34.}

35.}

36.}

37 int Open_Raw_Socket () {

38. int calcetín;

39.if((calcetín = socket(AF_INET,SOCK_RAW, IPPROTO_TCP)) < 0){

/*entonces el socket no se creó correctamente y debe morir*/

40. perror(El socket sin formato no se creó);

<

p>41. salida(0);

42.};

43. retorno(calcetín);

44.}

45 int Set_Promisc(char *interfaz,int sock) {

46. struct ifreq ifr;

47. );

48. if ((ioctl(sock,SIOCGIFFLAGS,&ifr) == -1)) {

/*No se pueden recuperar los indicadores de la interfaz*/

49.perror(No se puede recuperar el indicador de la interfaz);

50.exit(0);

51.printf(La interfaz es: :: %s\n ,interfaz);

53. perror(banderas recuperadas exitosamente de la interfaz);

54.ifr.ifr_flags |= IFF_PROMISC;

55.ifr.ifr_flags |= IFF_PROMISC;

56.if (ioctl (sock,SIOCSIFFLAGS,&ifr) == -1 ) {

/*No se puede establecer la bandera en la interfaz*/

56 perror(No se pudo configurar el indicador PROMISC:);

57.exit(0);

58.}

59. printf(Configuración de interfaz ::: %s :: a promisc,interface);

60. return(0);

61.}

/******************************EOF********** ***** ********** *********/

El programa anterior tiene una descripción muy detallada, pero creo que es necesario decir algunas palabras primero. línea 10 - intOpen_Raw_Socket(void); es nuestra función de personalización, de la siguiente manera:

37 int Open_Raw _Socket() {

38.int sock;

39 if((sock = socket(AF_INET,SOCK_RAW ,IPPROTO_TCP)) < 0){

/*Entonces el socket no se creó correctamente y debe morir*/

40. (El socket sin formato no fue creado);

41. exit(0);

42.};

43. p>

44.}

Línea 39 if((sock = socket(AF_INET,SOCK_RAW,IPPROTO_TCP)) < 0) {

Aquí llamamos a la función socket para crear un socket sin formato para recibir paquetes TCP/IP.

La siguiente línea 11-int Set_Promisc(char *interface,intsock) también es nuestra función personalizada para poner la tarjeta de red en modo promiscuo, de la siguiente manera:

45 int Set_Promisc(char *interfaz, int calcetín) {

46. struct ifreq ifr;

47. strncpy(ifr.ifr_name,interfaz,strlen(interfaz)+1);

48. if((ioctl(sock,SIOCGIFFLAGS ,&ifr) == -1)) {

/*No se pudieron recuperar indicadores para la interfaz*/

49 . perror (No se pudieron recuperar los indicadores de la interfaz);

50. exit(0);

51.}

52. :: : %s\n,interface);

53.perror (obtuvo exitosamente la bandera de la interfaz).

54. ifr.ifr_flags |= IFF_PROMISC;

55. if (ioctl (calcetín, SIOCSIFFLAGS,&ifr) == -1 ) {

/*No se puede configurar el indicador en la interfaz*/

56 perror (No se puede configurar el indicador PROMISC:);

57.exit(0);

58. }

59. printf(Configuración de interfaz ::: %s :::: a promisc,interfaz);

retorno(0);

61.}

Primera estructura ifreq ifr; corrige una estructura ifrreg ifr, luego strncpy(ifr.ifr_name,interface,).strnlen(interface)+1);, que es para completar el nombre del estructura ifr del dispositivo de red, donde #define INTERFACE eth0, miremos más abajo, la solicitud ioctl(sock,SIOCGIFFLAGS,&ifr),SIOCGIFFLAGS indica que necesitamos obtener el indicador de interfaz, ahora en la línea 54, después de obtener con éxito el indicador de interfaz, configúrelo en modo promiscuo, ifr.ifr_flags|=IFF_PROMISC;ioctl(sock, SIOCSIFFLAGS,&ifr). Bien, ahora se ha completado el primer paso que mencionamos ----- --- Configure la tarjeta de red en modo promiscuo.

Ahora ingresa al segundo paso, capturar el paquete de datos. A partir de la línea 20, ingresamos un bucle infinito while(1), y luego en la línea 24 recvfrom(sock,buffer,sizeof buffer,0,(struct sockaddr *)&from,&fromlen), la función Todo lo que hace es recibir datos y colocar los datos recibidos en un búfer. Es así de simple y ya hace el trabajo que intentamos hacer para capturar los paquetes.

El tercer paso es analizar el paquete de datos.

Línea 27, ip = (struct ip*)buffer, por lo que encontramos los datos recibidos correspondientes a la estructura IP en el archivo de encabezado. El siguiente paso es determinar si se utiliza el protocolo TCP en la capa de red, si (ip->. ; ip_protocol == 6), si la respuesta es que la información en el paquete tcp proviene del buffer de todo el paquete IP/TCP + la dirección que comienza con (4*ip->ip_length), entonces línea 31 tcp = (struct tcp*)(buffer + (4*ip->ip_length)), y luego genere la información requerida en la estructura correspondiente.

/************************headers.h*************** *** ***********/

/* Estructura del encabezado ip*/

struct ip {

unsigned int ip_length:4 ; /*little-endian*/

unsigned int ip_version:4;

unsigned char ip_tos

unsigned short ip_total_ length

ip_id corto sin firmar;

ip_flags cortos sin firmar;

ip_ttl de caracteres sin firmar; ip_cksum;

unsigned int ip_source; unsigned int ip_dest;

};

/* Estructura del encabezado TCP*/

struct tcp {

tcp_source_port corto sin firmar;

tcp_dest_port corto sin firmar;

int tcp_seqno sin firmar;

int tcp_ackno sin firmar;

unsigned int tcp_res1:4,/*little-endian*/

tcp_hlen:4,

tcp_fin:1,

tcp_syn:1,

tcp_rst:1,

tcp_psh:1,

tcp_psh:1,

tcp_ack:1,

tcp_urg: 1,

tcp_res2:2;

tcp_winsize corto sin firmar;

tcp_cksum corto sin firmar;

tcp_urgent corto sin firmar;

p>

};

/************************EOF********** ****** **********************/

Del análisis anterior, podemos entender claramente que para identificar SNIFF, debemos entenderlo en detalle Protocolo TCP/IP, de lo contrario no se encontrará la información requerida. Con los conceptos básicos anteriores implementados, estás listo para crear tu propio SNIFF.

ghts Reserved.