Ataque y Defensa de Aplicaciones Web
Una de las partes más importantes de cualquier auditoría de hacking ético es conocer las bases, estructuras y protocolos de las tecnologías que se van a auditar.
De esta manera, es muy importante conocer los protocolos que intervienen en la comunicación entre el navegador del usuario y el servidor y la estructura de un aplicativo web.
La ventaja de este modelo es que en cualquier momento se puede sustituir cualquiera de estas capas por otra capa que asuma las mismas funciones y que aporte más ventajas. Por ejemplo, el uso de una nueva tecnología o lenguaje de programación, sin influir en las otras capas. A continuación se enumeran las distintas capas:
- Controlador: Es la capa que se encarga de recoger y gestionar los datos de los usuarios para que sean tratados. Sirve de enlace entre las otras dos capas, es decir, con los datos que le indica el usuario (dirección URL y parámetros de entrada) solicita los datos al modelo y se los comunica a la vista.
- Modelo: Esta capa se encarga de gestionar y mantener los datos de la aplicación, se apoya en la base de datos.
- Vista: Por su parte la vista se corresponde con la representación visual de los datos, genera el código HTML y JavaScript que se devolverá al usuario para representar los datos obtenidos.
Define la sintaxis y la semántica que utilizan los elementos de software de la arquitectura web (clientes, servidores, proxies) para comunicarse.
La comunicación se realiza mediante una arquitectura Petición-Respuesta, los clientes (navegadores web, aplicativo móvil, etc.) envían peticiones HTTP al servidor. El servidor por su parte responde a cada petición con una respuesta HTTP y cierra el canal de conexión. Si el cliente necesita seguir comunicándose necesita volver a establecer una comunicación mediante el envío de una petición.
El protocolo HTTP es un protocolo sin estado. Es decir, no guarda ninguna información sobre conexiones anteriores. Este hecho se produce a que el canal de comunicaciones no permanece abierto, es decir, el cliente envía una petición HTTP y el servidor le devuelve una respuesta HTTP a su petición y se cierra el canal de comunicaciones.
El desarrollo de aplicaciones web necesita frecuentemente mantener estado. Para suplir esta carencia se hace uso del mecanismo de las cookies, que es información que un servidor puede almacenar en el sistema cliente.
Este mecanismo permite a las aplicaciones web entregarle al navegador del cliente un identificador de sesión que identifica al usuario en la aplicación (una vez que el usuario ha realizado una autenticación satisfactoria en el sistema).
En cada intercambio de información, el cliente envía al servidor (en las cabeceras de la petición HTTP) este identificador de sesión almacenado en la cookie. De esta manera, el servidor puede verificar el usuario de la aplicación con el que se está comunicando.
Las peticiones originadas en el cliente tienen una estructura en la que podemos diferenciar los siguientes elementos:
- Línea de petición: Es la primera línea de la petición, incluye el método HTTP utilizado (GET, POST…), el path de la url a consultar y la versión del protocolo utilizada.
- Cabeceras de la petición: Contienen todas las cabeceras de la petición HTTP, como puede ser cookies, User-Agent (indica el navegador utilizado por el cliente), Host (indica el servidor remoto), etc.
- Cuerpo de la petición: Este Apartado puede estar incluido (método POST) o no incluirse (método GET, HEAD, OPTIONS).
En caso de encontrarse presente, contiene los parámetros que se han de enviar al servidor para hacer una consulta. En el siguiente ejemplo se envían 2 parámetros (“bookId” y “author”) el servidor recogerá estos parámetros y, dependiendo de la acción indicada en la URL del path, podrá ejecutar una funcionalidad de búsqueda o incluso una funcionalidad de inserción en la base de datos los valores indicados.
- GET: Este método no incluye cuerpo de la petición. La información transmitida a través de los parámetros se envía en la propia dirección URL.
- POST: Este método incluye un cuerpo de la petición. En este cuerpo de la petición HTTP se incluye la información que queremos que procese el servidor. Esta información se puede transmitir en el cuerpo de la petición HTTP de varias maneras como, por ejemplo, mediante el uso de parámetros, datos estructurados en formato JSON o XML o incluso datos binarios como pudiera ser la subida de un fichero o una imagen.
- HEAD: Realiza una petición HTTP igual que realizaría el método GET pero le indica al servidor que sólo quiere obtener las cabeceras de respuesta.
- OPTIONS: Solicita al servidor que le indique los métodos HTTP que acepta.
- PUT: Carga, hace upload de un fichero en el servidor o hace una inserción de información en el servidor.
- DELETE: Borra el recurso o la información indicada.
- TRACE: Le indica al servidor que le muestre en la respuesta todos los datos que le envíes en el mensaje de petición. Se utiliza con fines de depuración.
A continuación se muestran las cabeceras HTTP más comunes:
- Accept: Indica los tipos de contenido que acepta que el servidor le incluya en las respuestas (texto, imágenes, información comprimida, XML, JSON, etc.).
- Accept-Charset: Indica el conjunto de caracteres que se aceptan para que el servidor mande la respuesta con ese conjunto de caracteres establecido (UTF-8).
- Accept-Encoding: Especifica el listado de codificaciones que se aceptan para que el servidor se ajuste a ellas a la hora de componer su respuesta (gzip, deflate).
- Accept-Language: Indica el lenguaje que está utilizando el navegador del usuario (en-US).
- Authorization: Cabecera que puede utilizarse para realizar algún tipo de autenticación (Como la autenticación básica o la autenticación basada en JSON Web Tokens) puede sustituir o complementar a la autenticación vía Identificador de Sesión indicado en una Cookie.
- Cache-Control: Controla la política de cache y si la respuesta que envíe el servidor ha de almacenarse en la caché del navegador.
- Cookie: Almacena cierta información enviada por el servidor previamente para que se incluya en cada petición realizada por el cliente. Normalmente es el mecanismo utilizado para otorgar y transmitir identificadores de sesión, aunque se puede almacenar cualquier información que se considere oportuna.
- Content-Length: El tamaño que ocupa la petición en Bytes.
- Content-Type: El tipo de contenido de la petición, sólo se utiliza cuando el método es POST o PUT para indicar el tipo de contenido que se incluye en el cuerpo de la petición HTTP (imagen, fichero binario, etc.).
- Date: Fecha y hora de la petición.
- Host: Nombre de dominio de host o dirección IP, el uso de esta cabecera es obligatoria a partir de HTTP/1.1(www.example.com).
- Referer: Indica la dirección URL inmediatamente anterior a la petición actual. Es decir, indica desde que path proviene la petición del usuario.
- User-Agent: Indica el navegador y sistema operativo utilizado por el cliente que realiza la petición (Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20100101 Firefox/21.0). El servidor registrara exactamente lo que el cliente manda en esta cabecera en sus solicitudes. Este dato lo puede manipular fácilmente el atacante a través de un proxy web como Burp Suite o ZAP. El ataque consiste en insertar, por ejemplo, código PHP malicioso o comandos que quedará registrado en el log, dando lugar a una ejecución remota de código (RCE) mediante log poisoning o envenenamiento de log.
- Protocolo: Es el protocolo de comunicaciones elegido para la transferencia de información entre el navegador del usuario y el servidor. Normalmente HTTP (protocolo sin cifrar) o HTTPS (Protocolo cifrado).
- Dominio: Representa el dominio al que queremos acceder.
- Port: Indica el número de puerto en el host y va precedido del carácter dos puntos (:). Normalmente se omite, con lo que se toma el puerto por defecto para el protocolo (en caso de http, sería el 80; y en caso de https, el 443).
- Path: Representa la ruta dentro del dominio al que queremos acceder separados por barras (/), normalmente se corresponde con una funcionalidad determinada que ofrece el aplicativo.
- Query: Es el sistema que presenta el protocolo para entregar los datos de entrada a la funcionalidad indicada separados por (?). Se componen del par nombre/valor separados por un delimitador que suele ser (&) o (;), dónde se indican el nombre de las distintas variables de entrada al aplicativo y el valor que toman respectivamente.
- Fragment: Identifica una zona dentro del documento. Va precedido del carácter almohadilla (#) y es opcional.
- Línea de estado: Es la primera línea de la respuesta, incluye el código HTTP que retorna la respuesta del servidor así como un pequeño mensaje de el resultado (OK, Not-Found, Forbidden…) y la versión del protocolo utilizada.
- Cabeceras de la respuesta: Contienen todas las cabeceras de la respuesta HTTP, como puede ser cookies, Servidor (indica el software y versión del servidor), Date (timestamp de la respuesta), etc.
- Cuerpo de la respuesta: Este Apartado puede estar incluido, o no, dependiendo del código de estado HTTP de la respuesta. En caso de incluirse cuerpo de la respuesta, éste puede contener el código HTML de una página web, una imagen o un fichero binario al que hayamos solicitado acceder, e incluso mensajes estructurados como JSON o XML.
La siguiente ilustración detalla las partes de una respuesta HTTP:
- Códigos con estado 1xx: Respuestas informativas, indica que la petición ha sido recibida y se está procesando.
- Códigos con estado 2xx: Respuestas que han sido procesadas correctamente y no retornan ningún tipo de error.
- Códigos con estado 3xx: Respuestas de redirección. Indica que el cliente necesita realizar otra petición a la dirección URL indicada por el servidor en la cabecera de respuesta.
- Códigos con estado 4xx: Errores causados por el cliente. Indica que ha habido un error en el procesado de la operación a causa de que el cliente no ha generado una petición correcta, trata de acceder a un recurso que no existe o para el que no se encuentra autorizado.
- Códigos con estado 5xx: Errores causados por el servidor. Indica que ha habido un error en el procesado de la petición provocado por un fallo en el servidor.
A continuación se muestran las cabeceras de respuesta HTTP más comunes:
- Access-Control: Indica otros dominios que pueden compartir información con el servidor, por ejemplo si se intercambia información con Google analytics.
- Allow: Indica los métodos HTTP soportados por el recurso remoto.
- Cache-Control: Indica la configuración de la cache del navegador para cada recurso accedido en ese aplicativo (por ejemplo, el tiempo máximo que se ha de almacenar la respuesta en el navegador en memoria caché).
- Content-Encoding: Indica que tipo de codificación se está aplicando en los datos incluidos en el cuerpo de la respuesta HTTP.
- Content-Language: Indica el lenguaje utilizado para componer la respuesta (es).
- Content-Lenght: Indica el tamaño de la respuesta en bytes.
- Content-Type: El Tipo Mime de los datos de la respuesta (Content-Type: text/html; charset=utf-8)
- Date: Fecha en la que se generó la respuesta HTTP.
- Expires: Indica el tiempo en el que la respuesta deja de ser válida y se ha de descartar.
- Last-Modified: Indica la última vez que se modificó el recurso en el servidor.
- Location: Se utiliza en los mensajes de redirección (Código de estado HTTP 3xx) para indicar la dirección URL a la que redirigir la navegación del usuario.
- Server: Indica el tipo y versión del Software utilizado en el servidor.
- Set-Cookie: Establece una cookie, indicándole al usuario que la utilice en todas las peticiones HTTP sucesivas contra el mismo recurso.
- Strict-Transport-Security: Fuerza a que el navegador del usuario únicamente se comunique con el servidor mediante el protocolo cifrado HTTP.
- WWW-Authenticate: Indica el tipo de autenticación adicional que se ha de utilizar para acceder al recurso solicitado (Por ejemplo Autenticación Básica o Autenticación vía WebSockets)
- X-Frame-Options: Protección especifica para evitar que la página pueda cargarse en marcos transparentes en otro dominio (Técnica utilizada en phishing)
- X-Powered-By: Especifica la tecnología específica con la que se ha desarrollado la aplicación (X-Powered-By: PHP/5.4.0)
Tipos de autenticación web
En los aplicativos web, existen distintos tipos de autenticación que enumeramos a continuación.
El usuario ha de identificarse con este usuario y contraseña en el aplicativo.
Existen varios tipos de autenticación ligada a la autenticación basada en credenciales. A continuación se enumeran los más importantes.
- Autenticación Básica
HTTP básica es el tipo más simple de autenticación web disponible. Esta forma de autenticación solicita al usuario que inicie sesión con su nombre de usuario y contraseña. Sin embargo, la información se transmite utilizando codificación Base64 a través de una cabecera "Authorization: Basic". Esto significa que la información enviada no se cifra.
En caso de que la información fuera capturada mediante técnicas de Man in The Middle, las credenciales del usuario podrían ser accesibles. Además, esta situación se agrava debido a que las credenciales codificadas se envían en cada petición HTTP.
A continuación se muestra una cabecera de tipo Authorization Basic. Si se decodifica mediante base64 podemos comprobar que las credenciales son usuario "Aladdin" y contraseña "open sesame"
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
- Autenticación Digest
Los protocolos de autenticación Digest funcionan de manera similar a la autenticación básica. El servidor solicita la información de identificación, que es suministrada por el usuario en la forma de un nombre de usuario y una contraseña. El servidor, a continuación, compara las credenciales con lo que está en archivo, y siempre y cuando coincidan, concederá el acceso.
La diferencia primaria con la autenticación de HTTP con protocolo Digest es que la conexión se realiza de una manera segura. Esto es debido a que las contraseñas son almacenadas en la base de datos de usuario en un formato cifrado y se transmiten a través de una cabecera "Authorization: Digest".
De esta manera, la integridad de la contraseña es mucho más segura, ya que sólo puede ser leída por el servidor web.
A continuación se muestra una cabecera Authorization Digest, en este caso no es posible revertir las credenciales de una manera directa.
- Autenticación Basada en Cookies
La autenticación basada en cookies ha sido el método predeterminado (y comprobado) para manejar la autenticación de usuarios durante mucho tiempo. La autenticación basada en cookies presenta un estado de tipo "stateful".
Al iniciar sesión, a través de un formulario de autenticación en el que el usuario envía sus credenciales, el servidor registra datos con el fin de recordar que el usuario se ha identificado correctamente. Estos datos que se registran en el backend, en correspondencia con el identificador de sesión, es lo que se conoce como estado.
El aplicativo le envía al navegador el identificador de sesión generado para identificar al usuario mediante la cabecera de respuesta HTTP "set-cookie". De esta manera el navegador siempre enviará las cookies en cada petición HTTP y, con ellas, el identificador de sesión que le autentica en el aplicativo.
El flujo que sigue este sistema de autenticación tradicional es el siguiente:
- Un usuario ingresa sus credenciales (datos que le permiten iniciar sesión)
- El servidor verifica que las credenciales sean correctas, y crea una sesión (esto puede corresponderse con la creación de un archivo, un registro nuevo en una base de datos, o alguna otra solución server-side)
- Una cookie con el session ID es puesta en el navegador web del usuario
- En las peticiones siguientes, el session ID es comparado con las sesiones creadas por el servidor
- Una vez que el usuario se desconecta, la sesión es destruida en ambos lados (tanto en el cliente como en el servidor)
- Autenticación basada en tokens
En este método, el usuario se identifica al igual que con la autenticación básica, con sus credenciales, nombre de usuario y contraseña. Pero en este caso, con la primera petición de autentificación, el servidor generará un token basado en esas credenciales.
El servidor guarda en base de datos este registro y lo devuelve al usuario para que a partir de ese momento no envíe más credenciales de inicio de sesión en cada petición HTTP. En lugar de las credenciales, simplemente se debe enviar el token codificado en cada petición HTTP.
Por norma general, los tokens están codificados con la fecha y la hora para que en caso de que alguien intercepte el token con un ataque MiTM, no pueda utilizarlo pasado un tiempo establecido. Además de que el token se puede configurar para que caduque después de un tiempo definido, por lo que los usuarios deberán iniciar sesión de nuevo.
A continuación se muestra un ejemplo de la cabecera Authorization cuando se utilizan tokens de tipo JWT para autenticarse en el equipo.
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1NGE4Y2U2MThlOTFiMGIxMzY2NWUyZjkiLCJpYXQiOiIxNDI0MTgwNDg0IiwiZXhwIjoiMTQyNTM5MDE0MiJ9.yk4nouUteW54F1HbWtgg1wJxeDjqDA_8AhUPyjE5K0U
- API Keys
Una clave de API es un token que proporciona un cliente cuando realiza llamadas a una aplicación de tipo API para identificarse. Normalmente es un valor fijo que se entrega al usuario del aplicativo y ha de enviarlo en cada petición contra la API.
Este valor puede enviarse en la petición HTTP de varias maneras:
- En la propia petición cómo si fuera un parámetro HTTP:
GET /something?api_key=abcdef12345
- En una cabecera específica de la petición HTTP:
- A través de una cookie
Con la autenticación de clave API, envía un par clave-valor a la API, ya sea en los encabezados de solicitud o en los parámetros de consulta. Algunas API utilizan claves de API para la autorización.
Las claves API son un secreto que solo el cliente y el servidor conocen. Al igual que la autenticación básica, la autenticación basada en claves API únicamente se considera segura si se usa junto con otros mecanismos de seguridad, como HTTPS/SSL.
Una de sus desventajas, al igual que ocurre con la autenticación de tipo "Basic" es que la API Key no suele cambiar, de tal manera que si esta clave es usurpada, el atacante podría utilizarla hasta que se forzase el cambio de la misma por parte del servidor.
Por ejemplo, es el método más común para autenticarse en los aplicativos web de la administración pública. En los cuales el usuario ha de verificar su identidad mediante un certificado personal emitido por la FNMT o, en su defecto, mediante el certificado que incorpora el DNI electrónico.
- A través de una llamada de teléfono o SMS enviado por el servicio.
- Haciendo uso de una tarjeta inteligente (token) física o virtual.
- Utilizando un dispositivo biométrico.
Este tipo de autenticación puede presentarse tanto a la hora de autenticar a un usuario en el sistema, como a la hora de requerir una autenticación adicional para realizar algún tipo de tarea privilegiada.
Como podréis comprobar, muchas de las pruebas que se aplican son las mismas que podríamos aplicar en las fases de reconocimiento y escaneo, pero esta vez enfocadas a recopilar información del aplicativo e infraestructura.
A continuación, se muestran las pruebas más comunes para recopilar este tipo de información.
Merece la pena recordar los buscadores más utilizados:
- Google: Uno de los buscadores más utilizados, tiene numerosos operadores de búsqueda para realizar búsquedas avanzadas.
- Bing: Buscador de Microsoft. La principal diferencia de este buscador con los demás es que permite realizar búsquedas basadas en direccionamiento IP.
- DuckDuckGo: Al igual que google, también permite utilizar operadores avanzados de búsqueda.
- Shodan: Es un buscador que en vez de indexar páginas web indexa tecnologías y servicios publicados en internet, pudiendo realizar búsquedas por una versión concreta de un determinado software, o por todas las tecnologías de una determinada organización, etc.
- Censys: Este buscador parecido a shodan se utiliza principalmente para buscar dominios que compartan el mismo certificado, o que tengan ciertos datos en el certificado expedido (Empresa, dominio, etc.)
- Archive.org: Este buscador tiene indexadas versiones antiguas de las páginas a lo largo de varios años. De esta manera podremos comprobar tecnologías que se estuvieran utilizando, parámetros de entrada o páginas que aunque no se encuentren enlazadas puedan estar presentes, etc.
Por otro lado, también se recomienda mirar los comentarios que dejan los
desarrolladores en ficheros HTML o JavaScript por si han dejado
información que pudiera ser interesante en estos comentarios.
En algunas ocasiones la respuesta HTTP devuelta por el servidor contiene una cabecera específica “Server” que indica el tipo de servidor utilizado y, en ciertas ocasiones, también la versión del mismo.
Además, al igual que vimos en entradas anteriores, es posible obtener esta información utilizando herramientas como nmap o nessus, que identifican el servidor en el caso que se muestre esta información en la respuesta HTTP o incluso analizando el tipo de respuestas devueltas.
De manera similar, si la aplicación se ha desarrollado en base a un determinado framework de programación, también es interesante intentar obtener el framework y versión utilizada dado que también puede ser susceptible a presentar vulnerabilidades “públicas”.
Para poder obtener esta información se recomienda revisar y analizar las respuestas HTTP devueltas por el servidor dado que esta información puede encontrarse tanto en las cabeceras como en el cuerpo de las respuestas HTTP.
- nc
También conocido como netcat, nc es una herramienta de red que permite, a través de intérprete de comandos y con una sintaxis sencilla, abrir puertos TCP/UDP en un HOST (quedando netcat a la escucha), asociar una shell a un puerto en concreto (para conectarse por ejemplo a MS-DOS o al intérprete bash de Linux remotamente) y forzar conexiones UDP/TCP (útil por ejemplo para realizar rastreos de puertos o realizar transferencias de archivos bit a bit entre dos equipos). Posteriormente fue portada a Windows y Mac OS X entre otras plataformas.
Para poder realizar la conexión simplemente habrá que indicar la dirección IP y el puerto al que se ha de conectar.
$ nc dirección_ip puerto
Una vez realizada la conexión, si queremos que el servidor devuelva el banner del servicio habrá que transmitir datos con la conexión establecida. En el caso de realizar una petición HTTP, el servidor web devolverá la respuesta HTTP en la que podremos comprobar si en las cabeceras de respuesta se puede obtener algún dato del aplicativo o servidor remoto.
- Curl
- -d, --data "<data>": Enviar datos en una petición POST. Si queremos enviar el contenido de un archivo, usamos @archivo para que se lea directamente desde el disco.
- --data-urlencode "<data>": Codifica automáticamente los datos.
- --upload-file: Subir un archivo a un servidor (FTP, SFTP, HTTP PUT si el servidor lo permite, o WebDAV)
- --json "<json>": Enviar datos en formato JSON (si tu versión lo permite).
- -F, --form "<campo=valor>": Enviar como formulario tipo multipart/form-data.
- -X <método>: Especifica el método HTTP (GET, POST, PUT, DELETE, etc).
- -x, --proxy <proxy> <url>: Para usar un proxy.
- -G: Fuerza método GET.
- -I, --head: Muestra solo cabeceras (HEAD).
- -L, --location: Sigue redirecciones.
- -k, --insecure: Ignora errores del certificado SSL.
- --cacert <archivo>: Especifica certificado CA.
- --cert <archivo>: Certificado de cliente.
- --key <archivo>: Clave privada del certificado.
- -u, --user "usuario:contraseña": Autenticación básica.
- --digest: Digest Auth.
- --ntlm: NTLM Auth.
- --negotiate: Kerberos Auth.
- --oauth2-bearer <token>: Token OAuth2.
- -s, --silent: Modo silencioso (sin barra de progreso).
- -v, --verbose: Modo detallado (útil para debug).
- --trace <archivo> / --trace-ascii <archivo>: Registro detallado.
- -b, --cookie "clave=valor": Enviar cookies.
- -c <archivo>: Guardar cookies en archivo.
- --cookie-jar <archivo>: Leer/escribir cookies automáticamente.
- -H "Header: Valor": Añadir cabecera personalizada.
- -A, --user-agent "<UA>": Cambiar el User-Agent.
- -e, --referer "<url>": Establecer el Referer.
- --connect-timeout <segundos>: Tiempo máximo para conectar.
- --max-time <segundos>: Tiempo máximo para toda la operación.
- --retry <intentos>: Reintentos si falla.
- BurpSuite
BurpSuite es uno de los proxies de interceptación HTTP más utilizados. Podemos utilizarlo para inspeccionar las cabeceras de respuesta HTTP al igual que lo hemos hecho con nc.
También podemos utilizar la herramienta a modo de escáner pasivo. La herramienta incorpora varios plugins que realizan ciertas pruebas. Varios de estos plugins inspeccionan las respuestas provenientes del servidor para localizar versiones de aplicativo, versiones de servidor, framework utilizado. o incluso información sensible en comentarios o devuelta en el propio código de la aplicación.
- Whatweb
WhatWeb es una herramienta que trata de identificar todos los componentes y tecnologías utilizados por un aplicativo web.
El funcionamiento consiste en realizar un proceso de spidering (recorre toda la web) y luego analiza toda la información devuelta por el aplicativo.
Dispone de cerca de 1800 plugins distintos para realizar esta tarea de análisis de información.
$ whatweb <url>
- Wappalyzer
- Nessus
Como ya pudimos comprobar, Nessus es la aplicación de escaneo de vulnerabilidades más conocida y utilizada. Podemos utilizarla también sobre un determinado aplicativo y realizará una recopilación de información, tanto del aplicativo como de su infraestructura, además de indicar las posibles vulnerabilidades existentes dependiendo de las versiones.
- CMSMap
Escáner “open source” desarrollado en Python que localiza vulnerabilidades en los CMS (sistema de gestión de contenidos) más populares como son Wordpress, Joomla, Drupal y Moodle. En este caso también se puede utilizar para la recopilación de información dado que es capaz de enumerarte módulos utilizados y versiones de los mismos.
- JoomScan
Escáner “open source” desarrollado en perl y perteneciente al proyecto OWASP. Localiza vulnerabilidades de versión y defectos en la configuración de portales basados en el framework Joomla. En este caso también se puede utilizar para la recopilación de información dado que es capaz de enumerarte módulos utilizados y versiones de los mismos.
- Wpscan
Escáner “open source” desarrollado en Ruby. Localiza vulnerabilidades de versión y defectos en la configuración de portales basados en el framework WordPress. En este caso también se puede utilizar para la recopilación de información dado que es capaz de enumerarte módulos utilizados y versiones de los mismos, usuarios, incluso permite ataques de fuerza bruta para obtener sus contraseñas.
Antes de nada, es importante comentar que si se desea que wpscan haga un análisis de vulnerabilidades, es necesario suministrar una API KEY, que se obtiene tras registrarse en la web de la herramienta, Una vez registrado, se puede acceder a ella en la página de perfil (/profile).
Las opciones principales son:
- --url: dirección url.
- --api-token TOKEN: necesaria para que wpscan haga un análisis de vulnerabilidades.
- -v, --verbose: para que la salida muestre más mensajes de retroalimentación.
- -e, --enumerate [opciones]: para enumerar distintos elementos. La lista de opciones posible es (se pueden indicar varias opciones separadas por comas):
- vp: plugins vulnerables.
- ap: todos los plugins.
- vt: temas vulnerables.
- at: todos los temas.
- cb: config backups.
- p: plugins instalados.
- t: temas instalados.
- u: usuarios validos.
- -P, --passwords: diccionario de contraseñas para extraer credenciales de los usuarios.
- -U, --usernames: permite suministrar una lista de usuarios (separados por comas) o un fichero con nombres de usuarios para tratar de extraer credenciales.
- --random-user-agent: sirve para cambiar automaticamente el User-Agent en cada petición usando uno aleatorio.
- --disable-tls-checks: desactiva las comprobaciones de seguridad TLS/SSL cuando te conectas a un sitio HTTPS
- --plugins-detection <passive/mixed (por defecto)/aggresive>: sirve para contolar como se detectan los plugins instalados.
- --themes-detection <passive/mixed (por defecto)/aggresive>: sirve para contolar como se detectan los temas instalados.
- wfuzz (web fuzzer): es una herramienta escrita en Python muy potente, especializada en fuzzing web, viene preinstalada en kali.
- -c: Muestra la salida en formato de colores, lo cual facilita enormemente la lectura de los resultados en la terminal.
- -u: Es obligatorio y se utiliza para especificar la URL objetivo (target URL) sobre la cual se realizará el escaneo o ataque.
- -t número: Es el número de hilos de ejecución.
- -w diccionario: Para indicar un diccionario con palabras para probar por fuerza bruta.
- -d: Se utiliza para enviar datos en el cuerpo de una petición HTTP (método POST).
- -H: Se utiliza para añadir o modificar cabeceras (headers) HTTP en tus peticiones.
- -L: Sirve para seguir redirecciones HTTP de forma automática.
- -z: Se utiliza para especificar el payload que se inyectará en los marcadores de posición durante el escaneo.
- file: Es el uso más habitual. Lee palabras de un diccionario. Ejemplo: -z file,/ruta/al/diccionario.txt.
- range: Útil para probar IDs de usuario o parámetros numéricos. Ejemplo: -z range,1-100.
- list: Permite pasar una lista de palabras separadas por guiones. Ejemplo: -z list,admin-login-upload.
- --hh: Filtra por tamaño de la respuesta (caracteres).
- --hc: Oculta las respuestas que coincidan con un código de estado específico.
- --hl: Filtra por número de líneas en la respuesta.
- --hw: Filtra por número de palabras.
- Script http-enum de nmap.
- dirbuster: también está incluido en kali. Tiene la gran baza de que puede ser usado con interfaz grafica.
- -u <URL>: URL objetivo (ej. http://10.10.10.10/)
- -l <wordlist>: Ruta del diccionario a usar
- -t <threads>: Número de hilos (ej. 50)
- -e <extensions>: Extensiones separadas por coma (ej. php,html,bak)
- -r: Habilita escaneo recursivo
- -x <archivo>: Guarda resultados en archivo XML
- -S: Usa el método HEAD en lugar de GET (más rápido)
- -q: Modo silencioso (menos salida)
- gobuster: es una herramienta de fuzzing escrita en Go, lo cual es una opción muy interesante ya que este lenguaje es muy eficiente a la hora de implementar sockets y conexiones.
Modos principales:
- dir: Búsqueda de directorios y archivos.
- dns: Enumeración de subdominios.
- vhost: Detección de virtual hosts.
- s3: Enumeración de buckets en Amazon S3.
- fuzz: Ataques de fuzzing simples.
- -u <URL>: Objetivo, por ejemplo: http://10.10.10.10
- -w <archivo>: Wordlist,
- -x <ext>: Extensiones (ej. php,txt)
- -t <num>: Hilos (concurrentes), por ejemplo -t 50
- -o <archivo>: Guardar resultados en un archivo
- -b <códigos>: Excluir ciertos códigos HTTP
- -k: Ignorar errores SSL
- -e: Expande resultados (muestra URLs completas)
- --wildcard: Manejo de respuestas wildcard
- -q: Modo silencioso (quiet)
- --random-agent: Utiliza una cadena de agente de usuario aleatoria.
- --append-domain: Cada entrada del diccionario se convierte en un subdominio completo añadiendo el dominio principal automáticamente, se utiliza en los modos dns y vhost.
- --follow-redirect: Si encuentra un código de redirección (como un 301 o 302), debe seguir esa ruta para ver a dónde lleva.
- dirb: está preinstalada en kali. Está escrita en Python. Quizás es mas lenta que otras herramientas como gobuster o ffuf escritas en Go.
- <URL>: Objetivo, por ejemplo: http://10.10.10.10/
- [wordlist]: Wordlist a usar (si no se indica, usa la por defecto)
- -X <ext>: Extensiones a probar (ej. -X .php,.html,.bak)
- -r: No seguir redirecciones
- -S: Guarda los resultados en un archivo
- -o <archivo>: Archivo donde guardar el output
- -z <delay>: Tiempo de espera entre peticiones (ej. -z 1000ms)
- -t <threads>: Número de hilos (por defecto 10)
- -N: No muestra mensajes de estado
- -v: Salida detallada
- dirsearch.
- -u <URL>: URL objetivo
- -e <ext>: Extensiones a probar (php, html, bak, etc.)
- -w <archivo>: Wordlist a usar
- -t <n>: Número de hilos
- --random-agents: User-Agent aleatorio
- --json-report: Guardar resultado en JSON
- --plain-text-report: Guardar en texto plano
- --full-url: Mostrar URLs completas
- --exclude-status <códigos>: Excluir ciertos códigos HTTP
- --follow-redirects: Seguir redirecciones
- --max-time: Tiempo máximo por solicitud
- ffuf: Está escrita en Go y ofrece un alto rendimiento.
- -u <url>: URL objetivo, debe contener FUZZ (punto de inyección).
- -w <wordlist>: Diccionario/s a usar (-w dic1.txt:HFUZZ -w dic2.txt:WFUZZ).
- -e <extensiones>: Extensiones a añadir, por ejemplo: -e .php,.html,.bak.
- -request: Archivo que contiene la solicitud http sin procesar.
- -mc <códigos>: Filtra por códigos de respuesta HTTP (ej. -mc 200,204) o "all" para todo.
- -fs <bytes>: Filtra respuestas por tamaño (bytes).
- -fc <códigos>: Excluye ciertos códigos (como 403, 404).
- -t <n>: Número de hilos, por defecto 40.
- -o <archivo>: Guardar resultado en un archivo (puede usarse con -of json).
- -of <formato>: Formato de salida: json, html, csv, ecsv, md.
- -v: Modo verbose, muestra más información.
- -H: Encabezado "Nombre: Valor", separado por dos puntos. Se aceptan múltiples indicadores -H.
- -X: Método HTTP a utilizar.
- -d: Datos POST.
- -mode: Modo de operación con múltiples listas de palabras. Modos disponibles: clusterbomb, pitchfork, sniper.
- -s: No imprimir información adicional (modo silencioso).
- feroxbuster: es una herramienta escrita en Rust, potente y rápida con descubrimiento recursivo de directorios.
- -u <URL>: URL objetivo (ej. http://10.10.10.10)
- -w <archivo>: Wordlist a usar
- -x <extensiones>: Extensiones a probar (ej. php,html,bak)
- -t <n>: Número de hilos (default: 50)
- -o <archivo>: Guardar resultados en archivo
- -q: Silencioso, solo muestra resultados válidos
- -k: Ignorar errores de certificado SSL
- -e: Muestra URLs completas
- --depth <n>: Límite de profundidad para escaneo recursivo
- --status-codes <códigos>: Filtra por códigos HTTP (ej. 200,204)
- --filter-status <códigos>: Excluye ciertos códigos
- --timeout <s>: Tiempo de espera por solicitud
- --user-agent <UA>: Define un User-Agent personalizado
- --dont-filter: No filtra duplicados ni contenido repetido
- /usr/share/wfuzz/wordlist/general: Diccionarios de wfuzz de distintas temáticas, incluyendo uno de extensiones de archivos frecuentes.
- /usr/share/dirb/wordlist: Diccionarios instalados con la herramienta dirb.
- /usr/share/dirbuster/wordlist: Diccionarios instalados con la herramienta dirbuster.
Por esta razón, el siguiente subapartado discurre enumerando las distintas pruebas más importantes que se han de realizar a la hora de realizar una auditoría de aplicativo web.
Para ello, utilizaremos la agrupación que recoge la Guía de pruebas en aplicativos web de la fundación OWASP.
Por un lado, mediante los diferentes recursos proporcionados por OWASP, los desarrolladores mejoren el nivel de seguridad de sus aplicaciones aplicando buenas prácticas en el desarrollo de los aplicativos.
Por otro, los auditores o pentesters también pueden hacer uso de sus guías y metodologías para realizar las pruebas de seguridad sobre un determinado aplicativo, así como utilizar las herramientas open source que ofrece la organización.
Los proyectos más destacados de la fundación OWASP son los siguientes:
- OWASP Web Security Testing Guide
Guía especializada que nos indica como afrontar una revisión de seguridad en un aplicativo web. Contiene los conceptos básicos de este tipo de auditorías, así como un resumen y catalogación de las vulnerabilidades más comunes en este tipo de aplicativos. Además, para cada vulnerabilidad incluida se incluye la metodología y pruebas necesarias para comprobar si la vulnerabilidad se encuentra presente en el aplicativo, así como recomendaciones para solucionar la vulnerabilidad.
- OWASP Mobile Security Testing Guide
Similar al anterior, pero orientado a las auditorías de aplicativos móviles. Contiene los conceptos básicos de este tipo de auditorías, así como un resumen y catalogación de las vulnerabilidades más comunes en este tipo de aplicativos. Además, para cada vulnerabilidad incluida se incluye la metodología y pruebas necesarias para comprobar si la vulnerabilidad se encuentra presente en el aplicativo así como recomendaciones para solucionar la vulnerabilidad.
Dado que la comunicación que se realiza entre el aplicativo móvil y el servidor se realiza mediante tecnologías propias de un aplicativo Web (normalmente la comunicación se realiza mediante el uso de API web) la guía se centra más en vulnerabilidades dependientes de la plataforma (Android e iOS) y para las vulnerabilidades que pudieran afectar al servidor nos apoyaríamos en la “Web Security Testing Guide”
- Zed Attack Proxy (ZAP)
Como desgranamos en la siguiente entrada, ZAProxy es un aplicativo tipo proxy web open source utilizado para realizar las pruebas necesarias para comprobar la existencia de las vulnerabilidades descritas en la guía “Web Security Testing Guide”.
- OWASP Top Ten – OWASP Mobile Top Ten
Proyecto que identifica y clasifica las vulnerabilidades más críticas que pueden producirse en los aplicativos web y aplicativos móviles respectivamente.
- OWASP Code Review Guide
Guía especializada que contiene un conjunto de “Mejores prácticas de programación” para evitar introducir vulnerabilidades, de tipo web, a la hora de desarrollar los aplicativos.
- Paneles de administración expuestos
En ciertas ocasiones los aplicativos web disponen de un acceso administrativo a través de un panel de administración, el cual permite realizar acciones privilegiadas dentro de la aplicación. En algunos casos, estas interfaces de administración no disponen de los controles de protección necesarios y son susceptibles de presentar vulnerabilidades que pudieran ocasionar un acceso no permitido.
Este tipo de pruebas tratan de descubrir paneles de administración que puedan ser accesibles de manera pública en internet.
Para poder comprobar si existe un panel de administración expuesto podemos hacer uso de las siguientes técnicas:
- Enumeración de ficheros y directorios (fuerza bruta con listado de posibles paths de administración).
- Búsqueda de paneles de administración en motores (Google Dorks).
- Buscar urls y enlaces en el código fuente del aplicativo (html y JavaScript).
- Si el aplicativo tiene como base una aplicación conocida o está desarrollado en un framework específico es posible consultar la documentación para comprobar si existe algún acceso administrativo por defecto.
- Comprobar si existe algún panel de administración en algún otro puerto TCP que preste servicio bajo los protocolos HTTP/HTTPS.
- Acceso a ficheros expuestos o no referenciados
De la misma manera, también se puede dar el caso de acceder a ciertos ficheros no referenciados por la aplicación (mediante funcionalidades directas o hipervínculos), pero que pertenezcan a la misma y se encuentren accesibles de manera pública. Por ejemplo, ficheros de Backup de versiones anteriores de la aplicación, ficheros de logs, ficheros de configuración que muestren información sensible en los parámetros de configuración e incluso credenciales de autenticación para interconectar distintos componentes de la aplicación (Gestores de Identidad, Bases de Datos, etc.).
Las siguientes técnicas nos pueden ser de utilidad para localizar este tipo de ficheros. Como se puede comprobar, muchas de las técnicas ya han sido descritas y únicamente habrá que modificar el enfoque de la información a buscar.
- Enumeración de ficheros y directorios (fuerza bruta con listado de posibles paths y nombres y extensión de ficheros).
- Búsqueda de ficheros específicos (como los ya mencionados) en motores (Google Dorks).
- Buscar urls y enlaces en el código fuente del aplicativo (html y JavaScript).
- Gestión de roles
- Enumeración de usuarios
- Acceso directo a la parte privada
- Modificación de parámetros
- Predicción del identificador de sesión
- Inyección SQL en el formulario de acceso a la aplicación
- Uso del protocolo HTTP
- Aplicativo disponible bajo HTTP y HTTPS
- Envío de la información mediante el protocolo cifrado HTTPS pero con el método GET
El método HTTP GET se caracteriza por que no dispone de cuerpo de la petición HTTP y los parámetros necesarios son transmitidos en la propia dirección URL. En el caso de que se esté enviando la información a través del protocolo cifrado HTTPS, la información transmitida se encontrará protegida ante ataques de tipo Man in The Middle. Sin embargo, al transmitirse esta información en la propia URL queda expuesta en el historial del navegador web utilizado y en los log del servidor web que sustenta el aplicativo.
La siguiente ilustración muestra la captura de una petición transmitida por HTTPS pero que expone las credenciales del usuario en la propia dirección URL:
En caso que los administradores del aplicativo no hayan modificado las credenciales de estas cuentas por defecto, un atacante podría acceder al aplicativo utilizando estas cuentas que suelen ser cuentas de administración o similar.
Para poder comprobar el uso de credenciales por defecto podemos utilizar las siguientes técnicas:
- Realizar búsquedas específicas en internet para averiguar las credenciales por defecto de los aplicativos afectados.
- Realizar búsquedas en los manuales del aplicativo base o en el repositorio del mismo (en caso de ser un aplicativo open source).
- Utilizar diccionarios de credenciales por defecto junto con una herramienta de fuerza bruta (el propio proxy de interceptación Burp Suite te permite automatizar esta tarea).
- Comprobar la información que se requiere para resetear la password
- Comprobar cómo se comunica la nueva contraseña al usuario
- Al resetear la contraseña se muestra directamente al usuario la nueva contraseña para autenticarse.
- Se establece una contraseña temporal y se fuerza al usuario a modificarla en el siguiente inicio de sesión.
- Se envía un correo electrónico al usuario con un enlace para realizar el cambio de contraseña.
- Combinar Mayúsculas, minúsculas, números y caracteres especiales.
- Longitud mínima de 8 caracteres.
- No debe contener ningún dato del usuario (username, nombre, apellidos)
- En la medida de lo posible, que no utilice palabras de uso común (no siempre es posible)
- Comprobar si se puede acceder a un determinado recurso, aunque no se haya realizado el proceso de autenticación o nos hayamos autenticado con un usuario que no debería tener privilegios de acceso al recurso indicado.
- Comprobar si se puede acceder a una determinada funcionalidad del aplicativo, aunque no se haya realizado el proceso de autenticación o nos hayamos autenticado con un usuario que no debería tener privilegios de acceso a la funcionalidad indicada.
- Manipulación del grupo de usuario
- Manipulación de la dirección IP de origen
- Referencias inseguras a objetos de manera directa (IDOR)
- Secure: Atributo que fuerza al navegador del usuario a transmitir la cookie únicamente a través del protocolo HTTPS. De esta manera se evita que se pueda forzar al usuario a transmitir esta cookie mediante HTTP y que pueda ser interceptada mediante ataques de Man in The Middle (ataque ssl-strip).
- HttpOnly: Atributo que especifica que la cookie no puede ser transmitida a través de scripts de cliente. Es decir, no se puede extraer la cookie a través de ordenes JavaScript y por tanto no se podría robar el identificador de sesión utilizando ataques de tipo Cross Site Scripting (este tipo de ataques se detallarán más adelante)
- Domain: Atributo que indica el dominio en el cual la cookie es válida y por lo tanto a los dominios a los que será enviada la cookie. Por ejemplo, si nuestro aplicativo se encuentra en un dominio de tipo cloud como azure https://www.mi_applicacion.azure.com si restringimos el dominio de nuestra cookie de sesión a todo el dominio *.azure.com obligaremos al navegador del usuario a entregar este identificador de sesión a cualquier aplicación dentro del dominio azure.com. En caso que el usuario visitara algún otro aplicativo alojado en el dominio de Azure también se transmitiría el identificador de sesión de nuestro aplicativo al aplicativo de otro dominio.
- Path: Muy similar al atributo anterior, pero en este caso se restringe el path en el cual la cookie es utilizada. Por ejemplo, es muy común en cierto tipo de ISP gratuitos que te ofrecen un alojamiento web en un determinado path del dominio del ISP. Por ejemplo https://sites.ucm.es/aplicativo en este caso cada departamento de la universidad tiene un path distinto en el que cuelgan su aplicativo web. En caso de no restringir el path al correspondiente al de nuestro aplicativo estaremos enviando nuestra cookie (con nuestro identificador de sesión) a cualquier aplicativo dentro del dominio sites.ucm.es (o incluso ucm.es dependiendo del valor del atributo domain), pero no a otros dominios con el mismo path.
- Expires: Indica la fecha en la cual el navegador del usuario deja de utilizar esta cookie. Es una manera de eliminar la cookie de la caché del navegador, aunque si el servidor tiene un tiempo de validez del identificador de sesión más amplio, el identificador seguiría siendo válido, lo único que el navegador del usuario legítimo ya habría descartado ese identificador de sesión y no lo enviaría a la aplicación.
- Códigos de error
- Información en el cuerpo del mensaje
- Tienda Online en la que puedes adquirir productos y un atacante localiza una vulnerabilidad mediante la que no es necesario pagar por ellos (o pagar una cantidad inferior).
- Aplicativo que dispone de códigos de fidelización con descuentos y un atacante puede generar los códigos desde la aplicación.
- Aplicación Bancaria en la cual un atacante puede evitar que le cobren comisiones por realizar operaciones bancarias.
- Aplicación Bancaria en la que un atacante puede realizar una transferencia con un importe negativo y el importe es abonado en su cuenta desde la cuenta del destinatario.




















