Una vez, antes de defender otro trabajo de laboratorio, me hicieron una pregunta: ¿qué campos de un paquete IP pueden usarse para acolchado? No lo sabía y solo me encogí de hombros. Pero pronto todavía decidí estudiar este tema.
Debajo del corte, encontrará el estudio de los encabezados de paquetes IP, la propia utilidad de ping de Python y varias formas de transferir datos sin llamar la atención.
Contenido
- Estructura de paquetes IP
- Entorno
- Ping: opción fácil
- Ping: opción difícil
- Mejoras?
Estructura de paquetes IPv4

Seleccione los campos, cuyo cambio no afectará en gran medida el paquete:
El DIH puede variar de 5 a 15.
El campo
ToS se usa para priorizar las notificaciones de tráfico y congestión sin descartar paquetes. Muy a menudo, este campo es 0. Teóricamente, se puede usar para transmitir un byte completo de información.
La longitud del paquete es un campo excelente para transmitir números del 20 al 65535.
TTL puede transmitir hasta 7 bits de información. Necesita saber el número de saltos al host y tener esto en cuenta.
Entorno
Para repetir el experimento, necesitará dos máquinas con Python y el marco escaso.
Puede instalarlo siguiendo las
instrucciones de la documentación . En mi caso, se trataba de dos gotas en OD con la red local activada. Para probar la operabilidad del stegano, se eligieron dos rutas: a través de la red local para 1 salto y a través de Internet para 2 saltos.
Ping: opción fácil
Primero implementamos sender.py, que enviará paquetes ICMP sin mensajes ocultos.
from scapy.all import *
Scapy completará los campos restantes con los valores predeterminados antes del envío y calculará la suma de verificación.
En el lado receptor, escriba listener.py, que escuchará y mostrará todos los paquetes ICMP entrantes.
from scapy.all import *
Salida de escucha ###[ Ethernet ]### dst = hh:hh:hh:hh:hh:hh src = gg:gg:gg:gg:gg:gg type = 0x800 ###[ IP ]### version = 4 ihl = 5 tos = 0x0 len = 28 id = 24923 flags = frag = 0 ttl = 64 proto = icmp chksum = 0x4364 src = 10.0.0.1 dst = 10.0.0.2 \options \ ###[ ICMP ]### type = echo-request code = 0 chksum = 0xf7ff id = 0x0 seq = 0x0 ###[ Padding ]### load = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
El encabezado del paquete IP tiene un campo identificador. Llénalo con los símbolos "A" y "B":
payload = ord("A") * 0x100 + ord("B") pkt = IP(src="10.0.0.1", dst="10.0.0.2", id = payload) / ICMP(type = 8)
Además, en el encabezado ICMP hay exactamente el mismo campo en el que también se pueden cargar dos bytes.
Cambie el oyente para mostrar los datos recibidos:
from scapy.all import * import sys packets = sniff(filter="icmp", timeout = 10, count = 100, iface="eth0") for pkt in packets: if pkt[ICMP].type != 8: continue
En la imagen y semejanza, puede llenar casi cualquier campo que anteriormente se haya señalado como adecuado para acolchado.
Ping: opción difícil
La transferencia de datos del párrafo anterior no fue la más obvia, pero podemos hacerlo aún más obvio. Puede ocultar los datos en el campo para la suma de verificación. De acuerdo con
RFC1071, una suma de verificación es (¡de repente!) Una inversión bit a bit de una suma aritmética un poco más compleja.
Explicación con un ejemploSupongamos que tenemos un encabezado para el que queremos calcular la suma de verificación. En el momento del cálculo, el campo de suma de verificación se restablece.
4500 003c 000a 0000 8001 [checksum] c0a8 000d c0a8 000d
1. Sume todas las palabras de 16 bits, recordando la transferencia del orden superior:
4500 + 003c + 000a + 0000 + 8001 + [checksum=0000] + c0a8 + 000d + c0a8 + 000e = = (2) 46b2
2. Sume el resultado con transferencias:
46b2 + 2 = 46b4
3. Invertir:
~(46b4) = b94b
b94b es la suma de comprobación que estamos
buscando . Para la verificación, puede sustituir en el encabezado y realizar los pasos 1 y 2. Si obtiene FFFF, la cantidad encontrada es correcta.
Verificación:
1. 4500 + 003c + 000a + 0000 + 8001 + [checksum=b94b] + c0a8 + 000d + c0a8 + 000e = = (2) FFFD 2. FFFD + 2 = FFFF
Sabemos que la suma de verificación de un paquete cambia a medida que los nodos pasan a través de la red, a medida que cambia el TTL. Además, al pasar a través de NAT en el paquete, se reemplaza la "dirección de origen", lo que también afecta a la suma de comprobación. Y cuánto TTL disminuirá al llegar a nuestro oyente ... La guinda del pastel es que el bitness del "identificador" coincide con el bit de la suma de comprobación. Este hecho nos permite influir en la suma de verificación y cambiarla a cualquier valor del área de definición. Dado que la suma de comprobación (carga útil) se calculará solo cuando pase el último nodo en la ruta, es importante tener en cuenta todo lo que se puede cambiar en el paquete durante la ruta durante los cálculos.
El algoritmo para encontrar el "identificador", que nos dará la suma de comprobación deseada:
- Configuramos el paquete como cuando pasa por el último nodo (IP, TTL, etc.)
- En el "identificador" escriba la carga útil
- Calculamos la suma de control
- El resultado debe escribirse en el "identificador" del paquete enviado
Escribiremos una función que formará un paquete por la cantidad de esperanzas, IP detrás de NAT y dos bytes de carga útil.
Mejoras?
- Los campos chksum, seq, id en el encabezado del protocolo ICMP también se pueden usar para transmitir datos
- ToS puede usarse para identificar paquetes "propios" e ignorar la solicitud de eco de otras personas.