Home News L’exploit namedobj in mano ai sviluppatori da mesi

[Scena PS4] L’exploit namedobj in mano ai sviluppatori da mesi

230
6

Il developer Specter ha riportato una testimonianza interessante all’interno della propria repository, pare che l’exploit namedobj sia già stato sfruttato da diversi sviluppatori, ma che non potevano rilasciarlo, il motivo pare sia legato all’enorme aiuto ricevuto dal team Fail0verflow.

Proprio il team Fail0verflow ha scoperchiato oggi il vaso di Pandora, da qui la volontà da parte dello sviluppatore di descrivere il bug, seguirà in un secondo momento la pubblicazione dell’exploit vero e proprio.

Il bug

Il bug è essenzialmente di tipo type confusion con il campo ‘kind’ dell’oggetto ‘id_entry’ utilizzato negli oggetti denominati. Gli oggetti denominati sono oggetti che dispongono di proprietà associate (ad esempio un nome per come lo si potrebbe immaginare), che punta all’oggetto reale nell’heap. Specificando un type 0x5000 per l’oggetto, è possibile causare una type confusion.

Ora è necessario trovare un’altra area del kernel che può eccedere per corrompere l’oggetto. Fortunatamente c’è sys_mdbg_service().

Questo ci permetterà di sovrascrivere i 32 bit più bassi di un puntatore free() con sys_namedobj_delete().

Da qui noi possiamo andare a creare una situazione use-after-free che è possibile utilizzare per ottenere l’esecuzione di codice spruzzando oggetti falsi nel mucchio e corrompendo un puntatore di funzione.

Strategia

Una buona strategia per sfruttare questo bug è la seguente:

  1. Perdere un oggetto di destinazione dal mucchio del kernel che non solo dispone di puntatori di funzioni che possono essere danneggiati, ma è anche ideale per evitare che si blocchi il kernel.
  2. Creare type confusion tramite sys_namedobj_create() con il flag 0x5000 (o flag 0x4000 a causa della bit OR).
  3. Impostare un kernel ROP chain in userland. Idealmente in questa ROP chain si desidera disattivare la protezione di scrittura del kernel, eseguire le patch desiderate (come la mappatura di memoria RWX) e pivot per tornare in maniera efficace.
  4. Sovrascrivere i 32 bit più bassi nell’oggetto con sys_mdbg_service() con i 32 bit inferiori dell’indirizzo dell’oggetto target. Non possiamo sovrascrivere i 32 bit superiori, ma fortunatamente il puntatore memorizzato in precedenza era comunque un puntatore di heap, quindi i 32 bit superiori verranno impostati sul prefisso dell’indirizzo heap di FreeBSD (0xFFFFYYYYxxxxxxxx dove YYYY viene randomizzato da ASLR all’avvio).
  5. Attivare free() tramite sys_namedobj_delete().
  6. Spruzzare l’oggetto falso sull’heap con un puntatore di funzione che indica il kROP chain creato in precedenza.
  7. Trova una funzione che utilizza l’oggetto corrotto e attiva il puntatore funzione da leggere.
  8. Ora hai l’esecuzione di codice e la tua catena kROP sta funzionando in ring0! Sìì!
  9. Correggere l’oggetto free(), perché se non lo fai, appena il webkit esce, il kernel si blocca perché cercherà free() al tuo oggetto e di portare a un doppio free().
  10. Ritorno in userland con successo.

Gli appunti

  • È necessario fixare l’exploit all’interno del kernel ROP chain o nel doppio free() quando si esce dal WebKit, causando un kernel panic.
  • È necessario riportare con successo il kernel ROP chain in userland o il kernel si blocca quando la kROP chain termina.
  • Trovare un oggetto a perdere ed un exploit blind è MOLTO difficile. Questa è stata la testa che mi ha colpito per me.
  • Rilascerò presto un’implementazione, ma fino a quel momento, cercare di implementarla da soli e vedere quanto tempo va, è una grande esperienza di apprendimento! Divertiti!