Business Logic Vulnerabilities
Esta sección trata sobre los defectos en la logica de negocios que conllevan a vulnerabilidades que los atacantes o pentester pueden tomar a favor para explotación a posteriori.
Last updated
Esta sección trata sobre los defectos en la logica de negocios que conllevan a vulnerabilidades que los atacantes o pentester pueden tomar a favor para explotación a posteriori.
Last updated
En esta sección hablaremos sobre el concepto de falla logica de negocios dentro de una aplicación.
Refleja todos los fallos logicos que se superponen por el usuario sin tenerlo presente, vamos a estudiar a detalle el concepto más adelante.
Las vulnerabilidades de logica empresarial son aquellos huecos de una aplicación cuando no se implementa correctamente un diseño o la implementación en si de una aplicación que llevan a comportamientos no deseados o no esperados de la aplicación en si misma, y que a su vez se puede prestar para los atacantes lograr cometidos legitimos en la aplicación aprovechando la falla de logica empresarial.
En este contexto, el término "lógica de negocios" simplemente se refiere al conjunto de reglas que definen cómo opera la aplicación.
La verdad es que los fallos logicos suelen ser invisibles en si mismo para los usuarios corrientes que usan el aplicativo de forma normal como cualquier otro usuario, y estos por lo general no generan fallos logicos porque por lo general son partes de la aplicación que se testean mucho por lo desarrolladores.
Porque aqui uno como atacante o pentester intentará jugar con la aplicación de formas que ni los usuarios ni los desarrolladores intentaron, como por ejm: Codificar la salida de un archivo en la url para probar un path traversal en lugar de cargar X archivo, todo eso desde un proxy receptor como BurpSuite, claro eso llevará tal vez a fallos logicos si la aplicación no es del todo robusta.
Crear las restricciones y reglas necesarias definidas en la aplicación para evitar problemas o fallos no esperados ni deseados.
Las restricciones y reglas se deben cumplir siempre, para tener una seguridad integra en la aplicación X.
Las reglas son basicamente los estatutos o parametros que se supone debe sostener y seguir la aplicación para determinados escenarios o acciones por parte del usuario en el aplicativo, esto con el fin de evitar acciones mal intencionadas o negativas en la aplicación que solo perjudicarían y pondrían en riesgo la seguridad de la aplicación.
Los fallos en la lógica pueden permitir a los atacantes eludir estas reglas. Por ejemplo, es posible que puedan completar una transacción sin pasar por el flujo de trabajo de compra previsto. En otros casos, la validación rota o inexistente de los datos proporcionados por el usuario podría permitirles realizar cambios arbitrarios en valores críticos para transacciones o enviar información sin sentido. Al pasar valores inesperados a la lógica del lado del servidor, un atacante puede potencialmente inducir a la aplicación a hacer algo que no debería hacer.
La verdad es que las fallas logicas empresariales o de negocios suelen ser muy diversas y el encontrar una en una aplicación depende mucho del contexto de la aplicación, el dominio empresarial y que por sobre todo el conocimiento humano especifico para poder lograrlo, es por ello que los escaneres automatizados en estos casos no aplican mucho y por ello está tan presente con los Bug Hunters.
Para no darle mucha vuelta a esto, surgen cuando no se piensa correctamente en como es el funcionamiento en conjunto de todos los modulos funcionales de X aplicación, cuando eso pasa se producen fallos logicos.
Ahora bien, los desarrolladores tienen un papel muy importante aqui y es que las vulnerabilidades surgen cuando los desarrolladores no piensan ni ven correctamente el funcionamiento en conjunto de todo el aplicativo, tanto que para ellos mismos es complejo de entender toda la aplicación, y esto por lo general es así en aplicaciones complejas que tienen muchas muchas lineas de codigo las cuales se dividen por desarrolladores, uno se encargan de ‘x’ modulo del codigo, los otros de ‘y’ modulo, entonces claro así el uno del otro no van a saber lo de su codigo mismo y puede llegar a producir el problema que se habla.
En este caso los desarrolladores deben documentar cada linea de codigo propia para que otros cuando la vean y analicen para implementar lo correspondiente a ellos sepan y entiendan de que trata lo anterior para poder implementarlo con lo de ellos mismos.
Para este caso realmente el impacto es muy iterable y variable, ya que dependiendo de la falla logica en conjunción con la funcionalidad de la aplicación que resulta vulnerable a un fallo de logica entonces de ese mismo modo será el impacto.
Si por el ejm el impacto de falla logica afecto la funcionalidad de Autenticación, pues con todo el dolor del mundo el impacto será bastante grave respecto a la seguridad de la aplicación.
Pero, si por ejm el impacto de falla logica afectó la funcionalidad de la transacción para los pagos desde la aplicación haciendo que se pueda bypassear el pago, pues en este caso el impacto tambien será muy grave respecto a los fondos y la economía de la aplicación misma.
También debe tener en cuenta que, aunque las fallas lógicas no permitan que un atacante se beneficie directamente, aún podrían permitir que una parte malintencionada dañe el negocio de alguna manera.
En resumen, las claves para prevenir vulnerabilidades en la lógica de negocios son:
Asegúrese de que los desarrolladores y evaluadores comprendan el dominio al que sirve la aplicación.
Evite hacer suposiciones implícitas sobre el comportamiento del usuario o el comportamiento de otras partes de la aplicación.
Debe identificar qué suposiciones ha hecho sobre el estado del lado del servidor e implementar la lógica necesaria para verificar que se cumplan estas suposiciones. Esto incluye asegurarse de que el valor de cualquier entrada sea razonable antes de continuar.
También es importante asegurarse de que tanto los desarrolladores como los evaluadores puedan comprender completamente estas suposiciones y cómo se supone que debe reaccionar la aplicación en diferentes escenarios. Esto puede ayudar al equipo a detectar fallas lógicas lo antes posible. Para facilitar esto, el equipo de desarrollo debe cumplir con las siguientes mejores prácticas siempre que sea posible:
Mantenga documentos de diseño y flujos de datos claros para todas las transacciones y flujos de trabajo, anotando cualquier suposición que se haga en cada etapa.
Escriba el código lo más claramente posible. Si es difícil entender lo que se supone que debe suceder, será difícil detectar fallas lógicas. Idealmente, un código bien escrito no debería necesitar documentación para comprenderlo. En casos inevitablemente complejos, producir documentación clara es crucial para garantizar que otros desarrolladores y evaluadores sepan qué suposiciones se están haciendo y exactamente cuál es el comportamiento esperado.
Tenga en cuenta cualquier referencia a otro código que utilice cada componente. Piense en los efectos secundarios de estas dependencias si una parte malintencionada las manipulara de una manera inusual.
Debido a la naturaleza relativamente única de muchos fallos lógicos, es fácil descartarlos como un error único debido a un error humano y seguir adelante. Sin embargo, como hemos demostrado, estos fallos suelen ser el resultado de malas prácticas en las fases iniciales de creación de la aplicación. Analizar por qué existía una falla lógica en primer lugar y cómo el equipo la pasó por alto puede ayudarlo a detectar debilidades en sus procesos. Al realizar ajustes menores, puede aumentar la probabilidad de que fallas similares se eliminen en el origen o se detecten antes en el proceso de desarrollo.
Estos ejemplos pueden no llegar a estar dentro de la lista de laboratorios de logica empresarial, sin embargo hay algunos otros que si están dentro de la lista, el objetivo es aprender, así que todo debe ser bienvenido (esto solo era aclaración para mi mismo).
⚠️ En esta sección, veremos ejemplos de algunos errores típicos que cometen los equipos de diseño y desarrollo y le mostraremos cómo pueden conducir directamente a fallas en la lógica empresarial. Ya sea que esté desarrollando sus propias aplicaciones o auditando las existentes, puede aprovechar las lecciones aprendidas de estos ejemplos y aplicar el mismo pensamiento crítico a otras aplicaciones que encuentre.
Ejemplos de fallas lógicas incluyen:
Este tipo de confianza supone que los creadores de la aplicación web o desarrolladores llegasen a sostener y suponer que los usuarios solo llegarán a interactuar con la aplicación de forma interactiva desde la web, además de que no se toma en cuenta la validación adecuada del lado del cliente para evitar datos maliciosos en la entrada a proposito.
Con esto en cuenta, debemos tener presente que si no se toman medidas estrictas para evitar ello, claramente se podría hacer algo al respecto, con herramienta como Burp Proxy, o burpSuite facilmente podemos llevar a cabo la toma de los datos de un usuario X y como no se valida la procedencia ni nada por el estilo antes de llegar del lado del servidor, tomamos los datos, los modificamos e ingresamos data maliciosa con el fin de obtener algo en especifico.
Es por ello que es tan importante tener en cuenta la validación de los inputs de los usuarios y por sobre todo los controles de acceso que tienen ellos dentro de la aplicación del lado del cliente.
Realmente lo que se puede lograr depende mucho en sí de la funcionalidad que se logré vulnerar, pero como tal además de ello de lo que pueda lograr hacer con los datos controlables por parte del user, todo esto en el contexto adecuado puede lograr un fallo gravisimo para la aplicación como tal y la X compañia dueña de la aplicación.
En las aplicaciones se debe mantener un estandar ante ciertos parametros de entrada en la aplicación, por ejm una app puede manejar datos de entrada de tipo entero para la cantidad de elementos en un carrito de compras, sin embargo ese entero matematicamente puede tener valores de +1000 caracteres o simplemente puede ser negativo -1-2-3-4 etc… y eso logicamente pues no es correcto, en estos casos se supone se debe regir la aplicación por parametros con ciertos limites, para el caso del carrito de compras con la cantidad se debe mantener una cantidad maxima dependiendo de la disponibilidad de items que haya POR EJM.
Y de esta forma es como se debe seguir está logica para poder llevar a cabo una seguridad en cuanto a la logica, ahora bien a esto se le llama mantener una logica empresarial adecuada.
En resumen los desarrolladores debemos mantener un claro presente de los diversos escenarios que pueden haber para así mismo de esa forma crear las posibles rutas de comportamientos que debería llevar a cabo la aplicación en esos casos especificos.
Consideremos una transferencia de fondos entre dos cuentas bancarias. Es casi seguro que esta funcionalidad comprobará si el remitente tiene fondos suficientes antes de completar la transferencia:
Pero si la lógica no impide lo suficiente que los usuarios proporcionen un valor negativo en el amount
parámetro, un atacante podría aprovechar esto para evitar la verificación del saldo y transferir fondos en la dirección "incorrecta". Si el atacante envió $1000 a la cuenta de la víctima, esto podría resultar en que reciba $1000 de la víctima. La lógica siempre evaluaría que -1000 es menor que el saldo actual y aprobaría la transferencia.
Preguntas claves que podemos hacer en esos momentos especificos cuando tomamos BURP y analizamos las peticiones para ver posibles fallos en las peticiones de las aplicación, con registro de comentarios, formularios, etc.
En esos casos debemos responder a las preguntas especificas para ver hasta que punto podemos llegar a lograr encontrar una vulnerabilidad de logica empresarial, las cuales son:
¿Hay algún límite que se imponga a los datos?
¿Qué pasa cuando alcanzó esos límites?
¿Se está realizando alguna transformación o normalización en su entrada?
¿Hay alguna respuesta inusual/diferente con X entrada diferente “maliciosa”?
Esto puede exponer una validación de entrada débil que le permite manipular la aplicación de maneras inusuales. Tenga en cuenta que si encuentra un formulario en el sitio web de destino que no maneja de forma segura entradas no convencionales, es probable que otros formularios tengan los mismos problemas.
Veamos a continuación otro ejemplo más detallado de lo que se debe seguir para poder tener presente, el como se involucra la vulnerabilidad logica a bajo nivel.
Vamos con otro laboratorio de entrenamiento más:
Una de las causas más grandes y comunes de la generación de fallas comunes de vulnerabilidades lógicas es hacer suposiciones erradas sobre el posible comportamiento de un usuario, tanto que uno como desarrollador crea toda una aplicación con todo su esquema de comportamiento logico tomando a consideración comportamientos posiblemente errados, que luego pueden ser explotados por un atacante en su defecto (uno de atacante).
Las aplicaciones parecen hacerse ver seguras implementando medidas de seguridad “seguras” para los etapas comerciales de un usuario dentro de una aplicación, el problema es que muchas veces suponen que se pueden relajar luego de que ya se ha aceptado al usuario como de “confianza” porque ya paso los controles estrictos de seguridad y dejan atrás los datos del usuario que luego de pasar los controles de seguridad pueden llegar a ser potencialmente peligrosos sino se cuida la etapa post control seguridad, en estos casos esos usuarios de confianza no siempre seguirán siendo dignos de confianza tal cual como el titulo.
⚠️ Si las reglas comerciales y las medidas de seguridad no se aplican de manera consistente en toda la aplicación, esto puede generar lagunas potencialmente peligrosas que pueden ser aprovechadas por un atacante.
En estos casos pasa cuando un usuario puede que proporcione lo que una pagina exige que se ingrese sin embargo un usuario que puede ser un potencial usuario puede llegar a romper estas reglas y modificar, testear o hasta borrar diversos parametros todo con el fin de los comportamientos que puede llegar a tener la aplicación antes esos cambios diferentes que se presentan en la aplicación.
Además se debe tener en cuenta que los parametros del lado del servidor están conectados logicamente a funcionalidades logicas en el server por ello, la presencia o ausencia de un parametro en la aplicación correspondrá a un comportamiento especifico de la aplicación.
Es importante si se van a eliminar los parametros, cada parametro uno por uno para observar que efecto tiene en la respuesta y de esa forma ir analizando para entender, entonces pasos:
Eliminar solo un parametro a la vez para garantizar que se alcancen todas las rutas de codigo relevantes.
Eliminar tanto el nombre del parametro como el valor en si, normalmente el servidor manejará cada eliminada de manera diferente, ya que una cosa es el nombre del parametro y otra diferente el valor del parametro.
Seguir los procesos de cada etapa hasta su finalización, ya que realmente no sabemos si la eliminada de x parámetro antes nos pueda servir para un paso más adelante teniendo un efecto directo, así que ello nos servirá en nuestro flujo de trabajo.
⚠️ Esto se aplica tanto a la URL como
POST
a los parámetros, pero no olvides comprobar también las cookies. Este sencillo proceso puede revelar algún comportamiento extraño de la aplicación que puede ser explotable.
Vamos a ver esto a detalle en el siguiente Lab:
Esto es algo que pasa muy frecuentemente y es que los usuarios uno parece creer que seguirán al pie de la letra el flujo de movimiento de una aplicación pero a veces hacen las cosas como no deben hacer por simple ignorancia o un atacante con motivos de explotación.
En estos casos es sumamente peligroso el hecho de que se pueda explotar el omitirse un paso tan importante como el 2FA porque significa que la aplicación finalmente no valida nada de lo que le ingresamos.
Es evidente que hacer suposiciones no trae nada bueno, el comportamiento de una aplicación no se supone que se debería “suponer” sino más bien tener presente y con hechos como se comporta, pero en fin, en el caso en el que solo sean suposiciones facilmente se podría replicar un evento e intentar llevarlo por otra vía o camino diferente testeandolo desde Burp Repeater para probar diferentes parametros o entradas con el fin de analizar la response y encontrar nuevas respuestas encontrando nuevos vectores de ataque o directamente Vulns.
Basta con testear las solicitudes GET o POST desde el repetidor para encontrar nuevas rutas de ataque o disclosure information, etc.
Toca pensar en las suposiciones erradas de los desarrolladores para poder encontrar los fallos logicos de la aplicación y por ende la superficie de ataque.
Con toda esta información ya podriamos pensar en como violentar los datos o vulnerabilidades que hayamos encontrado.
Es realmente de suma importancia tener presente los mensajes que llegue a presentar la aplicación ante los diversos escenarios que vamos a generar al momento de testear la aplicación, porque pueden ser una valiosa fuente de divulgación de información, que pueden llegar ayudarnos a ajustar nuestro ataque y comprender detalles claves sobre el comportamiento del backend.
Vamos a ver un poco más a detalle con un laboratorio facultativo:
En este caso vamos a ver como podemos omitir la autenticación de inicio de sesión en user, que ingresa como wiener pero intentaremos omitirlo para saltar a iniciar como admin y eliminar al user carlos.
Aqui venimos a vernos expuestos con algo muy claro y es que las aplicaciones de por si en algun punto tienen sus vulnerabilidades o ciertas cosas que no vemos màs alla pero se pueden interpretar como fallas logicas y es en estos casos cuando debemos tomar presente esto para intentar encontrar las fallas determinadas.
Por ejm: pongamos el contexto de una aplicación que aplica descuentos de productos que se compren luego de que pase el saldo total de $1000
y está bien esa es la estrategia de la aplicación, el problema viene un poco más dado cuando por ejm: la aplicación no toma en cuenta los posibles escenarios en los cuales se puede añadir o eliminar productos a gustos luego de haber tomado el descuento, ¿que pasa si se eliminan productos el saldo total < 1000 y aún así sigue aplicando el descuento? En esos casos es importante tener en cuenta esto y actuar de forma defensiva, estás son las cosas que uno como desarrollador tal vez no tomar presente, pero un atacante si y ve mucho más allá.
En estos casos es importante cuando podemos ver que algoritmos utiliza la aplicación, como actua, como se comporta ante ciertos escenarios.
Con ver no me refiero a verlos así sencillito, toca analizar, ver y volver a analizar la aplicación para poder entender como es su flujo de proceso intentando comprender como es que funciona la aplicación.
Esto para el caso en los que son dominios que son un poco familiares para nosotros, pero cuando no lo sean 😮 →
Nos encontraremos con dominios que nada tienen que ver con lo que conozcamos o no sean familiar para nosotros, en estos casos debemos leer toda la documentación que sea necesaria para poder comprender el dominio (aplicación), y pode llegar a entender un poco más para llevar a cabo las acciones, pero eso sería en algunos casos, en otros casos puede que nos toqué hablar con desarrolladores (si tenemos la oportunidad) que sepan del tema o les sea familiar todo con el fin de poder obtener sus opiniones para poder comprender totalmente o parcialmente la aplicación.
Habrán dominios que parecerán ser muy oscuros, y cuanto más oscuro sea, es más probable que más evaluadores hayan pasado por alto muchos errores, así que eso nos dará mucha más oportunidad a nosotros.
Vamos a ver más a detalle un lab para intentar comprender esto:
Ahora vamos a ver un laboratorio para completar la falla o vulnerabilidad del flujo de trabajo en el proceso de compra de un producto, con la falla “dinero infinito ∞”
Este suele ser uno de los ataques que nos permite a nosotros como atacantes lograr obtener información certera e importante sobre una aplicación, ya sea en estructura interna, algoritmos implementados (de cifrado Asimetrico, simetrico), etc…
Ahora bien no todo esto puede ser así de la nada, se necesita una buena implementación además de que para gestar un ataque por oraculo de cifrado primero se debe mantener una conexión dual entre ciertos inputs de la aplicación que se interconectan entre sí y nos permiten sacar información uno de otro mediante cifrado.
¿Que es un oracle?
Oracle es un sistema o entidad que responde a consultas sobre datos cifrados/privados sin revelar información sensible.
Entonces un Ataque de Oracle →
Vendría siendo la forma en como se obtiene información de datos sensibles y privados de forma NO autorizada mediante el análisis de las respuestas del sistema a consultas especificas.
Ataque Oracle por cifrado →
Un ataque entonces de Oráculo por cifrado vendría siendo el poder obtener información privada pero manipulando datos cifrados y jugando con ellos analizando las posibles respuestas/comportamientos y con ello haciendo conexiones y deducciones sobre el sistema.
Ejemplo Numérico:
Supongamos que el mensaje cifrado original es un número entero. El atacante, mediante el análisis de respuestas del servidor, descubre que el bit más significativo del número es correcto. Luego, ajusta el mensaje cifrado para inferir el siguiente bit y continúa este proceso hasta descifrar todo el número.
Vamos a ver un ejemplo un poco más practico para terminar de comprender este concepto →
discrepancia en el analizador de correo electronico:
Algunos sitios web analizan las direcciones de correo electrónico para extraer el dominio y determinar a qué organización pertenece el propietario del correo electrónico. Si bien este proceso puede parecer sencillo en un principio, en realidad es muy complejo, incluso para direcciones válidas que cumplen con la RFC.
Las discrepancias en la forma en que se analizan las direcciones de correo electrónico pueden socavar esta lógica. Estas discrepancias surgen cuando distintas partes de la aplicación manejan las direcciones de correo electrónico de manera diferente.
Un atacante puede aprovechar estas discrepancias utilizando técnicas de codificación para ocultar partes de la dirección de correo electrónico. Esto le permite crear direcciones de correo electrónico que pasan las comprobaciones de validación iniciales pero que la lógica de análisis del servidor las interpreta de forma diferente.
El principal impacto de las discrepancias en el analizador de direcciones de correo electrónico es el acceso no autorizado. Los atacantes pueden registrar cuentas utilizando direcciones de correo electrónico aparentemente válidas de dominios restringidos. Esto les permite obtener acceso a áreas sensibles de la aplicación, como paneles de administración o funciones de usuario restringidas.
Documento tecnico sobre la explotación: https://portswigger.net/research/splitting-the-email-atom
Muy buen paper, lo voy a procesar bien bien para entenderlo y explotar.
https://datatracker.ietf.org/doc/html/rfc2822#section-3.2.3
Todos los caracteres que metió →
UUCP
→ Unix to Unix copy “Era para enviar mensajes entre sistemas unix” de hace como unos 35/40 años.Naturalmente, tuve que hacer un seguimiento con un dominio de Colaborador diferente para asegurarme de que realmente iba a un servidor diferente:
El ejemplo anterior va al dominio de colaborador "oastify.com" y no a example.com cuando se utiliza Sendmail 8.15.2. Esto me resultó muy interesante porque demostré que esta investigación realmente iba a alguna parte. El siguiente paso fue encontrar otros caracteres que causaran este comportamiento, así que escribí un fuzzer SMTP bastante rápido. Descubrí que Postfix no tenía este comportamiento porque es más seguro, ¿verdad? Bueno, eso es lo que pensé hasta que encontré una variación en Postfix 3.6.4 a través del fuzzer:
¡Esto es una locura! ¡Los correos electrónicos ahora pueden tener UTF-7! Entonces se me ocurrió una idea: si existe la codificación Q y los conjuntos de caracteres, ¿es posible tener ambos? La sorprendente respuesta a esta pregunta es un rotundo sí. ¡Se puede combinar UTF-7 con la codificación Q!
Después de eso, comencé a experimentar con la codificación base64 porque, por supuesto, "encoded-word" la admite en los correos electrónicos. Simplemente, usa "b" en lugar de "q" en el tipo de codificación y podrás usarla.
El ejemplo anterior utiliza la cadena codificada en base64 "foobar" que el analizador decodifica. Sé lo que estás pensando o tal vez sea solo yo, pero sí, puedes usar datos codificados en UTF-7 y base64:
https://datatracker.ietf.org/doc/html/rfc2047#section-2
https://datatracker.ietf.org/doc/html/rfc2822#section-3.2.3
https://datatracker.ietf.org/doc/html/rfc2822#section-3.2.5
expert:
Eso es todo gracias por leerme nos vemos en una proxima, chaus! :)
Por ello es tan importante testear y no suponer como se debería comportar la aplicación, sino tener construida y presente como se maneja la aplicación correctamente, en este caso, si por EJM: un aplicación no testea el 2FA de un user que ingresa su username, password y correo de verificación para ingresar a la app pero antes de ello llega un code de verificación al email para verificar, pero, ¿que pasa si ni siquiera es necesario digitar el code? uno puede bypassearse esa pagina y llegar directamente a simplemente ingresar como el laboratorio que hicimos en
En realidad, esto va a psres.net, no a example.com, y utiliza otro protocolo arcaico llamado . Las rutas de origen permiten utilizar una cadena de servidores para enviar correo. La idea era separar cada host con una coma y luego incluir el destino final al final. También existe lo que se denomina el "truco del porcentaje", en el que el programa de correo convierte el % o un carácter diferente elegido en el símbolo arroba y luego reenvía el correo electrónico al servidor. Este ejemplo lo ilustra:
Encontré varios sitios con este comportamiento y todos tenían algo en común: Ruby. Parecía que todos usaban el mismo Ruby Gem llamado "Mail", que tiene más de 508 millones de descargas. Empecé a buscar en el código fuente y descubrí que la biblioteca estaba . En mi banco de pruebas intenté reproducir esto: