Archive

Archive for the ‘Red’ Category

MiTM Replace / Jugando entre capas

October 24th, 2012 No comments

En este post me gustaría presentaros una herramienta y dar algunos ejemplos para jugar un poco con los protocolos Ethernet y TCP/IPv4 (en adelante TCP), en concreto para hacer Ethernet Forwarding y modificar el payload de los segmentos TCP.

La herramienta en cuestión está disponible en https://github.com/sch3m4/mitmreplace.

Nota: De aquí en adelante supondremos que estamos trabajando sobre redes Ethernet.

Como es sabido, la tarea más básica de cualquier router que se precie, es el de interconectar distintas redes. Esta tarea se lleva a cabo (simplificando) cambiando la cabecera Ethernet (origen y destino) así como la cabecera IP, guardándo las “equivalencias” en una tabla en la memoria del dispositivo.

De manera casi similar funcionan los puentes de red, cuya tarea seŕia la de unir varias redes en una, pero sin realizar los cambios de ambas cabeceras (lo que sí hace un router).
La herramienta en cuestión realiza un “mix” entre estos dos modos de funcionamiento, actúa como un puente de red entre una o más redes, ofreciendo la posibilidad de manipular el payload de los segmentos TCP.

Q: ¿Un puente sobre una única red?
A: Sí, dependiendo de los entornos que veremos a continuación trabajaremos sobre una red o sobre dos.

La idea para poder realizar esto, es lanzar la herramienta sobre una red en la que controlemos el tráfico, ¿cómo lo conseguimos? Pues entre otras opciones, tenemos el envenenamiento ARP y montar un punto de acceso falso. Por ello, si hacemos envenenamiento ARP trabajaremos sobre una única red, y si optamos por montar el punto de acceso trabajaremos con dos redes.

Veamos una imagen para ver más claro cómo funciona la herramienta en cada uno de estos entornos:

Nota: Las siguiente imagen no se corresponde con una arquitectura de red real, solo pretende mostrar el flujo de datos.

En esta figura se puede ver el flujo de datos entre los PCs 4 y 5 siendo víctimas de un envenenamiento ARP por el PC 3, por lo que estos tres equipos están en el mismo segmento de red y solo disponen de una interfaz de red.

Es importante cuando ejecutemos la herramienta, desactivar el IP Forwarding en el sistema, ya que será la propia herramienta quien realice esta tarea. Otro detalle importante es que la herramienta no realiza NAT, por lo que debemos estar preparados para enrutar el tráfico sobre las IPs que a priori desconozcamos.

Si por el contrario hemos montado un punto de acceso (siendo nosotros el PC-3) tendremos dos interfaces, una interface por la que enrutar el tráfico de los clientes (modificado o no) y otra interface (Wireless) donde se conectarán los clientes.

Dicho esto, vamos a comenzar con algunos ejemplos sobre la herramienta en cada uno de estos entornos.

Lo primero como siempre, es descargarnos la herramienta:

$ git clone git://github.com/sch3m4/mitmreplace.git
Cloning into ‘mitmreplace’…
remote: Counting objects: 56, done.
remote: Compressing objects: 100% (43/43), done.
remote: Total 56 (delta 12), reused 55 (delta 11)
Receiving objects: 100% (56/56), 286.47 KiB | 117 KiB/s, done.
Resolving deltas: 100% (12/12), done.

A continuación entramos en el directorio y compilamos (necesitaremos las siguientes librerías: glib-2.0, xml2, pcap):

$ ./configure && make
checking for a BSD-compatible install… /usr/bin/install -c
(…)
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating config.h
config.status: config.h is unchanged
config.status: executing depfiles commands
(CDPATH=”${ZSH_VERSION+.}:” && cd . && /bin/bash /home/sch3m4/mitmreplace/missing –run autoheader)
rm -f stamp-h1
touch config.h.in
cd . && /bin/bash ./config.status config.h
config.status: creating config.h
config.status: config.h is unchanged
make  all-recursive
make[1]: se ingresa al directorio `/home/sch3m4/mitmreplace’
Making all in src
make[2]: se ingresa al directorio `/home/sch3m4/mitmreplace/src’
gcc  -g -O2   -o mitmreplace mitmreplace-checksum.o mitmreplace-forward.o mitmreplace-main.o mitmreplace-patterns.o mitmreplace-replace.o  -lglib-2.0 -lpcap -lxml2 -lpthread
make[2]: se sale del directorio `/home/sch3m4/mitmreplace/src’
make[2]: se ingresa al directorio `/home/sch3m4/mitmreplace’
make[2]: se sale del directorio `/home/sch3m4/mitmreplace’
make[1]: se sale del directorio `/home/sch3m4/mitmreplace’

Y tendremos la herramienta lista para ser ejecutada:

Su uso es bastante intuitivo, los parámetros “ingw” y “outgw” corresponden a las direcciones MAC de los gateways legítimos tanto de entrada como de salida, para que el equipo que recibe los datos modificados “crea” que provienen del dispositivo legítimo.

El objetivo en este caso va a ser un dispositivo Android que visitará http://safetybits.net Y lanzaremos la herramienta de manera que reemplazará todas las coincidencias de “libntoh” por “l33t.0f”, este es el contenido legítimo que el objetivo visualizaría:

Para llevar a cabo este “ataque” la herramienta dispone de un archivo donde introduciremos los datos que queremos reemplazar. Este archivo es un XML donde especificaremos la cadena a encontrar y la cadena por la que será reemplazada. Si una de estas dos cadenas deben ser tratadas como datos binarios, debe indicarse mediante un atributo que pondremos a “1″ o “0″ en función de si alguna de las cadenas deben ser tratadas como datos binarios respectivamente, en cuyo caso las representaremos en hexadecimal.

El archivo en cuestión tiene el siguiente formato, y para este ejemplo no necesitaremos modificarlo pues ya tiene los reemplazos que necesitamos:

Como se puede ver, reemplazaremos “Acept-Encoding: gzip” por “Accept-Encoding: text” para poder acceder a la respuesta en bruto (sin comprimir). El siguiente patrón es el que realmente cambiará el texto que necesitamos.

Por lo tanto (como se aprecia en la imagen), debemos crear una entrada en este archivo siguiendo el formato estipulado por cada reemplazo que queramos realizar.

Lo primero que vamos a realizar es un envenenamiento ARP de un cliente (192.168.1.45), haciendo uso de arpspoof:

Lo siguiente (no necesariamente en este orden) es desactivar el IP Forwarding, para ello usamos sysctl:

Con nuestro escenario preparado, solo necesitamos lanzar la herramienta indicándole la puerta de enlace legítima y la interfaz que vamos a utilizar:

A partir de ahora, será la herramienta quien realice el forwarding para mantener el acceso a la red del objetivo, y cada vez que encuentre un segmento TCP en el que exista alguna coincidencia con los datos especificados a través del fichero XML, lo sustituirá y enviará el segmento de vuelta a la red, causando el siguiente salida y efecto en el cliente:

Ha de quedar claro que la herramienta “no entiende” de protocolos de aplicación, el reemplazo solo se realiza en segmentos TCP, y como probáblemente más de uno se ha dado cuenta, las cadenas “libntoh” y “l33t.0f” tienen la misma longitud, ¿Por qué? La respuesta es bastante simple, si intentamos reemplazar “aabbcc” por “ABC” el resultado será “ABCbcc”. Esto es así, por la limitación del MSS, ya que de sobrepasarlo habría que enviar otro segmento TCP, y de cualquier modo, si modificamos la longitud del segmento, habría que ajustar el número de secuencia en dicho punto de la conexión, lo que desestabilizaría la conexión ya que no estamos haciendo de proxy a nivel TCP.

Con esto ya podemos “jugar” cambiando URLs de javascripts, imágenes, PDFs, binarios, “https://” por ” http://” (fíjate que hay un espacio ;-) ), etc.

libntoh @ GitHub

December 7th, 2011 No comments

Hace mucho tiempo que no escribo, y esta vez lo hago para presentar un proyecto personal que he decidido publicar.

Este proyecto es una librería escrita en C, que pretende agregar una capa más para determinadas aplicaciones de red, agregando las funcionalidades de desfragmentación de datagramas IPv4 y reensamblado de segmentos TCP.

El motivo que me ha llevado a escribir y publicar esta librería, es que las posibles opciones que se toman cuando se intentan realizar estas tareas son usar libnids o escribir una implementación propia. Esto no es problema para una sola aplicación, pero extrapolando el “problema” tenemos muchas implementaciones diferentes que realizan la misma tarea. En el caso de libnids, el primer problema viene con la licencia (GPL), otro problema viene con la concurrencia, otro inconveniente es la poca flexibilidad que ofrece (a costa de intentar dar usabilidad al usuario), ya que si usamos libnids obligatoriamente no podremos salirnos de las capas de enlace soportadas por la librería, no podremos gestionar las conexiones de manera individual, etc.

Por todo esto y algunos motivos más, me decidí a comenzar este proyecto. Aunque la versión actual (0.3a) es una “Alpha” se comporta bastante bien según las pruebas que he realizado, realizando correctamente  el reensamblado de segmentos TCP y la desfragmentación de datagramas IPv4.

Dado que es una versión “Alpha” puede que tenga fallos, así que si encuentras alguno o ves alguna incongruencia, ¡notifícala!.

URL: [email protected] [email protected]

Categories: C/C++, libntoh, Programacion, Proyectos, Red, UNIX Tags:

Sniffing en Remoto

May 4th, 2011 No comments

En más de una ocasión me he encontrado en la necesidad de realizar una captura de red de un equipo remoto en tiempo real y analizarla con varias herramientas, pero se plantean varios “problemas” a la hora de realizarlo.

Uno de los problemas es que necesitaríamos tener instaladas en el servidor todas las herramientas de análisis que necesitemos. Esto en algunos casos no es posible (herramientas con GUI), además de no ser muy seguro tener todas las herramientas instaladas en el servidor. Una opción es realizar una captura con tcpdump durante X tiempo y luego volcarla a la estación de trabajo, pero el no poder analizar la captura “on-the-fly” o el hecho de que la actividad sospechosa no se realizase justo cuando estamos capturando los datos (¿qué pasa si te la cuelan entre captura y captura?) es algo que me preocupa, y sí, el servidor ya cuenta con NIDS y HIDS pero el problema se plantea cuando necesitamos una captura de red completa.

Para ello lo que vamos a hacer es lo siguiente:

  • Crear un usuario en el servidor, que pueda ejecutar tcpdump con permisos de root sin password
  • Autorizar el login de dicho usuario por SSH en el servidor mediante claves DSA permitiendo únicamente ejecutar el binario ‘sudo
  • Crear una cola FIFO donde volcar la captura remota

Hecho esto, la FIFO contendrá la captura del servidor remoto, con lo que podremos usarla como origen de captura en la estación de trabajo.

El servidor es una Debian GNU/Linux y la estación de trabajo es FreeBSD 8.2.

Creando el usuario en el servidor:

[email protected]:~$ sudo useradd -m -N -s /bin/bash sniffer
[email protected]:~$ sudo passwd sniffer
sudo passwd sniffer
Introduzca la nueva contraseña de UNIX:
Vuelva a escribir la nueva contraseña de UNIX:
passwd: contraseña actualizada correctamente

Parámetros:

  • -m Crea el directorio de conexion si no existe
  • -N No crea el grupo del usuario
  • -s Shell por defecto del usuario
  • sniffer Usuario

La password es opcional, dependiendo si el servidor SSH permite logins con contraseñas vacías. Hecho esto ejecutamos la siguiente orden para permitirle ejecutar tcpdump como root sin pedir la contraseña:

[email protected]:~$ sudo echo "sniffer ALL= NOPASSWD: `which tcpdump`" >> /etc/sudoers

Autorizar login SSH sin password:

Ahora lo que haremos será generar una clave DSA en la estación de trabajo, en caso de que ya la tengas generada, puedes saltarte esta parte.

[[email protected] ~]$ ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/home/sch3m4/.ssh/id_dsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/sch3m4/.ssh/id_dsa.
Your public key has been saved in /home/sch3m4/.ssh/id_dsa.pub.
The key fingerprint is:
78:d2:ed:e7:33:8f:d8:5c:78:b6:2b:21:1d:9c:c0:a6 [email protected]
The key's randomart image is:
+--[ DSA 1024]----+
|         .       |
|          +      |
|         o o .   |
|       oE.  +    |
|      o S .. .   |
|       o .. o.   |
|          ..o.+  |
|           *+= . |
|          . ==+. |
+-----------------+
[[email protected] ~]$

Ahora camos a copiar la clave pública que hemos generado (~/.ssh/id_dsa.pub) al directorio de trabajo del usuario “sniffer” en el servidor, crear la carpeta “.ssh” y volcar la clave pública al fichero “.ssh/authorized_keys” y darle los permisos adecuados. Dependiendo de la configuración que tengamos en el servidor SSH tendremos que agregar el usuario “sniffer” en la linea “AllowUsers“  del fichero de configuración de SSH (/etc/sshd/sshd_config).

[[email protected] ~]$ scp -C .ssh/id_dsa.pub [email protected]:~/
[email protected]'s password:
id_dsa.pub         100%  616     0.6KB/s   00:00   
[[email protected] ~]$

Ahora nos conectamos por SSH al servidor, con el usuario “sniffer” para crear el directorio “~/.ssh” crear el fichero “~/.ssh/authorized_keys” con la clave pública DSA que hemos subido al servidor, e indicarle que solo puede usar la orden ‘sudo‘:

[[email protected] ~]$ ssh [email protected]
[email protected]'s password: 

[email protected]:~$ mkdir .ssh
[email protected]:~$ chmod 0700 .ssh/
[email protected]:~$ cat id_dsa.pub > .ssh/authorized_keys
[email protected]:~$ rm id_dsa.pub
[email protected]:~$ chmod 600 .ssh/authorized_keys
[email protected]:~$ ls -l .ssh/
total 4
-rw------- 1 sniffer users 631 may  4 19:55 authorized_keys
[email protected]:~$

Hecho esto el contenido de “~/.ssh/authorized_keys” quedaría algo parecido a esto:

ssh-dss A(...)suGkuJRcwAAAIEAmKBmvqR+0IjzrdYXR8BX(...)ZScAAACAG2l92RIc4vlI+o(...)UQoreQ= [email protected]

Ahora probamos a iniciar sesion con el usuario ‘sniffer‘ en el servidor:

[[email protected] ~]$ ssh [email protected]

Last login: Wed May  4 19:58:10 2011 from 10.0.0.33
[email protected]:~$

Ahora vamos a intentar iniciar sesión lanzando tcpdump:

[[email protected] ~]$ ssh [email protected] sudo tcpdump -i tun0

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun0, link-type RAW (Raw IP), capture size 65535 bytes
^CKilled by signal 2.
[[email protected] ~]$

Todo correcto así que vamos a preparar los parámetros de tcpdump y volcar la salida a una FIFO:

[[email protected] ~]$ mkfifo /tmp/fifo.sniffer
[[email protected] ~]$ ssh [email protected] sudo tcpdump -U -n -w - -i wlan0 "port 80" > /tmp/fifo.sniffer

Ahora, ya podemos lanzar Wireshark con la siguiente orden:

[[email protected] ~]$ sudo wireshark -k -i /tmp/fifo.sniffer

La opción “-k” es para que comience la captura en cuanto se abra.

Categories: *BSD, General, GNU/Linux, Red, Seguridad, UNIX Tags: