
Inyector de opciones DHCP
¿Alguna vez has querido interceptar peticiones DHCP e insertar algunas opciones DHCP adicionales, sin que el remitente lo sepa? Probablemente no. Sin embargo, si alguna vez surge la necesidad, dhcpoptinj (con suerte) te ayudará.
Puede haber muchas razones para modificar peticiones DHCP, aunque probablemente deberías buscar un método mucho mejor para resolver tu problema. Quizás no tienes acceso al servidor/clientes DHCP y necesitas modificar sus opciones DHCP, quizás el software DHCP es difícil de configurar (o no admite lo que quieres hacer), quizás tienes una configuración muy compleja o extraña, o quizás solo quieres experimentar enviando opciones exóticas o malformadas. Existe una pequeña posibilidad de que dhcpoptinj pueda ser de alguna utilidad.
dhcpoptinj espera a que los paquetes lleguen a una cola de netfilter. Se asegura de que un paquete sea realmente un paquete BOOTP/DHCP y, de ser así, procede a inyectar opciones. Recalcula la suma de comprobación del encabezado IPv4, deshabilita la suma de comprobación UDP (para una implementación más simple) y luego devuelve el paquete a netfilter.
Necesitas una regla de iptables para interceptar paquetes y enviarlos a dhcpoptinj. Supongamos que tienes dos interfaces puenteadas, eth0 y eth1. Supongamos que quieres interceptar todas las peticiones BOOTP que provienen de eth0 e inyectar la opción de información del agente de relay (82/0x52). Inventemos un payload tonto: una sub-opción de ID de circuito de agente con el valor "Fjas".
Añade una regla a la tabla mangle de iptables:sudo iptables -t mangle -A PREROUTING -m physdev --physdev-in eth0 -p udp --dport 67 -j NFQUEUE --queue-num 42.
Luego ejecuta dhcpoptinj (ejecutémoslo en primer plano con salida de depuración adicional): sudo dhcpoptinj -d -f -q 42 -o'52 01 04 46 6A 61 73'. Ten en cuenta que dhcpoptinj debe ser ejecutado por un usuario con la capacidad CAP_NET_ADMIN. No es necesario, y realmente no deberías ejecutar dhcpoptinj como root. En su lugar, puedes, por ejemplo, otorgar la capacidad CAP_NET_ADMIN al binario (usando setcap) y limitar los derechos de ejecución solo a un usuario o grupo específico. Este es un método utilizado para ejecutar wireshark como no root, por lo que encontrarás varias guías que te ayudarán a lograrlo.
Ahora envía un paquete DHCP a la interfaz eth0 y observa cómo (usando una herramienta como wireshark) ha sido modificado cuando llega a la interfaz puenteada. Debería tener la opción inyectada al final de la lista de opciones. Si capturas el paquete DHCP entrante con Wireshark, aparecerá sin modificar aunque en realidad esté modificado.
Observa el formato del argumento para la opción -o: Debe ser una cadena hexadecimal que comience con el código de opción DHCP seguido del payload de la opción. La longitud de la opción (el byte que normalmente sigue al código de opción) se calcula automáticamente y no debe especificarse. La cadena hexadecimal puede estar delimitada por caracteres no hexadecimales para facilitar la lectura. Todas las opciones deben tener un payload, excepto la opción especial de relleno (código 0).
El diseño de la opción sin sentido utilizada en este ejemplo (primero el diseño de opción DHCP, luego el diseño de sub-opción de la opción de información del agente de relay) es el siguiente:
| Código | Longitud | Datos |
|---|---|---|
| 52 | (auto) | 01 04 46 6A 61 73 ("Fjas") |
| Sub-opc. | Longitud | Datos |
|---|---|---|
| 01 | 4 | 46 6A 61 73 ("Fjas") |
Ten en cuenta que dhcpoptinj no se preocupa por lo que escribas en los payloads de las opciones, ni verifica si tu código de opción existe. Sin embargo, te prohíbe usar el código de opción 255 (la opción de fin de terminación). dhcpoptinj inserta esta opción como la última automáticamente.
dhcpoptinj -f -d -q42 -r -o'0C 66 6A 61 73 65 68 6F 73 74' -o'52 01 04 46 6A 61 73' -o 320A141E28
3 opción(es) DHCP para inyectar (con un total de 25 bytes): 12 (0x0C) (Nombre de host), 82 (0x52) (Información del agente de relay), 50 (0x32) (Solicitud de dirección)
Se eliminarán las opciones existentes
Inicializando cola de netfilter
Inicializando manejador de señales
Inicialización completada. Esperando paquetes para modificar en la cola 42
Recibidos 416 bytes
Inspeccionando paquete DHCP de 328 bytes de B6:40:FE:41:30:DC a 255.255.255.255:67
Modificando paquete
Opción encontrada 53 (0x35) (Tipo de mensaje DHCP) DHCPREQUEST (copiando)
Opción encontrada 54 (0x36) (ID del servidor DHCP) con payload de 4 bytes 0A 14 1E 01 (copiando)
Opción encontrada 50 (0x32) (Solicitud de dirección) con payload de 4 bytes 0A 14 1E 28 (eliminando)
Opción encontrada 12 (0x0C) (Nombre de host) con payload de 12 bytes 33 31 36 64 65 39 31 34 64 61 62 34 (eliminando)
Opción encontrada 55 (0x37) (Lista de parámetros) con payload de 13 bytes 01 1C 02 03 0F 06 77 0C 2C 2F 1A 79 2A (copiando)
Opción FIN encontrada (eliminando)
Inyectando opción 12 (0x0C) (Nombre de host) con payload de 9 bytes 66 6A 61 73 65 68 6F 73 74
Inyectando opción 82 (0x52) (Información del agente de relay) con payload de 6 bytes 01 04 46 6A 61 73
Inyectando opción 50 (0x32) (Solicitud de dirección) con payload de 4 bytes 0A 14 1E 28
Insertando opción FIN
Rellenando con 10 byte(s) para cumplir con el tamaño mínimo de payload BOOTP
Enviando paquete modificado
dhcpoptinj está en Debian/Ubuntu. El paquete deb está bajo control de fuentes en salsa. Se recomienda instalar dhcpoptinj desde el paquete deb en lugar del siguiente procedimiento de instalación manual, porque también incluye una página de manual, reglas de autocompletado de bash, archivos de ejemplo, etc.
Necesitas cmake y libnetfilter_queue (y un compilador de C que soporte C99). Con suerte, estás usando un sistema tipo Debian, en cuyo caso puedes ejecutar lo siguiente para instalarlos: sudo apt-get install cmake libnetfilter-queue-dev.
git clone git://github.com/misje/dhcpoptinjcd dhcpoptinjmkdir build && cd buildcmake .. (o cmake -DCMAKE_BUILD_TYPE=Debug .. si quieres una compilación de depuración)make -j4sudo make installsudo make uninstall desde tu directorio de compilaciónEl directorio de compilación con todo su contenido se puede eliminar de forma segura. Si no usaste un directorio de compilación, puedes deshacerte de todos los residuos de cmake ejecutando git clean -dfx. Ten en cuenta, sin embargo, que esto elimina todo en el directorio del proyecto que no esté bajo control de versiones.
dhcptopinj intentará analizar /etc/dhcpoptinj.conf o el archivo pasado con -c/--conf-file. La sintaxis del archivo de configuración es
Los espacios en blanco son opcionales. Todo lo que esté después e incluya el carácter # se considera un comentario. Las opciones DHCP se listan una por una como opcion=01:02:03. Las comillas alrededor de la cadena hexadecimal de la opción son opcionales, y los bytes pueden estar separados por cualquier número de caracteres no hexadecimales.
Las opciones version, help y conf-file no se aceptan en un archivo de configuración.
Ejemplo:
# Ejecutar en primer plano:
foreground
# Habilitar salida de depuración:
debug
# Sobrescribir nombre de host a "fjasehost":
option = '0C 66 6A 61 73 65 68 6F 73 74'
# Enviar ID de agente "Fjas":
option = "52:01:04:46:6A:61:73"
# Sobrescribir solicitud de dirección para pedir 10.20.30.40:
option=320A141E28
# Usar cola 12:
queue = 12
remove-existing-opt # Eliminar opciones antes de insertar
Este readme debería haberte ayudado a empezar. También consulta la página de manual (en el paquete deb) y la salida de ayuda (dhcpoptinj -h), que debería cubrir todo lo que la utilidad tiene para ofrecer.
Para errores y sugerencias, por favor crea un issue.
dhcpoptinj es simple y esperemos que se mantenga así. No obstante, las siguientes son características faltantes que con suerte se añadirán algún día:
Error al vincular el manejador de cola a AF_INET: Operación no permitida
Lo más probable es que no tengas la capacidad CAP_NET_ADMIN o que haya otro proceso (quizás otra instancia de dhcpoptinj?) vinculado al mismo número de cola de netfilter.
Fuga de memoria en salida no normal.
Esto no se considera una fuga. Sin embargo, no debería haber fuga de memoria en una salida normal (capturando SIGTERM, SIGINT o SIGHUP).
Al crear reglas de iptables para usar con dhcpoptinj, las siguientes opciones pueden ser útiles:
--queue-bypass
No descartar paquetes, sino dejarlos pasar si dhcpoptinj no está en ejecución (o no está escuchando en el número de cola correcto).
Si tienes alguna sugerencia, por favor deja un issue y te responderé. Eres bienvenido a contribuir y las solicitudes de extracción (pull requests) son muy apreciadas.
Si encuentras dhcpoptinj útil, me encantaría saber para qué lo estás usando. Actualiza la página wiki y describe tu uso.
He elegido usar GPL para este proyecto. Si eso no te conviene, contáctame y podemos acordar una licencia diferente.