Hola a todos!
Me llamo Andrey Durante 10 años he estado buscando vulnerabilidades en varios servicios web. y listo para compartir mi conocimiento contigo. En mayo pasado, hice un informe sobre esto en la conferencia de
Heisenbug , y ahora estoy listo para compartir mi conocimiento aquí, también, en los espacios abiertos de Habr. Entonces comencemos.
Una vez
encontré una vulnerabilidad en los servidores de la famosa empresa Facebook. Los chicos olvidaron actualizar ImageMagick (la biblioteca de procesamiento de imágenes) y lo pagaron :) Con este ejemplo, quería mostrar que todos somos humanos y que todos podemos cometer errores, sin importar en qué compañías y en qué puestos trabajamos. El único problema es que estos errores pueden conducir a todo tipo de riesgos.
Cuanto más complicada sea su aplicación / sitio web / herramienta, más probable es que algo salga mal.
Debe verificar las vulnerabilidades. Es una tontería no hacer esto en absoluto.
Los siguientes elementos pueden ser etapas de verificación de aplicaciones web:
- Preparación:
- Definir puntos de entrada, de hecho, de dónde pueden venir los datos en la aplicación;
- Identificar stock de tecnología;
- Determine qué vulnerabilidades tiene sentido verificar;
- Verificación Debe verificar todas las vulnerabilidades que se aplican al alcance de la tecnología de su aplicación web;
- Análisis de código. No seas perezoso, no te saltes este artículo. En algunos casos, sin acceso al código, es difícil encontrar vulnerabilidades, y esto también le permite omitir el filtrado que puede estar incrustado en su aplicación.
Hablaré de todo esto en detalle.
Entonces, preparación. No me enfocaré en todos los tipos de vulnerabilidades, de lo contrario, la cantidad de texto en el artículo excederá todos los tamaños imaginables e inconcebibles. Le aconsejo que comience a aprender de la
lista de los 10 proyectos principales de OWASP . Cada pocos años,
el consorcio OWASP forma una lista de las vulnerabilidades más relevantes en este momento. Consideraremos algunos de ellos en detalle.
Xss
XSS (cross-site scripting) es un ataque a un usuario que permite a un atacante ejecutar un script arbitrario en el contexto del navegador de su víctima. Muy a menudo, implica la implementación de etiquetas
HTML y scripts
JS .
Ejemplo: en un momento existió dicho servicio
Yahoo! Ad Exchange El formulario de recuperación de contraseña tenía un parámetro "
URL de retorno ". Podría indicar a qué página volver después del proceso de restablecimiento de contraseña. Si inserta uno u otro vector allí que conduce a la ejecución del código
JS , puede obtener todas las
cookies del usuario. Analizaremos cómo sucede esto y por qué.

Aquí está el vector en sí. Todo a la vez:

Para realizar una inyección, debe salir del contexto de la variable en la que estábamos por defecto (por defecto, esto es lo que asumió el programador cuando escribió el código).
A continuación se muestra el valor original. Este es un comportamiento válido.

Vemos que returnURL = / login.jsp
Esto cae dentro del valor de la
etiqueta <input> .
Si agregamos una comilla después de
jsp , veremos que se ha vertido la sintaxis
HTML . Afortunadamente, el lenguaje
HTML no es estricto, el analizador saltará y no habrá problemas:

Agrega otro personaje. Aquí estamos completamente fuera del contexto de la
etiqueta <input> :

Ahora agregamos la apertura de la
etiqueta <svg> y obtenemos dos etiquetas válidas en términos de sintaxis:

A continuación, agregue todo el vector de ataque:

En este caso, se dibuja la imagen
svg . Usando el controlador
JavaScript "
onload ", ejecutamos una alerta con las
cookies del documento. Eso es todo! El atacante recibió tus
cookies .
Si en la prueba mostramos solo la alerta en sí, no será difícil para un atacante enviar cookies a un servidor controlado por él y, en el peor de los casos, incautar su cuenta. Veamos cómo se ve de nuevo:

También hay más vectores de ataque en el cliente. Daré algunos ejemplos con una breve descripción. Pero primero debe comprender cómo salir del contexto:
- Fuera de contexto. Estos 6 caracteres ayudarán a salir no solo del contexto del valor del parámetro HTML, sino también de muchos otros:
-> '">
Bueno, de hecho, los dos vectores de ataque más simples:
- Insertar enlaces en particular. Pero en el caso general: cambiar la apariencia de la página. Por ejemplo, pueden incrustar código html en su página y mostrar una ventana falsa pidiendo datos:

La cadena " aaaa " apunta a google.com . Puede ver que el enlace se representa en la página, pero es posible que no lo vea, pero esto no cancela su presencia en el código. En ambos casos, el caso puede considerarse completado; - Ejecución de script, por ejemplo, interceptando cookies de usuario:

¿Dónde y cómo buscar XSS?
Primero, encuentre las funciones de salida de información / datos en la página. ¿Analizar qué datos llegan allí? Aquí viene el concepto de una
fuente no confiable . Y tal, en primer lugar, es
su usuario . Los vectores de ataque pueden estar contenidos en cualquier otra fuente: fuentes RSS, otros servicios, tanto externos como internos.
Aquí hay un ejemplo de la vida real: trabajo para SEMrush IT. Estamos desarrollando una plataforma en línea, que es una herramienta universal para los vendedores en línea. Entonces, un servicio guardó datos, el otro dedujo, cada uno de los equipos se basó el uno en el otro, resultó que en el segundo servicio
XSS surgió debido a la falta de procesamiento adecuado de los datos de salida, y el primer comando no consideró necesario filtrar los datos entrantes. de ninguna manera y los mantuvo "
tal cual ". Conclusión: si no sabe cómo se almacenan estos o esos datos, deben considerarse no confiables. O acuerde de antemano quién almacena y cómo, filtros, muestra datos.
Si ya tiene datos de fuentes no confiables, le recomiendo:
- Para estudiar el filtrado de datos entrantes;
- Examina el contexto de la salida. No en todos los casos, XSS puede ejecutarse, incluso en ausencia de filtrado. Por ejemplo, si el tipo de contenido de la respuesta es: text / plain;
- No confíe en el filtrado de marcos de sistemas de seguridad integrados.
Inyección SQL
Implementación de código SQL (inyección SQL en inglés) : la introducción en la consulta de la base de datos de instrucciones que no estaban implícitas allí.
Ejemplo (no de la vida, sino también bueno):
Vemos un script que muestra una tabla de usuario. En este caso, puede buscar por nombre de usuario.
A la derecha se muestra cómo se ve la consulta a la base de datos, y a la izquierda es el resultado de la secuencia de comandos en el navegador.

Además, para probar y obtener al menos algún resultado primario, insertamos dos comillas en el valor del parámetro de nombre. Sencilla y doble:

Vemos que desde el punto de vista de la salida, todo se vino abajo, la tabla desapareció por completo. La solicitud también obtiene las 2 comillas adicionales. Se viola toda la sintaxis de la consulta
SQL .
Si tomamos y agregamos dicha construcción al valor del parámetro (
ed .: Mire en el cuadro amarillo ), obtenemos una solicitud absolutamente válida. El resultado de la página es completamente idéntico a la primera solicitud, que no incluía una inyección:

Para verificar completamente que hay una vulnerabilidad, agregamos un deuce en lugar de la unidad:

Resulta que la solicitud se vuelve falsa, desde el punto de vista de la lógica booleana y, como resultado, no contiene datos. Sin embargo, a diferencia del momento en que tuvimos un error, tenemos la salida de la tabla misma.
Para no enumerar todo lo que puede estar en diferentes motores de base de datos y consultas de diferentes tipos, he reducido todo a una línea:

Esto es algo que puede intentar ingresar en el parámetro y luego, de acuerdo con las diferencias en las respuestas, intente comprender lo que está sucediendo, ¿hay una vulnerabilidad o no? Alrededor del 80% de los casos que puede cubrir con esta manipulación.
Queda un 20% de situaciones difíciles en las que no le dará ninguna información, por ejemplo: consultas / filtros anidados, etc. En mi práctica, me encontré con una persona similar solo una vez. Luego tuve que evitar el filtrado en el lado del servicio.
¿Cuál es el peligro en SQL?
- De lo obvio: fuga de información . Si un atacante pudo generar consultas a sus bases de datos, de una forma u otra puede obtener valores que no estaban destinados a la salida (hashes de contraseñas, direcciones de clientes, etc.);
- Cambio de datos . Ahora muchos desarrolladores usan bases de datos a través de sistemas ORM . Estos sistemas, por defecto, le permiten hacer múltiples consultas a la vez, la sintaxis SQL también le permite hacer esto. Si hay una vulnerabilidad, todo puede volverse no solo a la selección de datos, sino también a su cambio (hasta eliminar tablas, cambiar la estructura de la base de datos, etc.).
En la misma situación, es posible un aumento de los privilegios del usuario. Cambie los campos en ciertas tablas (por ejemplo, coloque is_admins = true en la base de datos de usuarios ) y aumente sus derechos al administrador; - DoS . En algunos casos, una inyección puede conducir a una denegación de servicio. Se generan varias consultas pesadas a la base de datos, se inician en varios subprocesos y su servicio puede dejar de funcionar por algún tiempo;
- Leer los archivos del sistema es otro desastre que la inyección SQL puede traer. La aparición de este riesgo depende del sistema de base de datos que utilice, así como del usuario que trabaje con él (privilegiado o no);
- RCE (Remote Code Execution) es ejecución de código. Depende directamente del tipo de base de datos que se use (anteriormente esto era posible de forma predeterminada, con la configuración predeterminada de la base de datos, en MSSQL).
La siguiente tabla muestra las vulnerabilidades en la consulta
SQL . Por supuesto, no necesitas memorizarlo. Además, estas no son todas las opciones posibles, sino simplemente ejemplos. Solo preste atención al hecho de que los lugares donde puede ocurrir la inyección en la consulta
SQL si llegan datos sin procesar están resaltados en rojo. Un atacante experimentado puede encontrar una manera de explotar esto. Ten cuidado y atento.

SSRF (falsificación de solicitudes del lado del servidor)
Traducción literal: solicitudes falsas en el lado del servidor. Es decir, un ataque que le permite manipular los datos que envía a la aplicación, lo que le obliga a realizar la solicitud no a donde la lógica de negocios originalmente se planeó.
El funcionamiento de
SSRF se muestra en la imagen a continuación:

Hay un atacante, está su servidor, que está cerrado por el
cortafuegos , pero al mismo tiempo hay una funcionalidad que le permite realizar solicitudes en nombre del servidor.
Si esta funcionalidad no está debidamente protegida y / o de manera incorrecta, como suele suceder :), procesa los datos entrantes, el atacante puede recurrir a
Memcached ,
Redis u obtener acceso a los recursos internos de la víctima.
Para un ejemplo más ilustrativo, considere el soporte que SEMrush utiliza para la capacitación interna de los empleados.
Es importante prestar atención al significado de la "
URL de Avatar ":

Aquí prestamos atención a 2 puntos:
- URL del avatar en sí
- y la capacidad de descargarlo usando un archivo.
Tenga en cuenta que el campo "
Avatar URL " es un campo de texto para la entrada, lo que significa que podemos manipular este valor. Intentemos poner el avatar, quizás, la imagen más famosa en Internet: Googlebot de la página de
error 404 .
Hazlo una vez:

Haga dos veces, haga clic en "
Guardar ". Tenemos un robot en lugar de mi foto:

Aquí vale la pena prestar atención al hecho de que el valor de la "
URL del avatar " ha cambiado, a alguna ruta local; aparentemente, la aplicación solicitó una imagen, la guardó en el servidor y sustituyó un nuevo valor.
Seguimos adelante. En el campo "
Avatar de URL ", ingrese el
archivo de valor
: /// etc / passwd . Este diseño le permite acceder a la estructura del archivo. En algunas bibliotecas que solían trabajar con
HTTP , de manera predeterminada, el trabajo con la estructura de archivos está activado y recibe datos de los servidores en los que se iniciaron:

¿Qué sucede después de hacer clic en el botón "
Guardar "? ..
En primer lugar, la imagen se convirtió en "
murciélago ", y en segundo lugar, la ruta del archivo cambió.

Si intentamos solicitar esta imagen en el navegador, no nos mostrarán nada (el archivo está "
roto "). Pero no somos el primer día en seguridad de la información, sabemos qué hacer :) Mediante simples manipulaciones obtenemos el contenido del archivo en nuestra computadora:

Por lo tanto, con la ayuda de esta vulnerabilidad, yo, como atacante, puedo obtener todos los códigos fuente de su servicio y otros datos disponibles para leer al usuario que ejecuta el servicio web.
Veamos los peligros de la SSRF:
- Escaneo de puertos. Para una red externa, su servicio es un punto de entrada y 2 puertos (http y https). Al escanear puertos desde el interior de su infraestructura, un atacante puede detectar puertos abiertos;
- Omitir la autenticación basada en host. Cual es el punto? Es posible que dentro de su estructura haya servicios que estén disponibles solo para ciertos recursos (lea: Lista blanca de IP). Por lo tanto, si su servidor vulnerable está en la lista blanca, obtiene acceso a los servicios que están disponibles para él y, como resultado, puede manipularlos;
- Continuando con el desarrollo del ataque antes mencionado, puede continuar explotando los programas vulnerables que se ejecutan en la intranet o en el servidor local. Muy a menudo hay situaciones en las que la infraestructura interna, inaccesible desde el exterior, está mal monitoreada (las versiones / parches de seguridad, etc. no siempre se actualizan). Esto también puede conducir a ataques y robo de datos;
- Lectura de datos locales. Lo mostré arriba con un ejemplo. Sus configuraciones se pueden leer y acceder, tokens y contraseñas.
¿Dónde buscar SSRF?
Esta no es una vulnerabilidad estándar. Se puede encontrar en diferentes, a menudo en los lugares más inesperados. En esta situación, la técnica "mira aquí, pero quizás ni siquiera mires aquí" no funciona.
Señales de un posible
SSRF :
- Webhook Si están mal configurados, si Firewall está configurado incorrectamente en aquellos servidores desde los cuales Webhooks realiza solicitudes, se puede obtener una vulnerabilidad;
- Conversión HTML Intente incrustar una construcción de URL <iframe> , <img> , <base> , <script> o CSS que apunte a un servicio interno;
- Descargar archivos borrados . ¿Recuerdas el ejemplo de avatar? Cuando un usuario tiene la oportunidad de cargar datos por URL al servidor, esto conlleva grandes problemas. Intente enviar la URL con el puerto y vea qué contenido se carga.
¿Cómo buscar SSRF?
XXE (entidad externa XML)
Comenzaré la historia, como siempre con un ejemplo, para que quede más claro:
En el servicio SEMrush mencionado anteriormente, existe una herramienta que se ocupa del análisis de contenido. El usuario conduce en la URL de su sitio o de un sitio de la competencia y, antes de analizarlo, el servicio descarga este mismo contenido. Mira cómo sucede esto en el video:
Para descargar, el servicio accede al sitio especificado y el rastreador descarga el archivo
sitemap.xml . Y este es el mismo
XML del que estamos hablando en este bloque.
En el video, podemos observar cómo el sitio atacante agregó una definición de la entidad externa
XXE a
sitemap.xml , que apunta a "
file: /// etc / hosts ". En los sistemas Linux, este es un archivo que describe qué IP corresponde a los hosts si no hay registros
DNS para ellos.
A continuación, el atacante indica en la
etiqueta <loc> la expansión de esta variable. Después de analizar el
XML, después de procesar todo el
XML en el compartimento, insertará el valor que estaba en "
archivo: /// etc / hosts " en la variable de
ubicación (resaltada en rojo en el video).
El atacante inicia el lanzamiento de nuestro analizador, va a los registros y aquí aparece una línea resaltada en blanco en el video. Este es el contenido del archivo "
archivo: /// etc / hosts " obtenido en la solicitud
GET en los registros de un servidor controlado por él.
Que sigue El atacante verificará que tenía razón. Cambiará el nombre del archivo a "
file: /// etc / fstab ", ejecutará el analizador nuevamente y obtendrá estadísticas sobre los procesos en ejecución.
Y finalmente: "
file: /// etc / hostname ", inicie el analizador, vaya a los registros y obtenga el
nombre de host de la máquina en la que estamos.
Este es un error real descubierto por una persona real que no está relacionada con nuestra empresa. Tuve que rociar ceniza en mi cabeza y pagar dinero :)
Otro ejemplo de
XXE :

Supongamos que tenemos un cierto
punto final , se llama:
example.com/xxe .
Le enviamos la estructura
XML → en
XML declaramos la entidad
→ la entidad
se refiere al archivo del sistema
/ etc / passwd y se abre más en el cuerpo de la respuesta → obtenemos el contenido de este archivo en respuesta.
Vale la pena señalar que esto no ocurre tan a menudo como nos gustaría.
Por que funciona
Los documentos
XML son un formato de datos estructurados que, entre otras cosas, le permite describir los tipos de datos que pueden contener utilizando una etiqueta
DOCTYPE especial.
Definición del tipo de datos (DTD) : la definición de los tipos de datos dentro de este documento
XML . Hay tres opciones sobre cómo se puede hacer esto:
- Si el documento es compatible con DTD . El siguiente ejemplo muestra algunos XML en los que hay una estructura de pedido, hay un elemento de producto y un elemento de conteo (presumiblemente: el número de inventario del producto y el número de artículos en el pedido). El orden es el padre de estos dos elementos:

- DTD externos en el servidor local.
Hacemos lo mismo que en la primera realización, pero hacemos todas las definiciones en un archivo separado, que se encuentra en el servidor local:

- DTD externos en un servidor de terceros:

Si es un lector atento, probablemente haya correlacionado el hecho de que la capacidad de hacer tales solicitudes en su servicio y solicitar esquemas de
DTD externos es una vulnerabilidad en sí misma, de lo que hablamos anteriormente, es decir, la vulnerabilidad
SSRF .
Una ocurrencia común: los desarrolladores corrigen la vulnerabilidad
XXE , pero olvidan prohibir el procesamiento de
DTD externos y obtener
SSRF . De esto no se derivarán consecuencias fatales, pero no debe olvidarse de ello.
¿Qué son las entidades en XML?
Entidades en
XML . Que es esto Esta es una oportunidad para definir ciertos valores y convertirlos en variables. Las entidades tienen tres tipos diferentes:
Predefinido : predefinido. De manera similar al código
HTML , es posible utilizar aquellos caracteres que forman parte de la sintaxis del lenguaje, como una estructura de texto. Aquí se dan como ejemplo, para que entiendas de qué se trata. Sí, en la mayoría de los ataques no se usan, pero pueden ser necesarios en algunos casos excepcionales.
General y
Parámetros . Este es uno y el mismo, solo cambia la sintaxis de su declaración y cómo pueden llamarse después de la declaración
¿Dónde buscar XXE ?
Varias opciones:
- Procesamiento de XML en cualquier manifestación:
- Convierte HTML a otros formatos;
- Manejo de docx , xlsx y formatos similares.
¿Cómo buscarlos?

La imagen muestra solo un ejemplo desde el cual comenzar. No es una clave universal. Debe optimizarse para los formatos que utiliza en el servicio en estudio.
Lo primero que hacemos: declarar una determinada entidad
Z , que accede al host controlado por el host atacante, lo expande dentro del cuerpo del documento
XML .
Aquí la segunda opción es posible: solo la esencia del
parámetro . Difiere del primer anuncio (signo de
% ). Y para volver a esta esencia, el cuerpo del documento ya no es necesario. Podemos acceder a él directamente en la estructura
DOCTYPE y exponer esta entidad:

El tercer escenario es ver si la capacidad de solicitar
DOCTYPE de servicios externos está activada o desactivada:

A continuación, observamos la salida de un servidor controlado por nosotros. Si vemos una llamada a
URL / verificación desde varias direcciones
IP , significa que con un alto grado de probabilidad la vulnerabilidad ha pasado, y luego solo tenemos que descubrir cómo obtener datos más interesantes para nosotros.

¿Cuál es el peligro de
XXE ? Escribiré brevemente y punto por punto:
- Lectura de archivos locales;
- Acceso a recursos locales;
- Escaneo de puerto / host
- Contenedores de texto sin formato . Esta es una oportunidad para acceder a sus servicios que operan en el protocolo de texto sin formato;
- Ejecución remota de código (no es frecuente). Está desactivado por defecto;
- DoS . Debido al hecho de que las entidades se pueden concatenar, es posible obtener fácilmente un aumento exponencial en la cantidad de memoria ocupada por estos parámetros. El resultado es un ataque de mil millones de risas . En otras palabras, simplemente está sobrecargando la memoria del servidor atacado.
En conclusión, diré que todo esto (el artículo y cualquier conocimiento que haya adquirido) no tiene sentido sin una aplicación práctica. Por lo tanto, le preguntaré acerca de una bagatela real: piense en la aplicación que escribió / probó ayer e intente verificar si hay vulnerabilidades. ¿Hay formularios de entrada o procesamiento
XML ? ¿Esta aplicación está protegida? ¿Se ha agregado el filtrado y la
DTD está deshabilitada?
Abra el manual de
SQLmap y descubra cómo verificar su aplicación con él. Si no encuentra nada, tome otra herramienta y examínela, y luego pruebe su aplicación para detectar otras vulnerabilidades. Como dije al principio, el artículo examina solo algunas vulnerabilidades, pero
miles de ellas .
No creo que puedas escribir un código absolutamente seguro. Siempre hay vulnerabilidades,
todavía no las ha encontrado .