Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
launchd-portrep — CVE-2018-4280: Vulnerabilidad de reemplazo de puerto Mach en launchd en macOS 10.13.5 que conduce a escalada de privilegios local y bypass de SIP. | Kitploit
Herramientas/GitHubGitHub/bazad/launchd-portrep
Escalada de PrivilegiosFrameworks de ExploitsExplotaciónPruebas de PenetraciónRed TeamingExplotación de Binarios
GitHubbazad/launchd-portrep

launchd-portrep

CVE-2018-4280: Vulnerabilidad de reemplazo de puerto Mach en launchd en macOS 10.13.5 que conduce a escalada de privilegios local y bypass de SIP.

Ver Repositorio
59610hace 7 añosRevisado por Kitploit

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

launchd-portrep

launchd-portrep es un exploit para una vulnerabilidad de reemplazo de puertos en launchd, el proceso inicial del espacio de usuario y el demonio de gestión de servicios en macOS. Al enviar un mensaje Mach manipulado al puerto de bootstrap, se puede forzar a launchd a desasignar su derecho de envío para cualquier puerto Mach al que el atacante también tenga un derecho de envío. Esto permite al atacante suplantar cualquier servicio de launchd que pueda consultar ante el resto del sistema.

La vulnerabilidad

Launchd multiplexa varios manejadores de mensajes Mach sobre su puerto principal, incluyendo un manejador MIG para mensajes de excepción. Si un proceso envía un mensaje mach_exception_raise o mach_exception_raise_state_identity a su propio puerto de bootstrap, launchd recibirá y procesará ese mensaje como una excepción a nivel de host.

Desafortunadamente, el manejo de estos mensajes por parte de launchd tiene errores. Si el tipo de excepción es EXC_CRASH, entonces launchd desasignará los puertos de hilo y tarea enviados en el mensaje y luego devolverá KERN_FAILURE desde la rutina de servicio, lo que hace que el sistema MIG desasigne los puertos de hilo y tarea nuevamente. (La suposición es que si una rutina de servicio devuelve éxito, entonces ha tomado posesión de todos los recursos en el mensaje Mach, mientras que si la rutina de servicio devuelve un error, entonces no ha tomado posesión de ninguno de los recursos.)

Aquí está el código de la rutina de servicio de launchd para mensajes mach_exception_raise, descompilado usando IDA/Hex-Rays y ligeramente editado para facilitar la lectura:

kern_return_t __fastcall
catch_mach_exception_raise(                             // (a) La rutina de servicio es
        mach_port_t           exception_port,           //     llamada con valores directamente
        mach_port_t           thread,                   //     del mensaje Mach
        mach_port_t           task,                     //     enviado por el cliente. Los
        unsigned int          exception,                //     puertos de hilo y tarea podrían
        mach_exception_data_t code,                     //     ser derechos de envío arbitrarios.
        unsigned int          codeCnt)
{
    kern_return_t kr;      // eax@1 MAPDST
    kern_return_t result;  // eax@10
    int pid;               // [rsp+14h] [rbp-43Ch]@1
    char codes_str[1024];  // [rsp+20h] [rbp-430h]@5
    __int64 __stack_guard; // [rsp+420h] [rbp-30h]@1

    __stack_guard = *__stack_chk_guard_ptr;
    pid = -1;
    kr = pid_for_task(task, &pid);
    if ( kr )
    {
        _os_assumes_log(kr);
        _os_avoid_tail_call();
    }
    if ( codeCnt )
    {
        do
        {
            __snprintf_chk(codes_str, 0x400uLL, 0, 0x400uLL, "0x%llx", *code);
            ++code;
            --codeCnt;
        }
        while ( codeCnt );
    }
    launchd_log_2(
        0LL,
        3LL,
        "Host-level exception raised: pid = %d, thread = 0x%x, "
            "exception type = 0x%x, codes = { %s }",
        pid,
        thread,
        exception,
        codes_str);
    kr = deallocate_mach_port(thread);                  // (b) El puerto "thread" enviado en
    if ( kr )                                           //     el mensaje es desasignado.
    {
        _os_assumes_log(kr);
        _os_avoid_tail_call();
    }
    kr = deallocate_mach_port(task);                    // (c) El puerto "task" enviado en el
    if ( kr )                                           //     mensaje es desasignado.
    {
        _os_assumes_log(kr);
        _os_avoid_tail_call();
    }
    result = 0;
    if ( *__stack_chk_guard_ptr == __stack_guard )
    {
        LOBYTE(result) = exception == 10;               // (d) Si el tipo de excepción es 10
        result *= 5;                                    //     (EXC_CRASH), entonces se devuelve
    }                                                   //     un error KERN_FAILURE.
    return result;                                      //     MIG desasignará los
}                                                       //     puertos nuevamente.

Esta doble desasignación de los nombres de puerto es problemática porque un proceso puede establecer los puertos que desee como los puertos de tarea e hilo en el mensaje de excepción. Launchd no realiza ninguna comprobación de que los derechos de envío recibidos correspondan realmente a un hilo y una tarea; los puertos podrían, por ejemplo, ser derechos de envío a puertos ya existentes en el espacio IPC de launchd. Entonces la doble desasignación haría que launchd perdiera una referencia de usuario en uno de sus propios puertos.

Este error puede ser explotado para liberar el derecho de envío de launchd a cualquier puerto Mach al que el proceso atacante también tenga un derecho de envío. En particular, si el proceso atacante puede consultar un servicio del sistema usando launchd, entonces puede liberar el derecho de envío de launchd a ese servicio y luego suplantar el servicio ante el resto del sistema. Después de eso hay muchas rutas diferentes para obtener privilegios del sistema.

Estrategia de exploit para obtener task_for_pid-allow

Este error es una versión menos general de CVE-2016-7637, un problema de manejo de referencias de usuario de puertos Mach en XNU descubierto por Ian Beer que permitía a los procesos liberar puertos Mach en otros procesos. Ian Beer explotó esa vulnerabilidad en macOS reemplazando el derecho de envío de launchd al endpoint com.apple.CoreServices.coreservicesd y suplantando a coreservicesd ante el resto del sistema. Coreservicesd es un objetivo atractivo porque es uno de los pocos servicios a los que los clientes envían su puerto de tarea en un mensaje Mach. Al reemplazar el derecho de envío de launchd a coreservicesd con su propio puerto y luego provocar que clientes privilegiados consulten y se comuniquen con coreservicesd, pudo obtener el puerto de tarea de un proceso privilegiado y luego ejecutar código dentro de ese proceso.

Dado que el comportamiento en macOS no ha cambiado, básicamente copié la estrategia de exploit de Ian Beer para esta vulnerabilidad. Enviamos mensajes de excepción a launchd que contienen el puerto de servicio de coreservicesd hasta que liberamos el derecho de envío de launchd a ese puerto. Podemos detectar cuándo hemos liberado el derecho llamando nuevamente a bootstrap_look_up() en el servicio: si launchd devuelve un nombre de puerto inválido, entonces hemos liberado con éxito el derecho de envío de launchd al puerto. Luego, registramos y desregistramos repetidamente un gran número de servicios en launchd hasta que uno de los servicios que registramos recibe el mismo nombre de puerto Mach en el espacio IPC de launchd que el puerto original de coreservicesd. En este punto, cualquier proceso que consulte com.apple.CoreServices.coreservicesd en launchd recibirá un derecho de envío a nuestro servicio falso en lugar del coreservicesd real. Luego ejecutamos un servidor MITM en el puerto de servicio falso, inspeccionando todos los puertos Mach en los mensajes recibidos de los clientes antes de reenviarlos al coreservicesd real. En este punto, enviamos un mensaje a sysdiagnose para que ejecute un tailspin, lo que hace que sysdiagnose se conecte a nuestro puerto falso de coreservicesd y nos envíe su puerto de tarea. Dado que sysdiagnose tiene el permiso task_for_pid-allow, ahora podemos obtener el puerto de tarea de cualquier proceso.

Descargar herramienta