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
CVE-2026-43783 — Proof-of-concept e analisi tecnica per CVE-2026-43783, un'escalation locale di privilegi su macOS tramite DesktopServicesHelper XPC con chown arbitrario per ottenere i privilegi di root. | Kitploit
Strumenti/GitHubGitHub/andrd3v/cve-2026-43783
Escalation di PrivilegiAnalisi delle VulnerabilitàExploitReverse EngineeringPenetration TestingAnalisi di BinariPaper e Ricerca
GitHubandrd3v/cve-2026-43783

CVE-2026-43783

Proof-of-concept e analisi tecnica per CVE-2026-43783, un'escalation locale di privilegi su macOS tramite DesktopServicesHelper XPC con chown arbitrario per ottenere i privilegi di root.

Vedi Repository
214261 mese 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

CVE-2026-43783: Riparazione dei permessi - Ottenere root: LPE tramite DesktopServicesHelper in macOS 26.5

Pubblicato originariamente su PT SWARM o andrd3v.github.io

Il daemon che Finder utilizza per "riparare" i permessi sui file iCloud si è rivelato disposto a riparare i permessi su qualsiasi cosa, comprese le directory di sistema. In questo articolo vedremo come funziona DesktopServicesHelper sotto il cofano e perché una singola richiesta XPC è stata sufficiente per ottenere root.

Dentro DesktopServicesHelper

Stavo cercando target con com.apple.private.tcc.allow con il valore kTCCServiceSystemPolicyAllFiles e DesktopServicesHelper ha attirato la mia attenzione. DesktopServicesHelper si trova in /System/Library/PrivateFrameworks/DesktopServicesPriv.framework/Versions/A/Resources/DesktopServicesHelper, e Finder lo utilizza per le operazioni sui file che richiedono privilegi elevati: spostare file, impostare permessi, gestire il Cestino.

Entitlements DesktopServicesHelper

Ho caricato il binario in IDA e sono andato a start(). Superata la solita configurazione di timer e code, crea un listener XPC, il punto di ingresso del daemon. Il listener registra un servizio mach con un nome specifico e inizia ad ascoltare le connessioni in arrivo. Qualsiasi processo che conosca questo nome può connettersi e inviare una richiesta. Ecco la parte chiave:

// get the service name
v16 = (const char *)sub_1000709F4(a1: 0);

// register the listener
mach_service = xpc_connection_create_mach_service(name: v16, targetq: nullptr, flags: 1u);

// set the incoming event handler
xpc_connection_set_event_handler(connection: mach_service, handler: &stru_1000B4B48);
xpc_connection_resume(connection: mach_service);

// start the event loop
CFRunLoopRun();

La funzione sub_1000709F4 restituisce il nome del servizio mach. In start() viene chiamata con argomento 0, il che significa che il daemon si registra con il nome com.apple.DesktopServicesHelper.

const char *__fastcall sub_1000709F4(int a1)
{
  if ( a1 != 0 )
    return "com.apple.DesktopServicesScriptingHelper";
  else
    return "com.apple.DesktopServicesHelper";
}

stru_1000B4B48 è un blocco handler (callback) che il daemon invoca per ogni evento in arrivo. XPC è basato su messaggi: il client costruisce un dizionario con chiavi e valori, lo invia al daemon, e il daemon analizza il contenuto e decide cosa fare. Tutti gli eventi in arrivo finiscono in questo handler. Diamo un'occhiata all'interno.

stru_1000B4B48 in IDA

La funzione invoke del blocco è sub_100032044. Su una nuova connessione, il daemon recupera prima l'euid e l'egid del client - ID utente effettivo e ID gruppo - gli identificatori dell'utente e del gruppo sotto cui viene eseguito il processo che si connette:

euid = xpc_connection_get_euid(connection: v8);
egid = xpc_connection_get_egid(connection: v8);
sub_100071268(a1: euid, a2: egid);

Poi assegna un handler per i messaggi in arrivo sulla connessione:

v15[2] = sub_10003AB2C;  // block's invoke function
xpc_connection_set_event_handler(connection: v14, handler: v15);
xpc_connection_resume(connection: v14);

sub_10003AB2C - è qui che arrivano le effettive richieste XPC dal client. Ora dobbiamo capire come il daemon decide quali richieste eseguire e quali rifiutare.

Dispatcher delle richieste

sub_10003AB2C è il dispatcher principale. È qui che il daemon decide cosa fare con una richiesta. La funzione è grande, quindi analizziamola a pezzi.

Innanzitutto, estrae la stringa "request" dal messaggio - il nome del comando che il client vuole eseguire:

reply = xpc_dictionary_create_reply(original: v12);
string = xpc_dictionary_get_string(xdict: v12, key: "request");
// ...
// logging: "Got Request '%{public}@'"

Poi il daemon recupera l'audit token del processo che si connette e verifica se è in esecuzione all'interno di App Sandbox. App Sandbox è un meccanismo di isolamento delle applicazioni macOS che limita l'accesso al file system, alla rete e ad altre risorse. Qui avviene la diramazione:

xpc_dictionary_get_audit_token(a1: v12, a2: buf);
qmemcpy(__p, buf, sizeof(__p));
if ( (unsigned int)sandbox_check_by_audit_token(a1: __p, a2: 0, a3: 0) != 0 )
{
  // client is sandboxed - check against allowlist
  if ( (sub_10003B25C(a1: &v32, a2: "Handshake") & 1) == 0
    && (sub_10003B25C(a1: &v32, a2: "exit") & 1) == 0
    && (sub_10003B25C(a1: &v32, a2: "SetDefaultPermissionOnHomeSubdirectories") & 1) == 0
    && (sub_10003B25C(a1: &v32, a2: "MoveAsideICloudToArchiveInHome") & 1) == 0
    && (sub_10003B25C(a1: &v32, a2: "RepairPermissionsForCloudItems") & 1) == 0
    && (sub_10003B25C(a1: &v32, a2: "CopyClientActive") & 1) == 0
    && (sub_10003B25C(a1: &v32, a2: "DeleteItem") & 1) == 0 )
  {
    sub_100034250(a1: v12, a2: &v32); // not in the list - kill the daemon
  }
}
else
{
  // client is not sandboxed - check entitlement
  *(_QWORD *)buf = sub_1000343C0(a1: v12, a2: CFSTR("com.apple.private.tcc.allow"));
  v19 = (const __CFArray *)sub_10003B1E0();
  v20 = v19;
  if ( v19 == nullptr
    || (v35.length = CFArrayGetCount(theArray: v19),
        v35.location = 0,
        CFArrayContainsValue(theArray: v20, range: v35, value: CFSTR("kTCCServiceSystemPolicyAllFiles")) == 0) )
  {
    sub_100034250(a1: v12, a2: &v32); // no entitlement - kill the daemon
  }
}

Se il client è in sandbox, il nome della richiesta viene confrontato con una allowlist di sette stringhe. Se corrisponde, il controllo viene superato e la richiesta passa. In caso contrario, sub_100034250 termina il daemon. Se il client non è in sandbox, il daemon verifica la presenza dell'entitlement com.apple.private.tcc.allow con il valore kTCCServiceSystemPolicyAllFiles. L'assenza dell'entitlement comporta anch'essa la terminazione.

Dopo aver superato il controllo, la richiesta attraversa due tabelle di handler. Prima sub_10002F7C8, poi sub_10002A194:

// first table (8 commands, two arguments)
v21 = sub_10002F7C8(a1: buf);
// ...
if ( v21 != 0 )
  v22(a1: v12, a2: v11); // found - invoke

// second table (21 commands, three arguments)
v27 = sub_10002A194(a1: buf);
// ...
if ( v27 != nullptr )
  v27(a1: v12, a2: reply, a3: v11); // found - invoke

Ora esaminiamo le tabelle dei gestori. La prima tabella (sub_10002F7C8):

__int64 __fastcall sub_10002F7C8(__int64 a1)
{
  __int64 result; // x0
  void **v3; // x21
  void **v4; // x8
  _BYTE v5[32]; // [xsp+8h] [xbp-128h] BYREF
  __int64 v6; // [xsp+28h] [xbp-108h] BYREF
  __int64 v7; // [xsp+48h] [xbp-E8h] BYREF
  __int64 v8; // [xsp+68h] [xbp-C8h] BYREF
  __int64 v9; // [xsp+88h] [xbp-A8h] BYREF
  __int64 v10; // [xsp+A8h] [xbp-88h] BYREF
  __int64 v11; // [xsp+C8h] [xbp-68h] BYREF
  __int64 v12; // [xsp+E8h] [xbp-48h] BYREF
  __int64 v13; // [xsp+108h] [xbp-28h] BYREF
Scarica lo strumento