macOS Stash Proxy Manipulación No Autorizada de las Preferencias de Red del Sistema mediante Ataque de Reutilización de PID

Jan 22, 2025

CVE Number

CVE-2025-4961

Credits

Carlos Garrido of Pentraze Cybersecurity

Descripción

Se identificó un nuevo problema de seguridad en un servicio XPC privilegiado tras cambios recientes destinados a corregir una vulnerabilidad previamente reportada (CVE-2024-7457). Aunque el problema original fue abordado, la implementación actualizada aún permite que procesos no autorizados establezcan una conexión XPC válida bajo condiciones específicas de carrera.

El servicio se basa en información relacionada con el proceso para la validación del cliente, lo cual no es adecuado para decisiones de seguridad. Como resultado, clientes no confiables pueden interactuar con el servicio como si fueran legítimos, lo que conduce a comportamientos privilegiados no intencionados.

Vulnerabilidad – Ataque de Reutilización de PID

La vulnerabilidad se debe a la dependencia del identificador de proceso (PID) para autenticar clientes XPC. Dado que los PID pueden reutilizarse, un atacante puede explotar una condición de carrera para enviar mensajes XPC maliciosos y, posteriormente, generar un proceso confiable que asuma el mismo PID.

Si el servicio valida al cliente después de esta transición, puede tratar incorrectamente los mensajes maliciosos como si provinieran de un proceso confiable. Esto permite que clientes no autorizados realicen acciones privilegiadas, incluida la modificación de la configuración de red del sistema.

listener:shouldAcceptNewConnection:

Al revisar la función listener:shouldAcceptNewConnection:, se invoca la función connectionIsValid:. En este punto, se hace evidente que la validez de la conexión se determina en función del identificador de proceso (PID) en lugar del auditToken. Esta decisión de diseño introduce una vulnerabilidad de Ataque de Reutilización de PID.

Esta condición de carrera es posible debido al siguiente comportamiento: al invocar posix_spawn para crear un nuevo proceso, se utiliza el flag POSIX_SPAWN_SETEXEC, lo que provoca que posix_spawn se comporte de manera efectiva como una llamada a execv y reutilice el identificador de proceso (PID) existente. Además, se especifica el flag POSIX_SPAWN_START_SUSPENDED para garantizar que el proceso se cree en estado suspendido.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16

char -[ProxyHelper listener:shouldAcceptNewConnection:](struct ProxyHelper* self, SEL sel, id listener, 
id shouldAcceptNewConnection)

    id obj_2 = _objc_retain(obj: listener)
    id rax_1 = _objc_retain(obj: shouldAcceptNewConnection)
    char result
        
     if (-[ProxyHelper connectionIsVaild:](self, sel: "connectionIsVaild:", 
            connectionIsVaild: rax_1) == 0)
    result = 0
    .
    .
    <SNIP>
    .
    .

connectionIsValid:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14

char -[ProxyHelper connectionIsVaild:](struct ProxyHelper* self, SEL sel, id connectionIsVaild)

    int64_t rax = *___stack_chk_guard
    id obj = _objc_retainAutoreleasedReturnValue(obj: _objc_msgSend(
    self: _OBJC_CLASS_$_NSRunningApplication, 
    cmd: "runningApplicationWithProcessIde…", 
    zx.q(_objc_msgSend(self: connectionIsVaild, cmd: "processIdentifier"))))
    char result
    .
    .
    <SNIP>
    .
    .

Remediación

  1. Finalizar la conexión al recibir un mensaje no reconocido.

  2. Realizar comprobaciones de autorización antes de aceptar una conexión siempre que sea posible.

    • Si las comprobaciones de autorización no son viables en esa etapa, utilizar xpc_dictionary_get_audit_token.

    • Alternativamente, guardar el audit token durante el manejador de aceptación para su uso posterior (este método también es efectivo para NSXPCConnection).

  3. Aprovechar las nuevas APIs para la verificación automática de firma de código antes de aceptar una conexión:

    • [NSXPCConnection setCodeSigningRequirement:] (disponible desde macOS 13.0)

    • xpc_connection_set_peer_code_signing_requirement (disponible desde macOS 12.0)

¿Ver el sitio en español?