Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

FeedContattoPrivacy© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
launchd-portrep — CVE-2018-4280: Vulnerabilità di sostituzione delle porte Mach in launchd su macOS 10.13.5 che porta a escalation dei privilegi locali e bypass di SIP. | Kitploit
Strumenti/GitHubGitHub/bazad/launchd-portrep
Escalation di PrivilegiFramework di ExploitExploitPenetration TestingRed TeamingBinary Exploitation
GitHubbazad/launchd-portrep

launchd-portrep

CVE-2018-4280: Vulnerabilità di sostituzione delle porte Mach in launchd su macOS 10.13.5 che porta a escalation dei privilegi locali e bypass di SIP.

Vedi Repository
596107 anni faRevisionato da Kitploit

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

launchd-portrep

launchd-portrep è un exploit per una vulnerabilità di sostituzione dei port in launchd, il processo iniziale nello spazio utente e demone di gestione dei servizi su macOS. Inviando un messaggio Mach appositamente costruito al bootstrap port, launchd può essere indotto a deallocare il suo send right per qualsiasi port Mach a cui l'attaccante ha anch'esso un send right. Ciò consente all'attaccante di impersonare qualsiasi servizio launchd che può cercare davanti al resto del sistema.

La vulnerabilità

Launchd multiplexa diversi gestori di messaggi Mach sul suo port principale, incluso un gestore MIG per i messaggi di eccezione. Se un processo invia un messaggio mach_exception_raise o mach_exception_raise_state_identity al proprio bootstrap port, launchd riceverà e processerà quel messaggio come un'eccezione a livello di host.

Purtroppo, la gestione di questi messaggi da parte di launchd è difettosa. Se il tipo di eccezione è EXC_CRASH, allora launchd dealloca i port di thread e task inviati nel messaggio e poi restituisce KERN_FAILURE dalla routine di servizio, causando la deallocazione da parte del sistema MIG dei port di thread e task una seconda volta. (L'assunzione è che se una routine di servizio restituisce successo, allora ha preso possesso di tutte le risorse nel messaggio Mach, mentre se la routine di servizio restituisce un errore, allora non ha preso possesso di nessuna risorsa.)

Ecco il codice dalla routine di servizio di launchd per i messaggi mach_exception_raise, decompilato con IDA/Hex-Rays e leggermente modificato per migliorare la leggibilità:

kern_return_t __fastcall
catch_mach_exception_raise(                             // (a) La routine di servizio
        mach_port_t           exception_port,           //     viene chiamata con i valori
        mach_port_t           thread,                   //     direttamente dal messaggio
        mach_port_t           task,                     //     Mach inviato dal client.
        unsigned int          exception,                //     I port di thread e task
        mach_exception_data_t code,                     //     potrebbero essere send right
        unsigned int          codeCnt)                  //     arbitrari.
{
    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) Il port "thread" inviato
    if ( kr )                                           //     nel messaggio viene deallocato.
    {
        _os_assumes_log(kr);
        _os_avoid_tail_call();
    }
    kr = deallocate_mach_port(task);                    // (c) Il port "task" inviato nel
    if ( kr )                                           //     messaggio viene deallocato.
    {
        _os_assumes_log(kr);
        _os_avoid_tail_call();
    }
    result = 0;
    if ( *__stack_chk_guard_ptr == __stack_guard )
    {
        LOBYTE(result) = exception == 10;               // (d) Se il tipo di eccezione è 10
        result *= 5;                                    //     (EXC_CRASH), allora viene
    }                                                   //     restituito un errore
    return result;                                      //     KERN_FAILURE. MIG dealloca
}                                                       //     i port di nuovo.

Questa doppia deallocazione dei nomi dei port è problematica perché un processo può impostare qualsiasi port desideri come port di task e thread nel messaggio di eccezione. Launchd non esegue alcun controllo che i send right ricevuti corrispondano effettivamente a un thread e un task; i port potrebbero, ad esempio, essere send right verso port già presenti nello spazio IPC di launchd. Quindi la doppia deallocazione farebbe effettivamente sì che launchd perda un riferimento utente su uno dei suoi port.

Questo bug può essere sfruttato per liberare il send right di launchd verso qualsiasi port Mach a cui il processo attaccante ha anch'esso un send right. In particolare, se il processo attaccante può cercare un servizio di sistema usando launchd, allora può liberare il send right di launchd verso quel servizio e quindi impersonare il servizio al resto del sistema. Dopo di che ci sono molte strade diverse per ottenere privilegi di sistema.

Strategia di exploit per ottenere task_for_pid-allow

Questo bug è una versione meno generale del CVE-2016-7637, un problema di gestione dei riferimenti utente di Mach port in XNU scoperto da Ian Beer che permetteva ai processi di liberare port Mach in altri processi. Ian Beer ha sfruttato quella vulnerabilità su macOS sostituendo il send right di launchd verso l'endpoint com.apple.CoreServices.coreservicesd e impersonando coreservicesd al resto del sistema. Coreservicesd è un bersaglio interessante perché è uno dei pochi servizi a cui i client invieranno il loro task port in un messaggio Mach. Sostituendo il send right di launchd verso coreservicesd con il proprio port e quindi inducendo client privilegiati a cercare e comunicare con coreservicesd, è riuscito a ottenere il task port per un processo privilegiato e quindi eseguire codice all'interno di quel processo.

Poiché il comportamento su macOS non è cambiato, ho sostanzialmente copiato la strategia di exploit di Ian Beer per questa vulnerabilità. Inviamo messaggi di eccezione a launchd contenenti il port di servizio di coreservicesd finché non liberiamo il send right di launchd verso quel port. Possiamo rilevare quando abbiamo liberato il diritto chiamando di nuovo bootstrap_look_up() sul servizio: se launchd restituisce un nome di port non valido, allora abbiamo liberato con successo il send right di launchd verso il port. Quindi, registriamo e annulliamo ripetutamente la registrazione di un gran numero di servizi con launchd finché uno dei servizi che registriamo non viene assegnato allo stesso nome di port Mach nello spazio IPC di launchd del port originale di coreservicesd. A questo punto, qualsiasi processo che cerca com.apple.CoreServices.coreservicesd in launchd riceverà un send right verso il nostro servizio falso invece che verso il vero coreservicesd. Poi eseguiamo un server MITM sul port di servizio falso, ispezionando tutti i port Mach nei messaggi ricevuti dai client prima di inviarli al vero coreservicesd. A questo punto inviamo un messaggio a sysdiagnose che lo fa eseguire un tailspin, il che fa sì che sysdiagnose si connetta al nostro port falso di coreservicesd e ci invii il suo task port. Poiché sysdiagnose ha l'entitlement task_for_pid-allow, possiamo ora ottenere il task port per qualsiasi processo.

Scarica lo strumento