hacktricks/pentesting-web/race-condition.md

346 lines
26 KiB
Markdown
Raw Normal View History

# Condición de Carrera
2023-06-05 18:33:24 +00:00
![](<../.gitbook/assets/image (9) (1) (2).png>)
\
Utiliza [**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks) para construir y automatizar fácilmente flujos de trabajo con las herramientas comunitarias más avanzadas del mundo.\
Obtén acceso hoy mismo:
2023-06-05 18:33:24 +00:00
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
<details>
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
* ¿Trabajas en una **empresa de ciberseguridad**? ¿Quieres que tu **empresa sea anunciada en HackTricks**? ¿O quieres tener acceso a la **última versión de PEASS o descargar HackTricks en PDF**? ¡Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
* Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Obtén el [**oficial PEASS & HackTricks swag**](https://peass.creator-spring.com)
* **Únete al** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sígueme** en **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Comparte tus trucos de hacking enviando PRs al** [**repositorio de hacktricks**](https://github.com/carlospolop/hacktricks) **y al** [**repositorio de hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
2023-06-05 18:33:24 +00:00
</details>
## Explotando la Condición de Carrera
2023-06-05 18:33:24 +00:00
El principal problema de abusar de las RC es que necesitas que las solicitudes se procesen en paralelo con una diferencia de tiempo muy corta (generalmente >1ms). En la siguiente sección, se proponen diferentes soluciones para hacer esto posible.
2023-06-05 18:33:24 +00:00
<figure><img src="../.gitbook/assets/image (5) (1).png" alt=""><figcaption></figcaption></figure>
2023-06-05 18:33:24 +00:00
### Ataque de un solo paquete (HTTP/2) / Sincronización del último byte (HTTP/1.1)
2023-06-05 18:33:24 +00:00
HTTP2 permite enviar **2 solicitudes en una sola conexión TCP** (mientras que en HTTP/1.1 deben ser secuenciales).\
El uso de un solo paquete TCP elimina por completo el efecto del jitter de la red, por lo que esto claramente tiene potencial para ataques de condición de carrera también. Sin embargo, **dos solicitudes no son suficientes para un ataque de carrera confiable** gracias al **jitter del lado del servidor** - variaciones en el tiempo de procesamiento de las solicitudes de la aplicación causadas por variables incontrolables como la contención de la CPU.
2023-06-05 18:33:24 +00:00
Pero, utilizando la técnica de '**sincronización del último byte**' de HTTP/1.1, es posible enviar previamente la mayor parte de los datos reteniendo un fragmento pequeño de cada solicitud y luego 'completar' **20-30 solicitudes con un solo paquete TCP**.
2023-06-05 18:33:24 +00:00
Para **enviar previamente la mayor parte de cada solicitud**:
2023-06-05 18:33:24 +00:00
* Si la solicitud no tiene cuerpo, envía todas las cabeceras, pero no establezcas la bandera END\_STREAM. Retén un marco de datos vacío con END\_STREAM establecido.
* Si la solicitud tiene un cuerpo, envía las cabeceras y todos los datos del cuerpo excepto el último byte. Retén un marco de datos que contenga el último byte.
2023-06-05 18:33:24 +00:00
A continuación, **prepárate para enviar los marcos finales**:
2023-06-05 18:33:24 +00:00
* Espera 100 ms para asegurarte de que se hayan enviado los marcos iniciales.
* Asegúrate de que TCP\_NODELAY esté desactivado: es crucial que el algoritmo de Nagle agrupe los marcos finales.
* Envía un paquete de ping para calentar la conexión local. Si no haces esto, la pila de red del sistema operativo colocará el primer marco final en un paquete separado.
2023-06-05 18:33:24 +00:00
Finalmente, envía los marcos retenidos. Deberías poder verificar que llegaron en un solo paquete utilizando Wireshark.
2023-06-05 18:33:24 +00:00
{% hint style="info" %}
Ten en cuenta que esto **no funciona para archivos estáticos** en ciertos servidores, pero como los archivos estáticos no son relevantes para los ataques de condición de carrera. Pero los archivos estáticos son irrelevantes para los ataques de RC.
{% endhint %}
2023-06-05 18:33:24 +00:00
Utilizando esta técnica, puedes hacer que 20-30 solicitudes lleguen al servidor simultáneamente, sin importar el jitter de la red:
<figure><img src="../.gitbook/assets/image (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
**Adaptándose a la arquitectura objetivo**
Vale la pena señalar que muchas aplicaciones se encuentran detrás de un servidor frontal, y estos pueden decidir reenviar algunas solicitudes a través de conexiones existentes hacia el backend, y crear conexiones nuevas para otras.
2023-06-05 18:33:24 +00:00
Como resultado, es importante no atribuir el tiempo inconsistente de las solicitudes al comportamiento de la aplicación, como mecanismos de bloqueo que solo permiten que un solo hilo acceda a un recurso a la vez. Además, el enrutamiento de solicitudes del servidor frontal se realiza a menudo por conexión, por lo que es posible que puedas suavizar el tiempo de las solicitudes realizando un calentamiento de conexión en el lado del servidor, **enviando algunas solicitudes inconsecuentes a través de tu conexión antes de realizar el ataque** (esto es simplemente enviar varias solicitudes antes de comenzar el ataque real)).
#### Mecanismos de bloqueo basados en sesiones <a href="#session-based-locking-mechanisms" id="session-based-locking-mechanisms"></a>
Algunos frameworks intentan evitar la corrupción accidental de datos mediante el uso de algún tipo de **bloqueo de solicitud**. Por ejemplo, el módulo de controlador de sesión nativo de **PHP solo procesa una solicitud por sesión a la vez**.
Es extremadamente importante detectar este tipo de comportamiento, ya que de lo contrario puede ocultar vulnerabilidades fácilmente explotables. Si notas que todas tus solicitudes se están procesando de manera secuencial, intenta enviar cada una de ellas utilizando un token de sesión diferente.
#### **Abuso de límites de velocidad o recursos**
Si el calentamiento de la conexión no marca ninguna diferencia, hay varias soluciones para este problema.
2023-06-05 18:33:24 +00:00
Usando Turbo Intruder, puedes introducir un breve retraso en el lado del cliente. Sin embargo, como esto implica dividir tus solicitudes de ataque reales en varios paquetes TCP, no podrás utilizar la técnica de ataque de un solo paquete. Como resultado, en objetivos con alta variabilidad, es poco probable que el ataque funcione de manera confiable, independientemente del retraso que establezcas.
<figure><img src="../.gitbook/assets/image (2) (1) (1).png" alt=""><figcaption></figcaption></figure>
En su lugar, es posible que puedas resolver este problema abusando de una característica de seguridad común.
Los servidores web a menudo **retrasan el procesamiento de las solicitudes si se envían demasiado rápido**. Al enviar una gran cantidad de solicitudes falsas para provocar intencionalmente el límite de velocidad o de recursos, es posible que puedas causar un retraso adecuado en el lado del servidor. Esto hace que el ataque de un solo paquete sea viable incluso cuando se requiere una ejecución retrasada.
<figure><img src="../.gitbook/assets/image (3) (1) (1).png" alt=""><figcaption></figcaption></figure>
{% hint style="warning" %}
Para obtener más información sobre esta técnica, consulta el informe original en [https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine)
{% endhint %}
#### Ejemplos de ataque
* **Tubo Intruder - Ataque de un solo paquete HTTP2 (1 punto final)**: Puedes enviar la solicitud a **Turbo Intruder** (`Extensiones` -> `Turbo Intruder` -> `Enviar a Turbo Intruder`), puedes cambiar en la solicitud el valor que deseas forzar por **`%s`** como en `csrf=Bn9VQB8OyefIs3ShR2fPESR0FzzulI1d&username=carlos&password=%s` y luego seleccionar **`examples/race-single-packer-attack.py`** del menú desplegable:
<figure><img src="../.gitbook/assets/image (4) (1).png" alt=""><figcaption></figcaption></figure>
Si vas a **enviar diferentes valores**, puedes modificar el código con este que utiliza una lista de palabras del portapapeles:
```python
passwords = wordlists.clipboard
for password in passwords:
engine.queue(target.req, password, gate='race1')
```
{% hint style="warning" %}
Si la web no admite HTTP2 (solo HTTP1.1), utiliza `Engine.THREADED` o `Engine.BURP` en lugar de `Engine.BURP2`.
{% endhint %}
* **Tubo Intruder - Ataque de un solo paquete HTTP2 (Varios endpoints)**: En caso de que necesites enviar una solicitud a 1 endpoint y luego múltiples solicitudes a otros endpoints para desencadenar la RCE, puedes modificar el script `race-single-packet-attack.py` de la siguiente manera:
```python
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=1,
engine=Engine.BURP2
)
# Hardcode the second request for the RC
confirmationReq = '''POST /confirm?token[]= HTTP/2
Host: 0a9c00370490e77e837419c4005900d0.web-security-academy.net
Cookie: phpsessionid=MpDEOYRvaNT1OAm0OtAsmLZ91iDfISLU
Content-Length: 0
'''
# For each attempt (20 in total) send 50 confirmation requests.
for attempt in range(20):
currentAttempt = str(attempt)
username = 'aUser' + currentAttempt
# queue a single registration request
engine.queue(target.req, username, gate=currentAttempt)
# queue 50 confirmation requests - note that this will probably sent in two separate packets
for i in range(50):
engine.queue(confirmationReq, gate=currentAttempt)
# send all the queued requests for this attempt
engine.openGate(currentAttempt)
```
* También está disponible en **Repeater** a través de la nueva opción '**Enviar grupo en paralelo**' en Burp Suite.
* Para **limit-overrun**, simplemente puedes agregar la **misma solicitud 50 veces** en el grupo.
* Para **connection warming**, puedes **agregar** al **principio** del **grupo** algunas **solicitudes** a alguna parte no estática del servidor web.
* Para **retrasar** el proceso **entre** el procesamiento **de una solicitud y otra** en 2 pasos de subestado, puedes **agregar solicitudes adicionales entre** ambas solicitudes.
* Para un RC de **multi-endpoint**, puedes comenzar enviando la **solicitud** que **va al estado oculto** y luego **50 solicitudes** justo después de ella que **explotan el estado oculto**.
<figure><img src="../.gitbook/assets/image (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
### Raw BF
Antes de la investigación anterior, estos eran algunos payloads utilizados que intentaban enviar los paquetes lo más rápido posible para causar un RC.
* **Repeater:** Consulta los ejemplos de la sección anterior.
* **Intruder**: Envía la **solicitud** a **Intruder**, establece el **número de hilos** en **30** dentro del menú **Opciones** y selecciona como payload **Cargas útiles nulas** y genera **30**.
* **Turbo Intruder**
2023-06-05 18:33:24 +00:00
```python
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)
2023-06-05 18:33:24 +00:00
def handleResponse(req, interesting):
table.add(req)
2023-06-05 18:33:24 +00:00
```
* **Python - asyncio**
La biblioteca `asyncio` de Python es una biblioteca de programación asíncrona que permite escribir código concurrente utilizando la sintaxis `async/await`. Proporciona una forma sencilla de escribir programas que realizan operaciones de entrada/salida de manera eficiente y no bloqueante.
La programación asíncrona es especialmente útil en situaciones en las que se necesita realizar múltiples tareas simultáneamente, como en el caso de las pruebas de penetración web. Una técnica común utilizada en las pruebas de penetración web es la condición de carrera, que aprovecha las condiciones de ejecución concurrente para obtener acceso no autorizado a recursos protegidos.
La condición de carrera ocurre cuando múltiples hilos o procesos intentan acceder y modificar un recurso compartido al mismo tiempo. Si no se implementan mecanismos adecuados de sincronización, esto puede llevar a resultados inesperados y potencialmente a vulnerabilidades de seguridad.
En el contexto de las pruebas de penetración web, la condición de carrera puede ser explotada para realizar acciones no autorizadas, como acceder a datos confidenciales o modificar configuraciones. Por ejemplo, si un sitio web permite a los usuarios modificar su perfil, un atacante podría aprovechar una condición de carrera para modificar el perfil de otro usuario y obtener acceso no autorizado a su cuenta.
La biblioteca `asyncio` de Python proporciona herramientas para manejar la concurrencia y evitar condiciones de carrera. Al utilizar `asyncio`, los programadores pueden escribir código que se ejecuta de manera concurrente sin preocuparse por los problemas de sincronización.
En resumen, `asyncio` es una biblioteca poderosa para la programación asíncrona en Python, que puede ser utilizada en las pruebas de penetración web para evitar condiciones de carrera y mejorar la eficiencia de las operaciones de entrada/salida.
2023-06-05 18:33:24 +00:00
```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
2023-06-05 18:33:24 +00:00
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)
2023-06-05 18:33:24 +00:00
asyncio.run(main())
```
## **Metodología de RC**
### Límite-desbordamiento / TOCTOU
Este es el tipo más básico de condición de carrera donde se presentan vulnerabilidades en lugares que limitan la cantidad de veces que se puede realizar una acción. Como usar el mismo código de descuento varias veces en una tienda web. Un ejemplo muy fácil se puede encontrar en [este informe](https://medium.com/@pravinponnusamy/race-condition-vulnerability-found-in-bug-bounty-program-573260454c43) o en [este error](https://hackerone.com/reports/759247).
Existen muchas variaciones de este tipo de ataque, que incluyen:
- Canjear una tarjeta de regalo varias veces
- Calificar un producto varias veces
- Retirar o transferir dinero en exceso de su saldo de cuenta
- Reutilizar una solución CAPTCHA única
- Bypass de un límite de velocidad anti-fuerza bruta
### **Subestados ocultos**
Otra condición de carrera más complicada explotará subestados en el estado de la máquina que podrían permitir a un atacante abusar de estados a los que nunca se suponía que debía tener acceso, pero hay una pequeña ventana para que el atacante lo acceda.
1. **Predecir subestados ocultos e interesantes potenciales**
El primer paso es identificar todos los puntos finales que ya sea escriben en él o leen datos de él y luego usan esos datos para algo importante. Por ejemplo, los usuarios pueden almacenarse en una tabla de base de datos que se modifica mediante el registro, la edición de perfiles, la iniciación de restablecimiento de contraseña y la finalización de restablecimiento de contraseña.
Podemos usar tres preguntas clave para descartar los puntos finales que es poco probable que causen colisiones. Para cada objeto y los puntos finales asociados, pregunte:
- **¿Cómo se almacena el estado?**
Los datos que se almacenan en una estructura de datos persistente en el servidor son ideales para la explotación. Algunos puntos finales almacenan su estado completamente en el lado del cliente, como los restablecimientos de contraseña que funcionan enviando un JWT por correo electrónico; estos se pueden omitir de manera segura.
Las aplicaciones a menudo almacenan algún estado en la sesión del usuario. Estos a menudo están algo protegidos contra subestados, más sobre eso más adelante.
- **¿Estamos editando o agregando?**
Las operaciones que editan datos existentes (como cambiar la dirección de correo electrónico principal de una cuenta) tienen un amplio potencial de colisión, mientras que las acciones que simplemente se agregan a los datos existentes (como agregar una dirección de correo electrónico adicional) es poco probable que sean vulnerables a algo más que ataques de límite-desbordamiento.
- **¿En qué se basa la operación?**
La mayoría de los puntos finales operan en un registro específico, que se busca utilizando una "clave", como un nombre de usuario, un token de restablecimiento de contraseña o un nombre de archivo. Para un ataque exitoso, necesitamos dos operaciones que usen la misma clave. Por ejemplo, imagine dos implementaciones plausibles de restablecimiento de contraseña:
<figure><img src="../.gitbook/assets/image (2) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
2. **Buscar pistas**
En este punto, es hora de lanzar algunos ataques de RC sobre los puntos finales interesantes potenciales para tratar de encontrar resultados inesperados en comparación con los regulares. Cualquier desviación de la respuesta esperada, como un cambio en una o más respuestas, o un efecto de segundo orden como diferentes contenidos de correo electrónico o un cambio visible en su sesión, podría ser una pista que indique que algo está mal.
3. **Probar el concepto**
El último paso es probar el concepto y convertirlo en un ataque viable.
Cuando envía un lote de solicitudes, es posible que descubra que un par de solicitudes tempranas desencadena un estado final vulnerable, pero las solicitudes posteriores lo sobrescriben/invalidan y el estado final no se puede explotar. En este escenario, querrá eliminar todas las solicitudes innecesarias: dos deberían ser suficientes para explotar la mayoría de las vulnerabilidades. Sin embargo, reducir a dos solicitudes hará que el ataque sea más sensible al tiempo, por lo que es posible que deba intentar el ataque varias veces o automatizarlo.
### Ataques sensibles al tiempo
A veces, es posible que no encuentre condiciones de carrera, pero las técnicas para entregar solicitudes con un tiempo preciso aún pueden revelar la presencia de otras vulnerabilidades.
Un ejemplo de esto es cuando se utilizan marcas de tiempo de alta resolución en lugar de cadenas aleatorias seguras criptográficamente para generar tokens de seguridad.
Considere un token de restablecimiento de contraseña que solo se aleatoriza utilizando una marca de tiempo. En este caso, podría ser posible desencadenar dos restablecimientos de contraseña para dos usuarios diferentes, que ambos usan el mismo token. Todo lo que necesita hacer es sincronizar las solicitudes para que generen la misma marca de tiempo.
{% hint style="warning" %}
Para confirmar, por ejemplo, la situación anterior, simplemente podría solicitar **2 tokens de restablecimiento de contraseña al mismo tiempo** (usando un ataque de paquete único) y verificar si son **iguales**.
{% endhint %}
Consulte el [ejemplo en este laboratorio](https://portswigger.net/web-security/race-conditions/lab-race-conditions-exploiting-time-sensitive-vulnerabilities).
## Estudios de caso de subestados ocultos
### Pagar y agregar un artículo
[Consulte este laboratorio](https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-insufficient-workflow-validation) para ver cómo **pagar** en una tienda y **agregar un artículo adicional** que no necesitará pagar.
### Confirmar otros correos electrónicos
La idea es **verificar una dirección de correo electrónico y cambiarla a otra al mismo tiempo** para averiguar si la plataforma verifica la nueva dirección cambiada.
### Cambiar el correo electrónico a 2 direcciones de correo electrónico basadas en cookies
Según [este informe](https://portswigger.net/research/smashing-the-state-machine), Gitlab era vulnerable a un secuestro de esta manera porque podría **enviar el token de verificación de correo electrónico de un correo electrónico al otro correo electrónico**.
También puede consultar [este laboratorio](https://portswigger.net/web-security/race-conditions/lab-race-conditions-single-endpoint) para obtener más información al respecto.
### Estados ocultos de la base de datos / Bypass de confirmación
Si se utilizan **2 escrituras diferentes** para **agregar información** dentro de una **base de datos**, hay una pequeña porción de tiempo en la que solo se ha escrito el primer dato dentro de la base de datos. Por ejemplo, al crear un usuario, el **nombre de usuario** y la **contraseña** podrían ser **escritos** y luego se escribe el token para confirmar la cuenta recién creada. Esto significa que durante un breve tiempo, el **token para confirmar una cuenta es nulo**.
Por lo tanto, **registrarse en una cuenta y enviar varias solicitudes con un token vacío** (`token=` o `token[]=` o cualquier otra variación) para confirmar la cuenta de inmediato podría permitir confirmar una cuenta donde no controla el correo electrónico.
Consulte [este laboratorio](https://portswigger.net/web-security/race-conditions/lab-race-conditions-partial-construction) para ver un ejemplo.
### Bypass de 2FA
El siguiente pseudocódigo demuestra cómo un sitio web podría ser vulnerable a una variación de carrera de este ataque:
```python
session['userid'] = user.userid
if user.mfa_enabled:
session['enforce_mfa'] = True
# generate and send MFA code to user
# redirect browser to MFA code entry form
```
Como puedes ver, esto es en realidad una **secuencia de múltiples pasos dentro de una sola solicitud**. Lo más importante es que pasa por un subestado en el que el **usuario tiene temporalmente una sesión válida iniciada**, pero aún no se está aplicando la autenticación multifactor (MFA). Un atacante podría potencialmente explotar esto enviando una solicitud de inicio de sesión junto con una solicitud a un punto final sensible y autenticado.
### Persistencia eterna de OAuth2
2023-06-05 18:33:24 +00:00
Existen varios [**proveedores de OAuth**](https://en.wikipedia.org/wiki/List\_of\_OAuth\_providers). Estos servicios te permitirán crear una aplicación y autenticar a los usuarios que el proveedor ha registrado. Para hacerlo, el **cliente** deberá **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?_"
2023-06-05 18:33:24 +00:00
#### 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. Luego, 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 (Token de Autenticación/Token de Actualización) a partir del **`authorization_code`** para tu cuenta. Básicamente, aprovechará el 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, se eliminará un par de AT/RT, pero los demás seguirán siendo válidos**.
2023-06-05 18:33:24 +00:00
#### Condición de carrera en `Refresh Token`
Una vez que hayas **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**.
2023-06-05 18:33:24 +00:00
## Referencias
* [https://hackerone.com/reports/759247](https://hackerone.com/reports/759247)
* [https://pandaonair.com/2020/06/11/race-conditions-exploring-the-possibilities.html](https://pandaonair.com/2020/06/11/race-conditions-exploring-the-possibilities.html)
* [https://hackerone.com/reports/55140](https://hackerone.com/reports/55140)
* [https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine)
* [https://portswigger.net/web-security/race-conditions](https://portswigger.net/web-security/race-conditions)
2023-06-05 18:33:24 +00:00
<details>
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
* ¿Trabajas en una **empresa de ciberseguridad**? ¿Quieres ver tu **empresa anunciada en HackTricks**? ¿O quieres tener acceso a la **última versión de PEASS o descargar HackTricks en PDF**? ¡Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
* Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección de exclusivos [**NFTs**](https://opensea.io/collection/the-peass-family)
* Obtén el [**merchandising oficial de PEASS y HackTricks**](https://peass.creator-spring.com)
* **Únete al** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de Telegram**](https://t.me/peass) o **sígueme** en **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Comparte tus trucos de hacking enviando PR al** [**repositorio de hacktricks**](https://github.com/carlospolop/hacktricks) **y al** [**repositorio de hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
2023-06-05 18:33:24 +00:00
</details>
![](<../.gitbook/assets/image (9) (1) (2).png>)
\
Utiliza [**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks) para construir y **automatizar fácilmente flujos de trabajo** con las herramientas comunitarias más avanzadas del mundo.\
Obtén acceso hoy mismo:
2023-06-05 18:33:24 +00:00
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}