Port Knocking con PowerShell

Después de varios días investigando con el USB Rubber Ducky para preparar una ponencia en el VI Congreso ACCID, sobre los peligros de los dispositivos USB si no se dispone de un control de éstos,  y como nos gusta tanto compartir con vosotros nuestras experiencias, os dejo este artículo sobre cómo hacer Port-Knocking con PowerShell para, por ejemplo, poder ejecutarlo desde nuestro querido Pato (USB Rubber Ducky).

A estas alturas creo que todos conocéis ya de sobra a nuestro amigo Pato, oficialmente conocido como USB Rubber Ducky y del que nuestro compañero Goldrak ya nos ha hablado. Si aún no habéis leído sus dos primeros artículos de esta serie, os aconsejo que lo hagáis:

Cuando el pato teclea Cuack Cuack – Parte 1

Cuando el pato teclea Cuack Cuack – Parte 2

¿Por qué Port Knocking?

La idea original era que el Pato ejecutara una instrucción PowerShell para descargar desde un servidor Web el payload que previamente habríamos preparado con Metasploit, para que la víctima (mejor dicho, nuestro Pato) lo descargara y ejecutara para obtener una sesión Meterpreter.

Así lo hice, monté mi servidor Web con Apache, generé con msfpayload un payload de tipo windows/meterpreter/reverse_tcp con los parámetros correspondientes y subí el fichero al servidor Web, listo para su descarga.

Problema: si dejo el servidor Web funcionando continuamente a la espera de algún ataque con el Pato, corro el riesgo de que el servidor y el recurso sean indexados por buscadores, crawlers y otras arañas. Lo ideal sería que fuera el propio Pato el que levantara el servicio Web, descargara el payload, y bajara el servicio. De esa forma dejar el servidor lo más “invisible” posible.

Se me ocurrió hacerlo con Port-Knocking, así que instalé knockd en mi servidor, donde tengo montado el servidor Web y subido el payload. El siguiente paso era configurar el knockd para que al “tocar” los puertos TCP 7000, 8000 y 9000 en un tiempo máximo de 10 segundos, levante el servicio Web, espere 30 segundos y lo vuelva a bajar. ¿Sencillo verdad?

Este es el archivo de configuración de knock.conf:

[options]

logfile = /var/log/knockd.log

sequence    = 7000,8000,9000

seq_timeout = 10

command     = service apache2 start ; sleep 30 ; service apache2 stop

tcpflags    = syn

En la opción command, escribo los comandos que quiero que se ejecuten en caso de que haya un Port-Knocking correcto: Iniciar Apache, esperar 30 (tiempo para la descarga del payload) y parar Apache.

Seguía teniendo un problema, y es que necesitaba un cliente de Port-Knocking. Hay varios clientes para Windows, pero necesitaría su descarga.  Otra opción sería con telnet o netcat, pero en las últimas versiones de Windows no están instaladas por defecto.

¡Houston! Aquí es donde me acordé de mi amigo Pablo González y de su charla en Qurtuba CON sobre PowerShell. ¿Por qué no intentar hacer Port-Knocking con PowerShell? Así que me puse manos a la obra y a investigar, de paso me vendría bien para adentrarme en este mundo de PowerShell, ya que yo soy más de “pingüinos”.

Pronto me empecé a llevar gratas sorpresas y di con clases y métodos tales como:

powershell (New-Object System.Net.Sockets.TcpClient).Connect(‘ip-address,’port’)

Que permite establecer como Cliente TCP una conexión al servidor y puerto que indiquemos. Así que probé a realizar la “llamada a puertos” con esta instrucción, repitiendo por cada puerto (7000, 8000, y 9000)

El knockd estaba esperando en un tramo máximo de 10 segundos, knocking a los puertos TCP 7000, 8000 y 9000, pero al ejecutarlos con PowerShell no lograba pasar todos los stages del Port-Knocking. Pensé que podía ser por el tipo de conexión, al no indicar nada, el cliente TCP intentaría llevar a cabo el Three-Way Handshake completo, lo que me podría causar problemas. Lo ideal sería poder indicar tipo de flag en los paquetes que envía el cliente, para que sólo envíe de tipo SYN, pero no encontré la forma.

Sin embargo, sí me encontré con otro método de la clase anterior, llamado BeginConnect que realiza una conexión asíncrona, y que por el tipo de conexión sí que me cuadraba más para poder llevar a cabo el Port-Knocking de forma exitosa.

powershell (New-Object System.Net.Sockets.TcpClient).BeginConnect(‘ip-address’,’port’,$null,$null)

Con la dirección IP y los puertos correspondientes, ejecutándolos en un tramo máximo de 10 segundos, conseguí el Ábrete Sésamo del knockd. ¡Bingo!

Port Knocking con PowerShell

Bastaría con cambiar el puerto por 8000 y 9000, siempre y cuando se ejecuten dentro de esos 10 segundos.

[2015-05-28 08:17] 8x.1x.16x.4x: prueba: Stage 1
[2015-05-28 08:17] 8x.1x.16x.4x: prueba: Stage 2
[2015-05-28 08:17] 8x.1x.16x.4x: prueba: Stage 3
[2015-05-28 08:17] 8x.1x.16x.4x: prueba: OPEN SESAME

Ya tan sólo me quedaría modificar el script del Pato, añadiendo las líneas correspondientes del Port-Knocking con PowerShell. La última línea del script del Pato sería la descarga y ejecución del payload.

En próximos artículos veremos cómo llevar a cabo estos pasos.

Como siempre, espero que el artículo haya sido de vuestro interés.

¡Hasta la próxima!