Recientemente he tenido que jugar con la libreria Scapy para Python. Ésta te permite crear cualquier tipo de paquete de red con un par de simples comandos, incluso para protocolos no existente mediante paquetes RAW.
En este caso pondre de ejemplo como solvente la necesidad de tener que enviar paquetes TCP a un puerto determinando usando cualquier combinación de flags TCP, cuyo objetivo era evaluar el comportamiento de la pila TCP al recibir cualquier combinación de flags.
Tenga en cuenta que no estamos hablando de permutaciones, puesto que es lo mismo enviar un paquete con el flags Syn y Ack que enviar un paquete con los flags Ack y Syn. Sí, seguramente habrán recordado la frase "el orden de los factores no altera el producto". Por tanto era necesario generar cualquier combinación teniendo en cuenta que el orden no afecta y que no se desea enviar más paquetes de los estrictamente necesarios.
Con está idea cogí un folio y lo rellene con un par de combinaciones para crear un algoritmo que resolviera el problema dando como resultado "algo", por concederle un nombre, bastante lento y que requería mucha lógica. Tenga en cuenta que no he considerado los flags de congestión y priorización del tráfico. El resultado fue el siguiente:
En este caso pondre de ejemplo como solvente la necesidad de tener que enviar paquetes TCP a un puerto determinando usando cualquier combinación de flags TCP, cuyo objetivo era evaluar el comportamiento de la pila TCP al recibir cualquier combinación de flags.
Tenga en cuenta que no estamos hablando de permutaciones, puesto que es lo mismo enviar un paquete con el flags Syn y Ack que enviar un paquete con los flags Ack y Syn. Sí, seguramente habrán recordado la frase "el orden de los factores no altera el producto". Por tanto era necesario generar cualquier combinación teniendo en cuenta que el orden no afecta y que no se desea enviar más paquetes de los estrictamente necesarios.
Con está idea cogí un folio y lo rellene con un par de combinaciones para crear un algoritmo que resolviera el problema dando como resultado "algo", por concederle un nombre, bastante lento y que requería mucha lógica. Tenga en cuenta que no he considerado los flags de congestión y priorización del tráfico. El resultado fue el siguiente:
#!/usr/bin/python # -*- encoding: utf-8 -*-
from scapy.all import * import sys
ip = str(sys.argv[1]) port = int(sys.argv[2])
flags = ['S','A','F','R','P'] send(IP(dst=ip)/TCP(dport=port, flags="")) for i in range(len(flags)): send(IP(dst=ip)/TCP(dport=port, flags=str(flags[i]))) vueltag = 2 #Bloque mayor while(len(flags) >= vueltag): vueltap = vueltag inib = 0 while (vueltap <= len(flags)): bloque = "" aux = inib cont = 0 while (cont < vueltag - 1): bloque = bloque + flags[aux] aux = aux + 1 cont = cont + 1 finb = inib + cont while(len(flags) > finb):
bandera = (bloque + flags[finb]) send(IP(dst=ip)/TCP(dport=port, flags=bandera)) finb = finb + 1 inib = inib + 1 vueltap = vueltap + 1 vueltag = vueltag + 1
Si desea ejecutar el programa, tenga en cuenta que debe indicar como primer argumento la IP del servidor a auditar y como segundo argumento debe indicar un puerto. Recuerde que debe disponer de Python y de Scapy en su máquina, las distribuciones como BackTrack los incluye por defecto. Por ejemplo para auditar el puerto 80 de la ip 127.0.0.1 usted debe introducir lo siguiente:
# ./programa.py 127.0.0.1 80
Al ejecutarlo contra el puerto 80 de mi máquina local, cuya IP local era 127.0.0.1, pude registrar con la herramienta de auditoría de red Tcpdump que se generaba correctamente el resultado esperado, tal como se muestra en la siguiente imagen:
Monitorización Tcpdump de la ejecución del programa |
Pero si se tiene en cuenta como funciona el protocolo TCP/IP y que Scapy permite introducir datos en crudo con valores hexadecimales o binarios, se podría resumir el código anterior con algo tan simple como lo siguiente:
#!/usr/bin/python # -*- encoding: utf-8 -*-
from scapy.all import * import sys
ip = str(sys.argv[1]) port = int(sys.argv[2])
num = 0b000000
while(num < 0b1000000): send(IP(dst=ip)/TCP(dport=port, flags=num)) num = num + 0b1
Donde si quisiera ampliar el algoritmo para que se comprobara los flags de congestión de tráfico únicamente deberia modificar la condición while por lo siguiente:
num = 0b00000000
while(num < 0b100000000): send(IP(dst=ip)/TCP(dport=port, flags=num)) num = num + 0b1
Como se aprecia, de forma sencilla podriamos crear un script en Python que permitiera auditar las pilas TCP/IP de muchos dispositivos, añadiendo otras opciones como:
- Enviar a puerto "0", valores de puertos con valor máximo o mismo puerto origen que destino.
- Versión TCP distinta a 4 y 6.
- Número de sesión y de acuse de recibo con valores idénticos, valores máximos o valor "0".
- Enviar múltiples paquetes con mismo valor de sesión pero ip origen distinta.
- Misma dirección IP origen que destino o IP reservadas como origen.
- Fragmentación simple y con superposición.
- Tamaño, campos de tamaño, checksum invalido o no múltiplo de 32 bits.
- Opciones extra TCP no validas.
Para finalizar le recomiendo que en caso que programe las opciones anteriores, tenga especial cuidado con lo que envía y con que velocidad lo hace, puesto que las centralitas telefónicas, entornos SCADA o impresoras suelen comportarse de forma distinta a lo esperado ante estos casos.
No hay comentarios:
Publicar un comentario