HttpOnly Session Hijacking XSS: Explicación y PoC

    El atributo "HttpOnly" en las cookies HTTP es esencial para mejorar la seguridad de las aplicaciones web al mitigar el riesgo de robo de cookies y proteger los datos del usuario. Este atributo impide que las cookies sean accesibles desde scripts del lado del cliente, como JavaScript, limitando su accesibilidad únicamente a las solicitudes HTTP. Esto proporciona una capa adicional de defensa contra ataques, especialmente los de tipo Cross-Site Scripting (XSS), donde los atacantes inyectan scripts maliciosos en páginas web para robar cookies o realizar acciones no autorizadas.

    Cuando un servidor web envía una cookie al navegador de un usuario, esta se almacena generalmente como un archivo de texto en el dispositivo del usuario y puede contener información sensible como ID de sesión, preferencias de usuario o tokens de autenticación. Sin el atributo "HttpOnly", estas cookies son accesibles tanto para los scripts del lado del cliente como para los del servidor, lo que aumenta el riesgo de que un atacante las robe y secuestre sesiones.

    Al habilitar el atributo "HttpOnly", se restringe el acceso de las cookies a los scripts del lado del cliente. Esto significa que incluso si un atacante logra inyectar un código malicioso en una página web, no podrá leer ni manipular los datos de la cookie. Esto reduce significativamente la superficie de ataque y protege mejor la información del usuario.

    Por ejemplo, en una aplicación de banca en línea, después de que un usuario inicia sesión, el servidor establece una cookie de sesión con el token de autenticación. Si la cookie no está marcada con "HttpOnly", un atacante que inyecta un script malicioso en la página puede robar la cookie y acceder a la cuenta del usuario. Sin embargo, si la cookie está marcada con "HttpOnly", el script malicioso no podrá acceder a la cookie, evitando el acceso no autorizado.

    En resumen, el atributo "HttpOnly" es una medida de seguridad crucial que los desarrolladores web deben implementar para proteger las cookies y, por ende, la información sensible de los usuarios contra accesos no autorizados y actividades maliciosas.



PoC 



    Después de autenticarnos, vemos que tenemos un campo de entrada. Cuando presionamos enviar, descubrimos que esta entrada proporcionada por el usuario se refleja en el lado del cliente. Lo que nos indica que podemos empezar a  probar ataques de Cross Site Scripting (XSS).

    Podemos saber si podemos secuestrar la información de la sesión inspeccionando las cookies y viendo si el atributo HTTP/HttpOnly está habilitado, lo cual vemos que no esta habilitado(false).



    En esta caso inyectaremos un script de JavaScript para ver mediante un PopUp la cookie de sesión. Con esto acabamos de ver que podemos inyectar JavaScript y confirmamos que el atributo HttpOnly no esta configurado.

    
    Vamos a crear un script el cual va a robar la cookie de sesión y que nos la envíe a nuestro servidor web:


    Este código crea una aplicación web básica usando Flask. Importa varias utilidades de Flask y configura la aplicación para servir archivos estáticos desde una carpeta específica. La aplicación está en modo de depuración para facilitar el desarrollo.

    Define una ruta /<steal_cookie> que acepta solicitudes GET con un parámetro de URL. Cuando se accede a esta ruta, se ejecuta una función que devuelve una plantilla HTML llamada "evil.html"`. Finalmente, la aplicación se ejecuta en la dirección "0.0.0.0" y el puerto "1337".

    Instalaremos algunas dependencias para ejecutar nuestro script como "flask" y "requests"

    Una vez lo ejecutemos, vamos a inyectar inyectar un script de JavaScript el cual va a capturar la cookie y la va a enviar a nuestro localhost por el puerto 1337 como parte de la URL.


    Después de inyectar el script, vemos la cookie en los registros del servidor.



Leer más»

Inyecciones LDAP: Explicación y PoC

    LDAP son las siglas de Protocolo Ligero de Acceso a Directorio, o en inglés (Lightweight Directory Access Protocol). Se trata de un conjunto de protocolos de licencia abierta que son utilizados para acceder a la información que está almacenada de forma centralizada en una red. Este protocolo se utiliza a nivel de aplicación para acceder a los servicios de directorio remoto.

    Un directorio remoto es un conjunto de objetos que están organizados de forma jerárquica, tales como nombres, claves, direcciones, etc. Estos objetos estarán disponibles por una serie de cliente conectados mediante una red (interna o LAN), y proporcionarán las identidades y permisos para esos usuarios que los utilicen.

    De forma general, estos directorios se utilizan básicamente para contener información virtual de usuarios, para que otros usuarios accedan y dispongan de información acerca de los contactos que están aquí almacenados. Además es capaz de comunicarse de forma remota con otros directorios LDAP. De esta forma se crea una base de datos de información descentralizada y completamente accesible

    Las inyecciones LDAP son un tipo de ataque en el que se aprovechan las vulnerabilidades en las aplicaciones web que interactúan con un servidor LDAP. 

    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. y llegar a 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 o 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.




POC 1

    Nos encontramos ante una aplicación web, las cual nos pide un usuario y contraseña para entrar;


    Intentamos iniciar sesión con un nombre de usuario y una contraseña aleatorios, pero el resultado es negativo;


    La arquitectura de la aplicación que soporta LDAP incluye componentes tanto del lado del servidor como del lado del cliente. Las consultas LDAP enviadas al servidor se conocen como filtros de búsqueda LDAP, que se construyen utilizando notación prefijo. A continuación, se muestra un ejemplo de un filtro de búsqueda LDAP:

find("(&(cn=" + username +")(userPassword=" + pass +"))")

Esta notación de filtro prefijo instruye a la consulta a encontrar un nodo LDAP con el nombre de usuario y la contraseña dados. La cual busca entradas en el directorio LDAP que cumplan con ambas condiciones: cn (Common Name) sea igual a "algo" y userPassword (contraseña del usuario) sea igual a "algo".

    Si revisamos el codigo del aplicativo; 


    Podemos ver que el filtro se construye concatenando directamente el nombre de usuario y la contraseña en el filtro sin una adecuada sanitización. Si reemplazamos el nombre de usuario y la contraseña con un carácter especial, podemos eludir los controles de autenticación. Usar "*" como nombre de usuario y contraseña resultará en un inicio de sesión exitoso puesto que busca cualquier atributo que coincida con cualquier valor;

"(&(cn=" * ")(sn=" * "))";

    Esto altera significativamente la lógica de búsqueda y posiblemente nos permite el acceso no autorizado.



POC 2


Nuevamente  nos encontramos ante una aplicación web, las cual nos pide un usuario y contraseña para entrar;



    Revisemos el codigo de la aplicacion y vemos que es el mismo que vimos anteriormente;


    Pero el filtro el cual utilizamos para alterar la lógica esta vez no nos funciona;

"(&(cn=" * ")(sn=" * "))";



Y esto se debe a que para evitar la inyección LDAP verifica la longitud de la entrada del usuario. Si la longitud es menor a 2, la entrada del usuario es inválida.


    Pero podemos utilizar caracteres especiales distintos de "*" para crear consultas maliciosas y alterar la logica;

username = admin)(!(&(1=0 
password q))

    El filtro quedaría así;

(&(cn=admin)(!(&(1=0))(sn=q)))

    Donde en username busca resultados que sean igual a admin inviertiendo la condicion buscando donde 1=0 junto al operador NOT y en password busca entradas que sean igual a q




Leer más»

Vulnerabilidad Client-Side Template Injection (CSTI): Explicación y PoC

    El término Inyección de Plantillas en el Lado del Cliente (o CSTI por sus siglas en inglés, Client-Side Template Injection) hace referencia a 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.

    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.



PoC

    Nos encontramos ante un aplicativo web el cual utiliza AngularJS 1.5




    Si intentamos inyectar etiquetas HTML para un ataque XSS, vemos que no podemos;


    AngularJS analiza y renderiza cada expresión entre corchetes. Entonces, si pasamos una expresión aritmética, como {{7*7}}, deberíamos esperar 49 como resultado;


    Ahora que sabemos que el aplicativo es vulnerable a una inyección de plantilla del lado del cliente, queremos hacer más que solo imprimir números agradables.

    Al observar posibles payloads, encontramos una que funciona para Angular < = 1.5.0 en PayloadAllTheThings


    Este payload define una expresión asincrónica la cual es interpretada por AngularJS como explicamos anteriormente y manipula un nodo de AST de JavaScript para crear una expresión con el fin de lanzar una alerta en el navegador del usuario

    Como podemos ver, se ejecuta el Pop Up de "alert(1)" ejecutandose JavaScript;


    Ahora podemos ejecutar código JavaScript en nuestro DOM. Este payload lo podemos modificar utilizando Python, es este le vamos a pedir cuando valdría en decimal la palabra CuriosidadesDeHackers


    Con la misma plantilla anterior usada modificamos el "Alert" y utilizaremos el método "String.fromCharCode()", Se utiliza en JavaScript para crear una cadena de caracteres a partir de los valores Unicode especificados. Toma una secuencia de números Unicode y devuelve una cadena que contiene los caracteres correspondientes a esos números Unicode.


    Si lo ejecutamos vemos que nos lo muestra correctamente, esto lo podríamos derivar a diferentes ataques como un robo de cookie, obtener accesos no autorizados o realizar acciones en nombre de otro usuario.




Leer más»

Ataques de Deserialización: Explicación y PoC

    Los ataques de deserialización representan una amenaza significativa en el ámbito de la seguridad informática. Estos ataques se aprovechan de las debilidades en los procesos de serialización y deserialización de objetos en aplicaciones que utilizan la programación orientada a objetos (POO).

    La serialización, un proceso esencial en la transferencia de datos, convierte un objeto en una secuencia de bytes que puede almacenarse o transmitirse a través de una red. Por otro lado, la deserialización es la acción inversa, donde una secuencia de bytes se convierte de nuevo en un objeto. Los ataques de deserialización se producen cuando un atacante puede manipular los datos durante este proceso, lo que puede resultar en la ejecución de código malicioso en el servidor.

    Estos ataques pueden manifestarse en diversas aplicaciones, incluyendo aplicaciones web, móviles y de escritorio. Los atacantes pueden explotar estas vulnerabilidades de diferentes maneras:

        • Alterando el objeto serializado antes de su transmisión a la aplicación, lo que puede inducir errores en la deserialización y permitir la ejecución de código malicioso.

        • Enviando un objeto serializado malicioso que se aproveche de una vulnerabilidad en la aplicación para ejecutar código dañino.

        • Llevando a cabo un ataque de “man-in-the-middle” para interceptar y modificar el objeto serializado antes de su llegada a la aplicación.

    Estos ataques representan una seria amenaza, ya que podrían permitir a un atacante tomar el control completo del servidor o de la aplicación objetivo.

    Para mitigar estos riesgos, es fundamental que las aplicaciones validen y autentiquen meticulosamente todos los datos antes de proceder con la deserialización. Además, es esencial emplear bibliotecas de serialización y deserialización robustas y mantener actualizados todos los componentes de la aplicación para abordar posibles vulnerabilidades de seguridad.


PoC

    Nos encotrasmos frente a un aplicativo web:


    El cual tras capturarlo con burpsuite;


    No encontramos frente a un objecto url-encodeado, si lo url-decodeamos vemos;


    Nos encontramos con la estructurar la cual nos indica la cantidad de caracteres "0" y las strings "S"
    
    Si echamos un vistazo al código del aplicativo entenderemos tod mejor;


    Como podemos ver, hay una clase "pingTest" dentro del script. Podemos ver las diferentes variables dentro de la clase, como "ipAddress" e "isValid".

    El script parece aceptar un objeto "pingTest" serializado a través de HTTP POST. Luego deserializa el objeto, llama a la función de validación y, a su vez, llama a la función ping. Por lo tanto, podemos ver que cuando escribimos una dirección IP en el aplicativo web y lo enviamos, Javascript serializa el objeto listo para PHP, y luego pasa ese objeto al script PHP. El script valida el valor de la dirección IP dentro del objeto y luego procede a pintarlo si la dirección IP es vailda.

    Para hacer ping a la dirección IP, se llama al comando "shell_exec" que simplemente ejecuta el comando en el sistema local. 
    
    El aplicativo web no valida del todo el objeto "pingTest" enviado a través de la petición HTTP, podemos buscar establecer el booleano ‘ isValid ’, y engañar al aplicativo para que piense que la dirección IP sea un comando dándolo como valido puesto que confia en el input.

    Crearemos un script con parte del código;


    Al utilizar parte del código cambiando el "isValid" en "true", añadimos un "one liner" de una revshell y con el echo para que todo lo "url-encode" y lo "serialice". Como vemos, al ejecutarlo tenemos un objeto serializado con los datos del "one liner" incluido.

    Copiamos todo el nuevo objeto y lo sustituimos en la petición HTTP capturada en burpsuite;


Estando a la escucha con NetCat, al ejecutarlo conseguimos una ejecución remota de comandos;




Leer más»

Inyecciones NoSQL; Explicación y PoC

        Las inyecciones NoSQL representan una amenaza significativa para la seguridad de las aplicaciones web que dependen de bases de datos NoSQL como MongoDB, Cassandra y CouchDB. Estas vulnerabilidades ocurren cuando los atacantes pueden introducir datos maliciosos en consultas de bases de datos, que luego son ejecutadas sin la debida validación o sanitización por parte de la aplicación.

    Al igual que las inyecciones SQL, las inyecciones NoSQL explotan vulnerabilidades específicas de las bases de datos NoSQL. Sin embargo, su enfoque difiere al aprovechar consultas basadas en documentos en lugar de tablas relacionales. En una inyección NoSQL, los atacantes pueden manipular consultas de base de datos para obtener información confidencial o realizar acciones no autorizadas.

    La falta de validación de datos en consultas a bases de datos NoSQL permite a los atacantes realizar estas manipulaciones. A diferencia de las inyecciones SQL, que se dirigen a bases de datos relacionales, las inyecciones NoSQL explotan la falta de validación en consultas a bases de datos NoSQL. Esta falta de validación significa que los atacantes pueden ejecutar consultas de manera no autorizada y acceder a datos sensibles sin restricciones.

    Para mitigar las vulnerabilidades de inyección NoSQL y proteger las aplicaciones web contra posibles ataques, es crucial implementar las siguientes prácticas de seguridad:

        •  Validación de entrada de datos: Validar cuidadosamente todos los datos ingresados por el usuario antes de procesarlos en consultas de base de datos. Esto puede incluir la verificación de tipos de datos, longitud y caracteres permitidos, así como la implementación de listas blancas (whitelists) para permitir solo entradas válidas.

         •  Parámetros parametrizados o consultas preparadas: Utilizar parámetros parametrizados o consultas preparadas proporcionados por los marcos ORM (Mapeo Objeto-Relacional) o bibliotecas de acceso a datos. Estas técnicas aseguran que los datos proporcionados por el usuario se transmitan de manera segura a la base de datos, evitando así la ejecución no deseada de código malicioso.

         • Escapado de caracteres especiales: Escape de manera adecuada los caracteres especiales que podrían ser utilizados para realizar ataques de inyección. Esto implica convertir estos caracteres en su equivalente seguro para la base de datos antes de incluirlos en consultas.

        •Aplicación del principio de menor privilegio: Limitar los privilegios de acceso de la aplicación a la base de datos. Específicamente, asegúrese de que la aplicación solo tenga acceso a las operaciones y datos necesarios para su funcionamiento, reduciendo así el impacto de posibles ataques.

        •Actualizaciones y parches regulares: Mantener actualizados todos los sistemas y bibliotecas utilizados en el desarrollo de la aplicación, incluyendo el sistema operativo, el servidor web, la base de datos y cualquier software de terceros. Las actualizaciones y parches suelen incluir correcciones de seguridad que pueden mitigar vulnerabilidades conocidas.

         • Monitorización y registro de actividades: Implementar sistemas de monitorización y registro de actividades para detectar y registrar posibles intentos de ataque. Esto permite una respuesta rápida ante posibles incidentes de seguridad y facilita la identificación de patrones de actividad maliciosa.

         • Auditorías de seguridad regulares: Realizar auditorías de seguridad periódicas para evaluar la robustez de las medidas de seguridad implementadas y detectar posibles vulnerabilidades. Estas auditorías pueden ser realizadas internamente por el equipo de desarrollo o mediante la contratación de servicios externos de seguridad informática.

    Al implementar estas prácticas de seguridad, se pueden reducir significativamente el riesgo de ataques de inyección NoSQL y proteger sus aplicaciones web contra posibles brechas de seguridad.



PoC

    Nos encontramos frente a un dashboard de una maquina vulnerable la cual contempla Mongo como base de datos


    Vamos a intentar iniciar sesión en el panel de login con usuarios y contraseñas por defecto;


    Nos identifica la estructura por la cual se procesan los datos, vamos a capturar la petición con burpsuite;


Vemos que nos indica que el usurario o la contarseña son invalidos, tras aplicar numerosas inyecciones sql vamos a aplicar inyecciones NoSQL.

    En este caso vamos a filtrar por el usuario "admin" y le vamos a indicar en el campo "password" mediante el operador "$ne" que la contraseña no es igual a admin;

    Como vemos nos hemos conseguido loguear, si vamos un poco mas allá,  en este caso vamos a utilizar el operador "$ne" en ambos casos para que diga que el usuario no es igual a "CuriosidadesDeHackers" y que la contraseña no es igual a "admin";


    Conseguimos logearnos como administradores.

    De la misma manera lo podemos hacer con el operador "$regex"(El operador $regex se utiliza para realizar coincidencias basadas en expresiones regulares en MongoDB) y con el operador "$ne".

    Le indicamos que estamos buscando "documentos" donde el campo "username" mediante una expresión regular que comience con la letra "a" gracias al acento circunflejo. Y de la misma manera con el operador "$ne" le indicamos que la contraseña no sea igual a "admin".

    Nuevamente nos logeamos somo administradores, en caso de que hubiera mas usuarios podríamos jugar con el operador "$regex" variando la letra

    En el panel de busqueda si indicamos el usuario no nos da informacion;


    Pero al cambiar la petición a POST y la estructura a JSON nos vuelca información confidencial;


    En el mismo panel de búsqueda podemos utilizar cadenas, este caso jugaremos con la cadena "admin' || '' == '1", donde `'1' == '1' siempre es verdadero y al utilizar el operador o tuberías "||" (OR) la condición será siempre verdadera para "admin", como vemos nos vuelca información la cual no deberíamos de estar viendo;



PoC 2

     
    En este otro escenario nos encontramos nuevamente frente a un panel de login;



    Vamos a logeranos capturando la peticion con burpsuite, vemos que "nanai de la china limonera";


    Vamos a utilizar los operadores "$ne" nuevamente, sin embargo, obtenemos un "302 Found", que se corresponde con una respuesta positiva de la base de datos; 


    Vamos a utilizar un script de PayloadsAllTheThings para conseguir extraer usuarios y contraseñas;


    Este script es un ejemplo de un ataque de inyección basado en MongoDB;

        1. Importa las bibliotecas necesarias, como "requests", "urllib3", "string", "re" y "time".
        2. Desactiva las advertencias de "urllib3"para evitar mensajes molestos.
        3. Define algunas variables importantes, como "username" y "password".
        4. Define la URL del objetivo "u" y establece los encabezados HTTP.
        5. Inicia un bucle infinito ("while True:") para realizar el ataque de manera continua.
        6. Itera a través de todos los caracteres imprimibles ("string.printable") y construye un payload para la solicitud POST. Este payload se inyecta en el campo "username" y contiene una expresión regular ("$regex") que coincide con la cadena "username" más un carácter ("c") de "string.printable".
        7. Realiza una solicitud POST al objetivo con el payload construido.
        8. Verifica si la respuesta tiene un código de estado 302 (Redirección encontrada). Esto puede indicar que se ha encontrado un usuario válido.
        9. Si se encuentra una redirección, imprime el carácter encontrado y lo agrega al "username".
        10. El bucle continúa hasta que se encuentran todos los caracteres del "username".

Utilizaremos "$regex" para filtrar por usuarios y nos muestres las coincidencias, como vemos, obtenemos el usuario "admin";


    De la misma manera, al indicar en la variable "username="m" le estamos indicando que comience por la letra "m" y nos itere todos los caracteres validos restantes;




    Una vez tenemos los usuarios, podemos modificar el script para que utilice el operador "$regex" en el campo de "password" utilizando como variable "username" los usuarios que hemos encontrado;


    Al ejecutarlo nos va mostrando los caracteres validos para el usuario "admin";


    Y de la misma manera para el usuario "mango";




Leer más»