Información blog

Linux, tutoriales, noticias, sistemas, redes y seguridad informática, entre otras cosas.

lunes, 22 de mayo de 2017

DNSspoof; qué es y cómo reconocerlo

Existen hoy en día miles de forma de que la seguridad de uno se pueda ver afectada. Desde el reciente escándalo de WannaCry a ataques simples, pero efectivos que si bien son populares y conocidos, siguen siendo efectivos. Existen muchos, pero hoy me centraré en uno de ellos bastante interesante, tanto por su sutileza como por las formas en las que uno puede reconocerlo: El DNS Spoofing.

DNS_spoofing

Lo primero de todo que uno se puede preguntar es: ¿Qué es dicho concepto? ¿En qué consiste? Primero de todo hay que tener claro que la función del DNS (Domain Name Service) es la conversión de un nombre de dominio (el nombre de una web, por ejemplo) a una dirección de IP; por defecto toda comunicación entre equipos se realiza vía IP, pero debido a que recordar éstas es muy difícil para un humano, los DNSs hacen que solamente tengamos que recordar nombres; encargándose éste de la traducción. Es decir que lo que haríamos sería preguntar al DNS qué IP tiene el nombre de dominio al que queremos acceder, ya sea Facebook, Google, este blog o cualquier página a la que queramos acceder. Para tener más claro este concepto he aquí el siguiente esquema, que resume el funcionamiento de forma muy simplificada:

Diagrama_DNS
Diagrama DNS

La cuestión está que estas peticiones pueden ser interceptadas y ser redirigidas a otro lugar con el fin de engañar al usuario... Es decir que el DNS puede ser suplantado o spoofeado para que a la hora de decirle al equipo la IP del nombre de dominio, en vez de darle la IP correspondiente le de una falsa para que el equipo acceda a ésta. El pequeño esquema simplificado de a continuación puede ayudar a aclarar este punto:

diagrama_dns_spoof
Diagrama DNS spoofing

Esta suplantación puede parecer complicada, pero desgraciadamente no lo es tanto; solamente requiere de las herramientas adecuadas... La prueba de concepto de a continuación se ha realizado con un equipo Debian como atacante/suplantador, pero puede hacerse con cualquier otra distribución de Linux. Imaginemos que tenemos un equipo de sobremesa normal y corriente (no importa el S.O que esté usando) y otro equipo con Debian instalado... ¿Cómo puedo hacer con Debian para que el otro equipo acceda a una IP bajo mi control cuando quiera acceder a una página web conocida (Facebook, Twitter, Google...)?  Las IPs que usaré a modo de prueba serán la 192.168.1.1 (router), 192.168.1.2 (equipo que queremos que se dirija a otro DNS) y la 192.168.1.3 (equipo atacante).

Lo primero que hay que tener instalado en Debian sería el paquete dsniff, que incluye un conjunto de herramientas que incluye una serie de utilidades de pentesting, entre otras, estarían utilidades para ataques de Man in the middle y DNS spoofing. Esto es tan sencillo como hacer:

apt-get install dsniff

Con las herramientas en nuestro poder, el primer paso para suplantar el DNS sería el realizar un ataque de man in the middle entre el equipo victima (192.168.1.2) y el router (192.168.1.1) para así manipular más adelante el tráfico entre ambos. Hay varios tipos de ataques (para más detalles podéis acceder al link anterior) pero el que usaremos en esta ocasión será el arp spoffing, el cual consiste de únicamente 3 comandos:

El primer comando para realizar el ataque con éxito, sería la activación de reenvío de paquetes en la máquina atacante para que así al lograr realizar el ataque con éxito, no se corte la comunicación:

echo 1 > /proc/sys/net/ipv4/ip_forward

Ahora pasaríamos a realizar un envenenamiento de la tabla ARP tanto del router como del equipo, lo cual obedece a la sintaxis:

arpspoff -i interfaz_red -t equipo1 equipo2
arpspoff -i interfaz_red -t equipo2 equipo1

Lo que si lo aplicamos a este caso en concreto sería:

  1. arpspoff -i eth0 -t 192.168.1.2 192.168.1.1
  2. arpspoff -i eth0 -t 192.168.1.1 192.168.1.2

Con el ataque de man in the middle realizado, ahora tocaría tener claro qué nombre de dominio queremos suplantar y a qué IP lo queremos dirigir... Por ejemplo podemos decirle a la victima que cuando pida la IP del nombre de dominio facebook, la IP no sea la de facebook sino la del equipo atacante... Para ello, antes de nada vamos a crear un fichero llamado, por ejemplo, dominio_falso.txt con el siguiente contenido:

192.168.1.3  facebook.es

Este txt estaría diciendo que la IP de facebook.es sería la 192.168.1.3, es decir la IP del equipo atacante; ahora obviamente habría que hacerle creer a la victima que en efecto el nombre de dominio hace referencia a dicha IP.

dnsspoof -i eth0 -f dominio_falso.txt

Esto haría que toda petición realizada al nombre de dominio facebook.es, será redirigida a la IP falsa, IP que sería en este caso la del atacante. Este atacante tendría que tener un servidor web levantado con una apariencia similar al nombre de dominio original, cosa que se podría conseguir con herramientas especializadas tales como SET (Social Engineering toolkit), pero el objetivo de este post no es enseñar cómo hacer que la apariencia del sitio web falseado sea lo más "realista" posible, sino demostrar la relativa facilidad con la que se ha podido interceptar la petición DNS, con lo que no ahondaremos en dicho tema...

Obviamente lo suyo sería que el ataque hubiese sido bloqueado por herramientas de análisis de red o por diferentes políticas de seguridad pero... ¿Cómo podemos saber que el sitio web al que hemos accedido es el autentico? Hay diferentes cosas que se pueden tener en cuenta:

  • Ping: Al hacer ping al sitio web, veríamos que la IP no corresponde a una de las IPs pertenecientes a la web; es más para este ataque estaríamos viendo que al hacer ping a facebook estaríamos viendo que se está haciendo ping a una IP de clase C, usada para redes locales, cosa que no tiene sentido en una web pública.
  • Certificado: Los portales de login del 99% de los sitios web usan certificados SSL para securizar la conexión; si vemos una pantalla de login sin certificado alguno (es decir, si vemos que la web es HTTP y no HTTPS), habría que salir de allí de inmediato. Algunos ataques de DNSspoof usan certificados SSL hechos por ellos mismos, pero son certificados no validados por entidades certificadoras con lo que el navegador diría que la web estaría usando un certificado cuya veracidad no esté asegurada.
  • Analizador de red: Si usamos un analizador de red, podemos ver que habrá una brutal cantidad de paquetes arp fluyendo en nuestra interfaz de red, pues los ARP spoofing son muy agresivos y veremos, que no solo hay muchas ARP requests y replies ¡Si no que veremos que la MAC del atacante está duplicada y que pertenecerá a su propio equipo y al router!
  • ARP: Si consultamos nuestra tabla ARP con arp -n (Linux) o arp -a (Windows) veremos que habrá una MAC que pertenecerá a dos IPs distintas, lo cual será indicativo de haber sufrido un Man In The Middle.
  • DNSSEC: En caso de tener un DNS propio que esté protegido por DNSSEC, podemos verificar que nuestro DNS es efectivamente el que tiene que ser mediante el comando: dig DNSKEY nombre_dominio +multiline

Como veis existen diferentes recursos para comprobar la veracidad del sitio al que queremos acceder; desafortunadamente la mayoría de ellos requieren ser algo paranoico y que se realicen varias comprobaciones antes de entrar a un sitio, si bien eso no significa que dichas comprobaciones no sean recomendables, ya sea para este tipo de ataques u otros.

Espero que os haya resultado útil.

Saludos.

miércoles, 10 de mayo de 2017

Cómo manipular el rendimiento de la CPU en Linux

El rendimiento de la CPU es algo que, dependiendo de la situación, puede resultar de vital importancia... A veces necesitamos que ésta actué de una forma distinta a la habitual y queremos sacarle el máximo partido para que se adapte a nuestras necesidades de la mejor forma posible... En el último artículo he hablado sobre la priorización y reserva de núcleos del procesador, cosa que nos puede resultar útil para sacarle el máximo partido, pero en este caso voy a hacer referencia a otro punto... A la manipulación frecuencia de las CPU dentro de Sistemas GNU/Linux.

CPU_Portada

La CPU puede trabajar a mayor o menor rendimiento si bien dependiendo la configuración que tengamos implantada en el equipo podemos tener una CPU a la que no estemos sacando partido, una CPU que está trabajando siempre a pleno rendimiento sin necesidad o una CPU cuya frecuencia varíe dependiendo del uso de la "demanda" del sistema. Cada una tiene sus ventajas y desventajas... A veces nos interesa tener la CPU trabajando siempre al mínimo, ya que puede ser que estemos usando un portátil y queramos que el consumo de batería sea bajo, además de que el tener la CPU en  un sistema de refrigeración "pobre" como el de un portátil (por ejemplo) hace que uno tema sobre-calentarla.

Todo esto es posible en cualquier sistema Linux, si bien dependiendo de las características del equipo que estemos manipulando, podremos hacer una serie de modificaciones u otras. Para poder hacer estas modificaciones tendremos que tener instalado el paquete cpufrequtils, el cual puede ser instalado desde los repositorios tal que así:

apt-get install cpufrequtils

Con este paquete y sus correspondientes dependencias instaladas, podríamos pasar a la manipulación de la CPU, cosa que no depende de comandos, sino del propio sistema, ya que los ficheros encargados de las tareas de la CPU estarían en: /sys/devices/system/cpu/cpuX/cpufreq/. Allá donde X haría referencia del número de núcleo que queremos modificar, pues esta modificación debe de ser hecha núcleo por núcleo... Si tuviese un sólo núcleo tendríamos solo cpu0, si tuviésemos dos cpu0 y cpu1 y así sucesivamente...

En este directorio veremos varios ficheros, de los cuales hay dos en especial que nos interesarían: scaling_governorscaling_available_governors.

El primer fichero contendría el comportamiento actual del procesador, mientras que el segundo mostraría todos los comportamientos disponibles para el susodicho... Aquí, tal y como he comentado antes, podemos encontrar diferentes opciones dependiendo de nuestro equipo, pero... ?Qué opciones tenemos y qué significa cada una de éstas? He aquí una explicación de cada comportamiento:


  • performance: Con esta opción lo que haríamos sería que el equipo trabajase con la CPU siempre con la frecuencia máxima. Esto no es demasiado recomendable a menos que se tenga un equipo alimentado a la corriente eléctrica y que tenga un buen sistema de refrigeración.
  • powersafe: Esta opción suele estar puesta por defecto en el scaling_governor de los portátiles, ya que tiene como objetivo que la CPU tenga la menor frecuencia posible y así consuma la menor batería posible al mismo tiempo que el equipo tendría menor riesgo de sobrecalentamiento.
  • ondemand: Sube o baja la frecuencia de la CPU dependiendo del uso de ésta... A mayor el uso de procesador, mayor la frecuencia y viceversa. Es la opción más popular y fiable de todas.
  • conservative: Actúa igual que Ondemand, con la diferencia de que este último realiza el cambio de frecuencia de forma paulatina, mientras que el anterior realiza el cambio de golpe.
  • userspace: Permite que un usuario con privilegios (como root) manipule a mano la frecuencia de la CPU... Esta opción no es demasiado fiable ya que da pie a que alguien introduzca un valor erróneo o un valor que empeore el rendimiento global del sistema.

Para cambiar el comportamiento de la CPU, solamente habría que introducir uno de los mencionados arriba en el fichero scaling_governor. Por ejemplo, si deseásemos que la CPU siempre trabajase al máximo y dicha opción apareciese en scaling_available_governors, ejecutaríamos el siguiente comando como root:

for i in /sys/devices/system/cpu/cpu[0-$(cat /proc/cpuinfo |grep 'processor' |wc -l)]/cpufreq; do echo 'performance' > $i/scaling_governor; done

Con este comando haríamos el cambio en todos los núcleos al mismo tiempo en vez de ir uno por uno realizando el cambio con el riesgo de dejarnos alguno por el camino. El problema que tiene el realizar el cambio de dicha forma es que en caso de reiniciar el equipo, los cambios realizados se perderían, cosa que generalmente no desearemos... Para evitar dicho problema, tendremos que hacer dicho cambio persistente, lo cual afortunadamente es muy sencillo, pues simplemente habría que crear un fichero llamado cpufrequtils dentro del directorio /etc/default y he introducir allí el valor GOVERNOR="comportamiento_deseado"; por ejemplo podríamos hacer:

  1. touch /etc/default/cpufrequtils
  2. echo 'GOVERNOR="ondemand"' > /etc/default/cpufrequtils

Gracias a esto, el comportamiento de la CPU sería el especificado por dicho fichero.

Si queremos saber exactamente a qué frecuencia estaría actualmente trabajando la CPU tendríamos que revisar el fichero cpuinfo_cur_freq dentro del mismo directorio que los dos ficheros anteriores, es decir en: /sys/devices/system/cpu/cpuX/cpufreq/. Dicho fichero mostraría la frecuencia en la que está trabajando el núcleo en MHZ, y se podrían consultar los ficheros correspondientes a todos los núcleos con el comando:

for i in /sys/devices/system/cpu/cpu[0-$(cat /proc/cpuinfo |grep 'processor' |wc -l)]/cpufreq; cat $i/cpuinfo_cur_freq; done

Si modificáis el valor de scaling_governor y luego consultáis el fichero cpu_cur_freq, veréis que su valor varía dependiendo del comportamiento introducido en el primer fichero, con lo que con cada modificación que se haga, uno se puede hacer una idea de a qué frecuencia se trabaja dependiendo del comportamiento seleccionado.

Como veis, la manipulación de la frecuencia de la CPU no es tan complicada como parece, simplemente hay que conocer los diferentes comportamientos y decidir cual de ellos se ajusta mejor a nuestras necesidades.

Espero que os haya resultado útil.

Saludos.

lunes, 24 de abril de 2017

Asignación de programas a un núcleo con taskset

En el día de hoy, es prácticamente imposible no pensar en la existencia de CPUs con múltiples núcleos. Es más, hoy en día un ordenador potente suele llevar múltiples procesadores que tienen múltiples núcleos. A mayor la el número de éstos, mayor la cantidad de tareas simultáneas que pueden ser realizadas por el equipo sin que éste se sienta "forzado", lo cual dependiendo del tipo de uso que le queramos dar a nuestro equipo. En caso de no entender muy bien este concepto, recomiendo leer primero: controlando la salud del equipo con bash; pues aquí se explica detalladamente dicho concepto. Teniendo dicho punto claro, es obvio que si bien cuantos más núcleos tengamos, mejor; no siempre tendremos toda la potencia deseada, ya sea porque nuestro hardware no es potente o debido a que estamos ejecutando una gran cantidad de procesos que hacen que los procesadores estén trabajando a toda potencia.

procesador_portada

Si bien la cantidad de procesos es proporcional a la cantidad de tareas que le ordenemos realizar al equipo y dicho punto únicamente se puede corregir disminuyendo éstos o aumentando la cantidad de procesadores/núcleos (lo cual conllevaría generalmente a cambiar la placa base, con su correspondiente desembolso económico); lo que sí que podemos gestionar es qué tareas son gestionadas por qué núcleo. Haciendo que algunos estén más "holgados" que otros y que tengamos la seguridad de que, al menos ciertas tareas se puedan desenvolver con relativa rapidez. Esta tarea se logra gracias a la herramienta taskset; herramienta que, no solo nos permite saber en qué núcleo se está ejecutando una tarea en concreto, sino que también nos permite hacer que dicha tarea se ejecute en otro núcleo.

Lo primero y más importante que necesitamos conocer para situarnos y tener una noción de lo que estamos manejando, es la cantidad de procesadores/núcleos que tiene nuestro equipo, ya que dicha cantidad nos servirá de base para saber cómo gestionar los procesos. Dicha cantidad se puede conocer con este sencillo comando:

cat /proc/cpuinfo |grep processor |wc -l

El resultado obtenido sería el número de procesadores o núcleos que tiene el sistema, número que podemos usar como base para las futuras gestiones.

A sabiendas de dicho número, procederíamos a revisar qué procesos tenemos ahora mismo en ejecución; revisión que se realizaría mediante el conocido comando:

ps -e

De dicho comando obtendríamos el listado de procesos activos, procesos entre cuyos datos nos importarían dos en concreto, el nombre y el PID (Process ID); un pequeño fragmento de ejemplo de la salida de dicho comando sería este:

salida_ps_e
Fragmento de salida del comando ps -e

A sabiendas de estos datos, pasaríamos a conocer primero el núcleo en el que se está ejecutando el proceso que nos interesa, por ejemplo SSH. En este caso el PID del proceso SSH sería el 905 con lo que escribiríamos lo siguiente:

taskset -p 905

El cual en mi caso devuelve este resultado:

máscara de afinidad actual del pid 905: 1

Si os fijáis bien, lo que dice no es el número de núcleo (que empieza en 0) sino la máscara de afinidad; que si bien viene a decir lo mismo, lo expresa de diferente forma. La máscara de afinidad devuelve el núcleo que está usando en formato de máscara de bits hexadecimal, lo que significa que habría que convertir dicha máscara a binario para después ver qué núcleo está corriendo dicho proceso. En este caso se estaría usando el primer núcleo, es decir que estaría usando el núcleo con ID 0. En caso de no querer hacer la conversión, podéis consultar el ID directamente mediante el comando:

taskset -pc 905

Cuya salida sería:

lista de afinidad actual del pid 905: 0


Obviamente, con esta herramienta no solo podemos consultar el núcleo usado por el proceso, sino que también podemos modificarlo para hacer que tenga la posibilidad de usarlos todos (no implica que tenga que usar todos a la fuerza, sino que pueda usar todos en caso de ser necesario debido a una gran carga de trabajo) o para que únicamente use un núcleo en concreto. Para ello se usaría la sintaxis de a continuación:

tasket -pc Núcleos_a_usar PID

Por ejemplo, si deseásemos que el proceso SSH use únicamente los núcleo con ID 1 y 3, haríamos:

taskset -pc 1,3 905

Gracias a este simple comando, habremos cambiado le preferencia de los núcleos a usar por el proceso SSH con PID 905.


Por otro lado, taskset no solo nos permite modificar el núcleo usado por un proceso ya existente, sino que también nos permite lanzar un proceso nuevo forzándole qué núcleos usar. Por ejemplo ejecutar el programa apache2 únicamente haciendo uso del núcleo con ID 0 haríamos:

taskset -c 0 /etc/init.d/apache2 start


El problema de los métodos usados hasta ahora es que si bien son perfectamente válidos, no nos aseguran que el núcleo en cuestión esté reservado para la tarea que hemos especificado. Por ejemplo, podemos haber forzado a que un proceso use el núcleo con ID 0, pero ello no nos garantiza que el resto de procesos no esté usando dicho núcleo, a menos que claro está forcemos al resto de procesos a que usen otro núcleo, lo cual es muy poco práctico.

Afortunadamente podemos decir durante el proceso de arranque que nos reserve uno o varios núcleos; es decir que no sean usados dichos núcleos a menos que nosotros se lo digamos específicamente. Esto tiene la ventaja de que nos garantiza que dichos núcleos están libres para las tareas especiales, pero por otro lado tiene la desventaja de que esos núcleos dejarán de estar disponibles para el resto de tareas, haciendo que tal vez, en momentos de gran carga de trabajo para el equipo, notemos esa falta de "potencia". Aún así es una opción interesante que es importante conocer. Para aislar dichos procesadores, tendríamos que esperar en el arranque a que aparezca el GRUB; allí tendríamos pulsar la tecla E para editarlo. En dicha edición lo que nos interesa editar es la línea que finaliza con ro quiet; a la cual habría que añadirle al final el parámetro isocpus= ID_procesadores; por ejemplo:

isocpus=2,3

Finalmente para arrancar con este cambio tendríamos que pulsar F10 o ctrl + X, haciendo que cualquier proceso que se ejecute de manera "natural" nunca utilice los núcleos con ID 2 o 3, pues estos dos núcleos solamente serán usados en caso de que nosotros lo forcemos.

Como veis la herramienta taskset es muy versátil y puede ayudarnos a optimizar algunos procesos y reservar ciertos núcleos para las tareas de mayor relevancia, lo cual puede ayudarnos a tener la seguridad de que éstas serán ejecutadas sin inconveniente alguno.

Espero que os haya resultado útil.

Saludos.

martes, 21 de marzo de 2017

Cómo crear paquetes de red desde cero en Linux

Cuando estamos realizando alguna prueba de red; ya sea para testear un cortafuegos o para hacer alguna tarea de debugeo, a veces tenemos la necesidad de tener que realizar tareas muy concretas que una aplicación "convencional" no puede ofrecernos; pues podemos tener que necesitar usar un protocolo IP o puerto concreto que no es fácil de emular de forma convencional. Es por ello que a veces necesitamos tener que hilar muy fino y recurrir a aplicaciones que nos puedan permitir crear paquetes de red de forma precisa y personalizada. Aquí es donde entra en juego una aplicación que, si bien he de admitir que inicialmente no es muy intuitiva, nos ofrece un enorme control sobre los paquetes de red; ya sea para crearlos desde cero, como para editar unos existentes: Dicha herramienta, desarrollada en Python, se denomina Skapy y hoy quiero enseñaros como desenvolvernos con ella para, por lo menos, saber defendernos a la hora de tener que usarla.

Portada_crear_paquete_red

Scapy es una herramienta usada puramente en la consola pero a la que no hay que tenerle miedo, ya que si bien inicialmente tiene una cierta curva de aprendizaje, tras un par de pequeñas pruebas comprobareis que podréis realizar, al menos, las pruebas y operaciones más básicas. Se trata de una herramienta que no está instalada por defecto en ningún sistema Linux ni tampoco en en ningún repositorio oficial, con lo que tiene que ser bajada desde la página oficial de ésta. La forma más ágil de hacerlo, en mi opinión, es desde la consola, ya que es tan sencillo como escribir:

wget https://github.com/secdev/scapy/archive/v2.3.2.zip

Al ser una utilidad comprimida en formato, zip; sería necesario tener ésta utilidad instalada en el sistema, cosa muy sencilla ya que está incluida en los repositorios oficiales. Después, simplemente habría que descomprimir el archivo descargado mediante el comando unzip. Todo esto se traduce en dos simples acciones:

  1. apt-get install zip
  2. unzip v2.3.2.zip

Del fichero descomprimido obtendremos una carpeta llamada scapy-2.3.2 en la que tendríamos que entrar para poder ejecutar su binario, llamado run_scapy.

Ahora bien; antes de continuar hay que tener claro qué es lo que necesitamos para crear nuestro paquete. Todo paquete de red requiere (explicado de forma muy resumida) de dos elementos:

  • Una cabecera IP: La cabecera IP es un conjunto de reglas o campos que se usan para transmitir el paquete de un lugar a otro. En concreto son 13 campos: La versión IP, longitud del paquete, tipo de servicio, longitud total, identificador, flags (etiquetas), Offset, tiempo de vida, protocolo, checksum, IP origen, IP destino y opciones. A veces lleva también un campo extra usado para "rellenar" el paquete para que así tenga un tamaño que sea múltiplo de 32 bits. Si bien todos los parámetros son importantes, los que más nos interesan al usar Scapy son: La versión IP (IPv4 o IPv6), el protocolo, la IP de origen y la IP de destino. 

Composicion_cabecera_IP
Composición cabecera IP

  • Payload: El payload serían los datos que se quieren incluir dentro del paquete; datos que pueden ser de cualquier tipo; desde un texto plano a una imagen. Dicho mensaje no es siempre necesario, pues dependiendo de la prueba que queramos hacer tal vez no nos interese en absoluto el contenido del paquete, sino que simplemente éste llegue.

Teniendo esto claro, vamos a crear nuestro propio paquete. Con Scapy en ejecución, lo primero que haremos será crear el elemento más importante: la cabecera IP. Dicha creación puede parecer compleja, pero no es así: Una cabecera vacía (a modo de test) sería tal que así:

Nombre_variable=IP()

Por ejemplo:

CABECERA=IP()

Con esto Scapy ya habría creado la cabecera, cabecera que tendría una serie de parámetros asignados por defecto; muchos de los cuales nos sirven tal y como están. Para ver el contenido de nuestra cabecera, escribiremos:

CABECERA.show()

Cabecera_IP_vacia
Cabecera IP vacía

Si os fijáis bien, la mayoría de los campos están rellenados, y la mayoría, con los datos que se han introducido por defecto, serían datos válidos para una cabecera IP; a excepción de 3: proto, src y dst. Los cuales serían, protocolo, IP origen (src, o IP source) e IP de destino (dst, o IP destiny). Al protocolo le daremos un trato personalizado, tal y como veréis más adelante, pero los otros dos parámetros deben de ser introducidos. Para ello, haremos que la variable CABECERA, tenga dichos nuevos valores, tal que así:

CABECERA=IP(src='192.168.1.2',dst='192.168.1.3')

Es importante tener en cuenta que, si queremos editar en el futuro otros valores, tendremos que seguir manteniendo estos valores. Por ejemplo si deseásemos ahora que el campo flags, tuviese el valor 2; si hiciésemos esto:

CABECERA=IP(flags=2)

Sobrescribiríamos lo introducido anteriormente, ya que lo que estamos haciendo es asignar un valor a la variable CABECERA, con lo que para añadir dicho valor tendríamos que hacer:

CABECERA=IP(src='192.168.1.2',dst='192.168.1.3',flags=2)

Tenemos la cabecera casi formada, pero tal y como he comentado antes, el protocolo que ha asignado Scapy por defecto no es el correcto. Pero no valdría que le asignásemos un valor a dicho campo, ya que el protocolo es un campo que debe de ser tratado por separado debido a su relevancia. Podemos optar por uno de estos tres protocolos: ICMP, TCP y UDP. En mi caso optaré por UDP, pero se puede escoger cualquiera de ellos. Para crear un campo UDP, haríamos:

Nombre_variable=UDP()

En mi caso:

PROTOCOLO=UDP()

Ahora veremos el interior de dicho campo del mismo modo que hemos hecho con nuestra cabecera; es decir:

PROTOCOLO.show()

Protocolo_sin_datos
Protocolo_sin_datos

Tenemos el protocolo UDP "creado", pero el problema está en que no hemos dicho desde qué puerto vamos a enviar el paquete y a qué puerto queremos enviarlo. Para ello tendremos que seguir el procedimiento, de forma parecida a la anterior, y editar la variable PROTOCOLO para que sus valores sport (puerto origen) y dport (puerto destino) tengan unos valores determinados; lo cual haríamos de esta forma:

PROTOCOLO=UDP(sport=1024,dport=80)

Por último, vamos a crear un payload con algo de contenido a modo de prueba. La creación de payloads en sí no es sencillo, pero en este caso, al querer enviar un payload con un texto plano a modo de prueba, su complicación no es elevada. Para crear el payload tendremos que usar el mismo procedimiento que el que hemos hecho antes para el resto pero llamando a la "función" Raw. Función que solo tiene un campo llamado load, con lo que a diferencia de con los procesos anteriores en los que primero hemos creado la variable, luego la hemos consultado y por último hemos rellenado sus campos. Aquí directamente la crearemos con su campo rellenado:

PAYLOAD=Raw(load='Esto es una prueba ->UDP\n')

Ya tenemos todos los elementos creados, solamente habría que unificarlos para crear el paquete; para lo cual recurriremos a las variables que hemos creado. El paquete tendrá la estructura:

nombre_variable=Cabecera_IP/Protocolo/Payload

Para nuestro caso particular sería:

PAQUETE=CABECERA/PROTOCOLO/PAYLOAD

Para ver cómo ha quedado nuestro paquete escribiremos PAQUETE.show(), que mostrará la unión de todo lo que hemos creado hasta ahora:

Paquete_scapy
Paquete Scapy

Ya tenemos todo listo; ahora solamente tendremos que enviarlo mediante el comando send:

send(PAQUETE)

Lo ideal sería tener algo que nos permita detectar en tiempo real si el paquete ha sido enviado con éxito. Esto se puede lograr de dos formas. La primera es usando un analizador de red como tcpdump o Wireshark, ya sea en este equipo o en el receptor del paquete. La segunda sería usando netcat en el receptor para "escuchar" en el puerto 80 y ver qué es lo que nos llega. Lo más normal sería optar por la primera opción; con lo que si hiciésemos una captura y la abriésemos, veríamos que efectivamente nuestro paquete ha sido enviado con éxito.

Captura_Wireshark
Captura de red leída con Wireshark

Como podéis ver la creación de un paquete de red con Scapy, no es tan complicado como parece; solamente requiere tener cierto cuidado durante su "elaboración", pero gracias a la flexibilidad otorgada por esta utilidad podremos enviar paquetes de red creados de forma completamente "artesanal" cuya creación hemos controlado de principio a fin.

Espero que os haya resultado útil.

Saludos.