Archivo

Posts Tagged ‘adastra python’

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.

Junio, mes de cursos de Python en Securizame.

mayo 19, 2016 Deja un comentario

logo_securizame

Llega junio con una propuesta formativa muy interesante por parte de Securizame, en donde tendré el placer y el honor de colaborar con la serie de cursos enfocados completamente a Python. Como podréis apreciar en la web de Securizame, se trata de una oferta formativa bastante completa en la que tendréis la posibilidad de conocer en profundidad las características más interesantes del lenguaje con el acompañamiento de profesionales de primer nivel, entre los que se encuentran Dani Garcia (Cr0hn), Maria José Montes, Julio Semper y un servidor. Podéis adquirir los módulos en formato individual o el curso completo, algo que recomiendo si de verdad queréis aprender a crear herramientas de todo tipo con Python. Algunos de los módulos son online, pero como podréis comprobar, algunos son presenciales incluyendo el que voy a impartir, aunque se está barajando la posibilidad de hacerlos también online para las personas que por cualquier motivo no podéis acercaros a las oficinas de Securizame en Madrid. Evidentemente, los cursos presenciales tienen la ventaja de que podéis hacer todas las preguntas que queráis y resolverlas “in-situ” y por si fuera poco, son cursos que se van a impartir los viernes en la tarde y los sábados, lo que facilita enormemente las cosas para aquellas personas que por trabajo u otras obligaciones no tienen la posibilidad de asistir entre semana. Las instalaciones se encuentran muy bien equipadas y con todo lo necesario para desarrollar cada uno de las clases que haremos los profesores, cuyos contenidos hemos diseñado con mucho cariño e ilusión, esperando que de verdad os sean útiles para vuestras vidas profesionales y/o académicas.
Creo que es una buena oportunidad para dominar el lenguaje y automatizar muchas de las labores que seguramente hacéis manualmente y que pueden suponer varias horas del día haciéndolas.
Finalmente, para animaros un poco y dependiendo del número de asistentes que decidáis apuntaros al curso completo, llevaré algunas copias de los dos libros de Python que he escrito para rifarlas entre vosotros, algo que os vendrá como anillo al dedo para apoyar vuestra formación en dicho lenguaje.

Espero veros por allí y si necesitáis más información al respecto, podéis rellenar el formulario que se encuentra disponible aquí o llamar directamente al teléfono que aparece en la página.

Un saludo y Happy Hack!
Adastra.

THW Academy: Plataforma de aprendizaje para hackers en castellano.

octubre 19, 2015 4 comentarios

Logo HackerWay1 Las cosas han cambiado muchísimo con respecto a hace poco más de 15 años, por aquel entonces encontrar información sobre seguridad informática y hacking no estaba al alcance de todo el mundo, en las bibliotecas ya te podías olvidar de encontrar manuales sobre reversing en sistemas Linux, explotación de software o hacking en general. Por aquella época todo ello era como la magia o la alquimia, cosas maravillosas que pocos habían llegado a escuchar y muchos menos habían llegado a ver.
Ahora tenemos Internet, comunidades, blogs, foros, etc. Mucha información que se encuentra a nuestro alcance y llegamos a ella al instante, muchas nuevas tecnologías y una curva de aprendizaje que cada vez está más cuesta arriba. No obstante nos seguimos encontrando con que prácticamente toda la documentación de calidad y con buenos niveles de profundidad se encuentra en inglés.
Hay muchos sitios en castellano que no son buenos, son lo siguiente, pero a veces se suelen centrar una temática muy concreta o abarcan muchos temas sin llegar a un nivel de profundidad aceptable en ninguno.
Luego, hay muchos cursos/certificaciones en donde te piden que pagues miles de euros para aprender sobre web hacking, reversing, networking, programación o cualquier otra temática concreta, con unos precios que a mi juicio tienen una calidad/precio muy desproporcionada.
Los que me conocéis o seguís este blog, sabéis que me gusta investigar y compartir lo que aprendo, llevo muchos años con una “sed” de conocimiento que nunca he llegado a saciar y aunque han habido épocas en las que me he sentido muy cansado y desmotivado por situaciones concretas, nunca he claudicado y llevo media vida, casi 15 años, intentando aprender y mejorar mis habilidades a nivel personal y académico, lo hago porque como he dicho en otras ocasiones, para mi esto no es solamente un oficio, representa una filosofía de vida a la que me mantengo fiel y también por eso escribo en este espacio cada vez que puedo.
Todo esto me ha llevado a crear THW Academy (http://academy.thehackerway.com/), una plataforma de aprendizaje totalmente online en la que vas a poder aprender sobre seguridad informática y hacking desde una perspectiva completamente “hands on” o practica. No esperes las típicas clases tradicionales llenas de conceptos teóricos sin ningún tipo de demostración practica, o clases demasiado extensas y aburridas en las que desconectas a los 10 minutos. Todas las sesiones de cada uno de los cursos tienen una parte teórica que suele ser muy concisa y una parte practica en la que se puede ver “al vuelo” cómo se aplican los conceptos teóricos.
Este espacio lo he diseñado con tres niveles de cursos: “Básico”, “Intermedio” y “Avanzado”, cada uno adaptado a su correspondiente nivel. Las personas inscritas en la plataforma podrán acceder a todos los cursos de cada nivel sin ningún tipo de restricción. Se suben varias sesiones todas las semanas que se pueden consultar en el calendario oficial, además tendrás acceso a vídeos en HD, documentación y espacios privados especialmente diseñados para probar técnicas de hacking.
Puedes seguir todos los cursos a la vez o solamente aquellos que sean de tu interés. Es aconsejable ir siguiendo las sesiones de todos los cursos para sacar el máximo provecho de la plataforma, pero el estudiante es libre de seguir únicamente aquellos cursos que decida. En la medida en que los cursos van avanzando, los contenidos van siendo más prácticos y didácticos, el desarrollo de las sesiones semanales es constante y muy dinámico, cada mes vas a tener acceso a varios vídeos que podrás repasar las veces que quieras.
La plataforma se encuentra ubicada en: http://academy.thehackerway.com y como podrás ver en el catalogo de cursos, los que se encuentran disponibles actualmente son los siguientes:

“Básico”
THWB1: Introducción a la programación en Python.
THWB2: Introducción a la privacidad y el anonimato.
THWB3: Introducción a la programación en Ruby.
THWB4: Introducción al pentesting y al hacking.

“Intermedio”
THWI1: Pentesting en aplicaciones web.
THWI2: Administración y hardening de servidores web Apache.
THWI3: Desarrollo web seguro con Java.

“Avanzado”
THWA1: Hacking con Python.
THWA2: Uso y configuración avanzada de I2P y Freenet.
THWA3: Uso y configuración avanzada de TOR.

Son 10 cursos a los que vas a tener acceso por el mismo precio y además hay promociones que te podrían interesar.  El calendario oficial incluye la planificación de las sesiones que se van a publicar durante los próximos meses con sus correspondientes contenidos, el cual puedes consultar en el siguiente enlace: http://academy.thehackerway.com/calendario-oficial además, puedes ver más detalles sobre THW Academy aquí: http://academy.thehackerway.com/cuentame-que-es-esto
En los próximos meses también tengo planificados cursos sobre Arquitectura de ordenadores, introducción a ensamblador, Fuzzing y explotación de software avanzado en sistemas Windows y Linux.
Esto es lo que tengo para toda la comunidad, quiero compartir lo que constantemente he ido aprendiendo en los años que llevo dedicado a esto y todo lo que me queda por aprender. Creo que está es una buena forma.

Como siempre, si quieres comentarme cualquier cosa o necesitas más información, me puedes escribir a adastra@thehackerway.com

Saludos y Happy Hack!
Adastra.

A %d blogueros les gusta esto: