Archivo

Posts Tagged ‘instalacion elasticsearch’

Seguridad en ElasticSearch: ES desde la perspectiva de un pentester – Parte V

octubre 14, 2019 1 comentario

Cuando ponemos un nodo en modo “cluster” es cuando realmente se empiezan a complicar las cosas desde el punto de vista de la seguridad. Algunas consideraciones que fácilmente se pueden detectar desde el punto de vista de un pentester son las siguientes:

Sin mecanismos de autenticación o autorización en el acceso a la API Rest.

Como se ha visto en los post anteriores de ésta serie (parte1, parte2, parte3, parte4), la API Rest de una instancia de ES es muy potente, de hecho es el corazón del motor. Desafortunadamente, por defecto no se implementa ningún mecanismo de seguridad para la autenticación de usuarios. Recordad que ES es una base de datos, con un modelo de funcionamiento diferente a las bases de datos relacionales pero su objetivo principal es el mismo: el almacenamiento de información. Si en una base de datos tradicional se permite que cualquier usuario sin autenticación previa, ejecute consultas SQL sobre las tablas y que tenga la posibilidad de lanzar procedimientos almacenados, estamos en una situación poco deseable en la que como mínimo, es posible que se produzcan fugas de información sensible y a mayores, en la explotación del sistema. Pues bien, por defecto esto es lo que tenemos con cualquier instancia de ES. Alguien podría decir: “pero no pasa nada, porque la API Rest de ES se vincula únicamente a la interfaz de red local, que no está expuesta a otros sistemas y por lo tanto únicamente un administrador podrá acceder a ella”. Sí y no. Si utilizamos ES en modo de desarrollo, es decir, con un único nodo local y sin activar el modo cluster esto es cierto, pero aún así, si el sistema ya ha sido comprometido y un atacante tiene la posibilidad de ejecutar comandos, se podría crear fácilmente un túnel SSH que exponga el puerto en el que se encuentra en ejecución la API Rest de ES y de esta forma, acceder a la información almacenada en el cluster. Incluso, sin llegar al supuesto de que el sistema haya sido comprometido, es posible que el administrador quiera acceder a la instancia remotamente y lanzar consultas, para ello también podría crear un túnel SSH abriendo la posibilidad de que él y cualquiera pueda entrar ya que por defecto, no hay mecanismos de autenticación y autorización.

ssh -L 0.0.0.0:9999:127.0.0.1:9200 esuser@localhost

Por ejemplo, si se ejecuta el comando anterior sobre el sistema en el que se encuentra en ejecución la instancia de ES, se abrirá el puerto “9999” en todas las interfaces de red disponibles y se podrá acceder a la API Rest de ES utilizando dicho puerto. Esta es solo una forma, existen otras más, por ejemplo utilizando redirecciones con socat. Este y muchos otros temas relacionados con la post-explotación de sistemas los enseño en los cursos que imparto en Securízame por si estás interesado.

Operaciones de administración de la instancia de ES sin protecciones de ningún tipo.

Ahora bien, en el caso de que efectivamente, lo anterior no sea posible porque el sistema está correctamente securizado y no hay agujeros de seguridad que le permitan a un atacante crear un túnel como el anterior, aún hay que considerar que si la instancia de ES se ha configurado en modo “cluster”, cualquiera se podrá conectar a ella, ya que como se ha visto en la parte anterior de esta serie, para que el modo cluster funcione correctamente la instancia tiene que permitir la conexión remota por parte de otros nodos. Esto significa que lo más probable es que otras instancias puedan consultar cualquier endpoint de la API Rest, incluyendo aquellos que permiten la administración completa del nodo, nuevamente sin ningún tipo de restricción.

Fugas de información sensible con instancias maliciosas en el cluster

Otra cuestión a tener en cuenta en el modo cluster, es que se puede consultar fácilmente si una instancia actúa como “master” y levantar otra instancia que funcione en modo “esclavo” para obtener las replicas de la información almacenada en el cluster. Esto está muy bien sino fuese porque nuevamente, no hay ningún mecanismo de autenticación y autorización por defecto en ES para este tipo de operaciones, es decir, que por defecto se “confía” en que la instancia que se quiere unir al cluster es legitima y no hay ningún mecanismo para indicar cuáles son aquellas instancias que realmente están autorizadas para unirse al cluster y cuáles no. Es posible que el lector recuerde o haya visto alguna vulnerabilidad de transferencia de zona en servidores DNS mal configurados, pues en este caso estamos ante una situación muy similar. Es posible levantar una instancia de ES y editar la configuración por defecto para que apunte al master y obtener la replica de los documentos almacenados en el cluster, es decir, la información propiamente dicha.

Denegación del servicio sobre nodos del cluster.

Existe otro problema inherente al funcionamiento de ES relacionado con el almacenamiento de la información. Como se ha mencionado anteriormente, la estructura de los documentos almacenados en ES parte de un índice, que funciona como un esquema en una base de datos relacional. Esta información se carga en memoria con el objetivo de que el acceso sea rápido, por lo tanto la máquina sobre la que se ejecutan dichas instancias tienen que ser lo suficientemente potente (tanto en términos de memoria como de procesamiento) para admitir la carga de estos documentos. Se tiene que tener un muy buen control sobre lo que se va a almacenar, es decir, permitir la inserción de documentos únicamente con la información estrictamente necesaria y evitar que sean estructuras JSON muy grandes. Si la API Rest de ES puede ser consultada por cualquiera o simplemente, no se tiene cuidado con las cuestiones indicadas antes, es posible que hayan problemas de almacenamiento en una o varias instancias del cluster, pudiendo incluso provocar condiciones de denegación de servicio. Por otro lado, tal como se ha explicado en uno de los posts anteriores de la serie, gracias a la API Rest de ES es posible abrir y cerrar índices, acción que se encarga de volcar los documentos del índice en cuestión a disco (operación de cierre) o de disco a memoria (operación de apertura). El problema de estas operaciones es que son costosas en términos de recursos como resulta evidente y si se ejecutan constantemente sin ningún control sobre índices con miles de documentos (ejecutando un script malicioso, por ejemplo) es bastante probable que se produzca una condición de denegación de servicio.

Tráfico sin cifrar.

En modo cluster los nodos se comunican e intercambian paquetes de datos sin ningún tipo de protección en la capa de transporte. Esto significa que evidentemente, es inseguro por defecto. Como seguramente ya sabéis, esto puede dar lugar a diferentes tipos de ataques que van desde la captura pasiva de paquetes hasta la manipulación y posterior reinyección de los mismos en ciertos escenarios. En este punto poco más merece la pena explicar, es evidente que se trata de un problema de seguridad que no es aceptable en un cluster encargado de almacenar información sensible.

¿Contramedidas?

Si el lector ha trabajado anteriormente con ES, seguramente una de las primeras cosas en las que pensará será en las características de seguridad disponibles en el módulo “X-Pack” (https://www.elastic.co/guide/en/elasticsearch/reference/current/configuring-security.html) y a continuación en la inversión que habría que realizar para adquirir y habilitar dicho módulo en la instancia de ES, ya que no es gratuito. Sin embargo, debido a la presión de la comunidad pidiendo implementar mecanismos de seguridad en la versión gratuita de ES, desde mayo del presente año todas las versiones de ES desde la 6.8 cuentan con características de seguridad incluidas en el producto y que se pueden activar si el administrador así lo desea. Dicho anuncio se ha hecho público hace unas pocas semanas a la fecha de escribir este post y se puede consultar aquí: https://www.elastic.co/es/blog/getting-started-with-elasticsearch-security

No obstante, como resulta evidente las instalaciones de ES existentes tienen que ser “reinstaladas” con las nuevas versiones disponibles en los repositorios de ES, lo cual no es precisamente una tarea fácil cuando la instancia o cluster tiene datos almacenados pero ya es algo.

Algunas de las características relativas a la seguridad en ES, que ahora se encuentran integradas por defecto y para las que no hace falta tirar de X-Pack son las siguientes.

  • Control de accesos basado en roles.
  • Comunicación segura entre nodos de la instancia.
  • Autenticación de usuarios basada en directorio activo, LDAP, Kerberos, SAML o de forma local.
  • Tráfico confiable “nodo a nodo”, habilitando filtrados basados en listas blancas.
  • Logging en eventos relacionados con la seguridad de forma transparete.

Entre muchas otras cosas más. Se trata de características que evidentemente se deben utilizar en un entorno productivo para proteger la información de accesos no autorizados y “miradas indiscretas”.

Un Saludo y Happy Hack.

Adastra.

Seguridad en ElasticSearch: Indices y búsquedas – Parte II

agosto 25, 2019 3 comentarios

En la primera parte de esta serie se han explicado las características funcionales incluidas en ES y los diferentes mecanismos de instalación. Ahora es el momento de comprender cómo funciona ES a la hora de crear índices, tipos y documentos, así como los endpoints disponibles en la API Rest para realizar búsquedas. La API Rest de ES es extensa y compleja, por lo tanto en estos posts solo se intentará cubrir las cuestiones relacionadas con la forma de realizar búsquedas, configuración de nodos/clusters, así como algunos complementos y medidas que pueden ayudar a mejorar la seguridad de una instancia de ES.

En primer lugar, hay que tener en cuenta que ES es bastante parecido a otros gestores de bases de datos no relacionales como MongoDB, especialmente en el sentido de que no hay una estructura fija. Esto significa que a diferencia de una base de datos relacional con tablas, las cuales están compuestas por un conjunto de columnas con restricciones en tipos de datos, relaciones con otras tablas (claves foráneas), longitudes, campos obligatorios, etc. En ES este tipo de estructuras y jerarquías a la hora de almacenar información son un poco diferentes. Para que esta idea quede clara, se expone el siguiente ejemplo:
En una base de datos relacional, se podría crear una tabla de usuarios, la cual estará compuesta por campos tales como: “nombre”, ”edad”, “genero”, “rol” y “fechaNacimiento”. A la hora de realizar una inserción de un registro en dicha tabla, se debe incluir como mínimo, un valor para todos aquellos campos que sean obligatorios y no se podría crear un registro que tenga un campo que no se encuentre definido en la tabla, es decir, no se podría crear un registro que incluya un campo llamado “direccionUsuario” dado que este campo no está en la definición de la tabla. Esto, en el mundo de ES no es así, ya que cada registro que es conocido como un document almacenado en un index y type concretos, no necesariamente tiene una estructura de campos fija, de hecho, se trata simplemente de estructuras JSON que pueden tener “cualquier cosa”, incluso elementos con múltiples valores como arrays, comportamiento que podría servir para crear relaciones de composición entre diferentes bloques de información, tal como se pretende hacer con las claves foráneas en una base de datos relacional. Los documentos en ES, desde el punto de vista técnico pueden estar compuestos por estructuras de datos no homogéneas, aunque evidentemente a la hora de diseñar un sistema es altamente recomendable definir una estructura base que será utilizada para la creación de registros en un nodo o cluster de ES. Dicho esto, es el momento de ver cómo crear índices, tipos y documentos.

¿Cómo crear registros en una instancia o cluster de ES?

Como se ha explicado en el post anterior a éste, para interactuar con una instancia o cluster de ES es necesario utilizar la API Rest que se encuentra disponible en cualquier nodo en ejecución. Se puede utilizar cualquier cliente HTTP para realizar peticiones contra dicha API Rest, desde CURL, wget, Postman hasta un objeto HttpConnection en Java o la librería “requests” de Python. El cliente empleado no es tan importante como conocer los endpoints disponibles y cómo se deben invocar de forma correcta. Probablemente la creación de índices es la labor más importante en ES y también, de las más sencillas tal como se puede apreciar en la siguiente imagen:

Utilizando Postman se ha creado un índice llamado “articulos”, con un tipo llamado “noticia” y un documento con identificador “2019001”. Si se quisiera comparar esta estructura con algo más familiar, como una base de datos relacional, “articulos” sería un esquema en la base de datos, “noticia” una tabla y “2019001” la clave primaria del registro insertado y luego, la estructura JSON que viaja en el cuerpo de la petición contiene los valores del registro propiamente dicho, cada uno en el campo que le corresponde. Sencillo, no?

Bien, esto es la operación de inserción pero también se puede gestionar el índice, tipos y documentos con operaciones CRUD (Create, Read, Update, Delete) tal como se puede apreciar a continuación.

Operación de lectura: Petición HTTP GET: http://ES_IP:ES_PORT/index/type/id

Operación de actualización: Petición HTTP POST: http://ES_IP:ES_PORT/index/type/id

Operación de borrado: Petición HTTP DELETE: http://ES_IP:ES_PORT/index/type/id

Gestionar índices en ES no es una labor compleja pero si vital para el correcto funcionamiento del sistema, ya que evidentemente es “el core” de la información y sobre los cuales trabajan otros endpoints de la API Rest disponibles en ES. Ahora que se ha visto cómo crear, obtener, actualizar y eliminar índices en ES, es el momento de hablar de búsquedas sobre estás estructuras de datos.

¿Cómo realizar búsquedas en ES?

Nuevamente es necesario utilizar la API Rest para realizar búsquedas contra ES. Dado que ES al igual que Lucene, se han creado precisamente para realizar búsquedas rápidas y potentes, no es de extrañar que ésta sea también una de sus características más complejas y difíciles de controlar. En este post solamente se explicará el proceso de búsquedas simples con el endpoint “_search”. En el próximo se hablará sobre la ejecución de búsquedas más complejas con múltiples filtros, paginación, acceso a mapeos, etc.

En primer lugar, el endpoint “_search” se pude utilizar directamente contra todos los índices disponibles en ES o contra uno concreto, nuevamente se puede utilizar Postman o cualquier cliente HTTP para realizar peticiones como las siguientes:

http://ES_HOST:ES_PORT/_search

Búsqueda sobre todos los índices disponibles en ES.

http://ES_HOST:ES_PORT/articulos/_search

Búsqueda sobre todos los documentos disponibles en el índice “articulos”.

http://ES_HOST:ES_PORT/articulos,negocios/_search

Búsqueda sobre todos los documentos disponibles en los índices “articulos” y “negocios”.

http://ES_HOST:ES_PORT/a*,n*/_search

Búsqueda sobre todos los documentos disponibles en los índices que empiezan por “a” y “n”.

http://ES_HOST:ES_PORT/articulos/noticia/_search

Búsqueda sobre todos los documentos disponibles en el índice “articulo” y tipo “noticia”.

http://ES_HOST:ES_PORT/_all/noticia,test/_search

Búsqueda sobre todos los documentos disponibles en todos los índices que tengan los tipos “noticia” y “test”.

http://ES_HOST:ES_PORT/articulos/noticia/_search?q=constitución

Búsqueda sobre todos los documentos disponibles en el índice “articulo” y tipo “noticia” aquellos cuyos en los que al menos un campo tenga la palabra “constitución”, o que se asemeje (esto se verá en el siguiente post).

Se trata de algunas de las peticiones más simples que se pueden ejecutar con ES y el endpoint “_search”, teniendo en cuenta que ahora mismo solamente se aplican filtros sobre índices y tipos, aún no se ha visto cómo filtrar por campos o paginar y además, las búsquedas anteriores se pueden hacer simplemente utilizando método HTTP GET. Como se verá en el siguiente post, esto se puede complicar bastante más dada la flexibilidad del motor de búsqueda y su potencia a la hora realizar consultas rápidas sobre volúmenes grandes de información.

Un saludo y Happy Hack.

Adastra.

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.

A %d blogueros les gusta esto: