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
multi_path — CVE-2018-4241: Desbordamiento de montón del kernel XNU debido a una comprobación de límites deficiente en MPTCP para iOS 11 - 11.3.1publicado por Ian Beer | Kitploit
Herramientas/GitHubGitHub/0neday/multi_path
Frameworks de ExploitsSeguridad iOSForensia de MemoriaAnálisis de VulnerabilidadesExplotaciónSeguridad MóvilExplotación de Binarios
GitHub0neday/multi_path

multi_path

CVE-2018-4241: Desbordamiento de montón del kernel XNU debido a una comprobación de límites deficiente en MPTCP para iOS 11 - 11.3.1publicado por Ian Beer

Ver Repositorio
414hace 8 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

multi_path - exploit para el issue p0 1558 (CVE-2018-4241)

@i41nbeer

mptcp_usr_connectx es el manejador de la syscall connectx para la familia de sockets AP_MULTIPATH.

La lógica de esta función falla al manejar correctamente sockaddrs de origen y destino que no son AF_INET o AF_INET6:

root@kitploit:~
  // verify sa_len for AF_INET:

  if (dst->sa_family == AF_INET &&
      dst->sa_len != sizeof(mpte->__mpte_dst_v4)) {
    mptcplog((LOG_ERR, "%s IPv4 dst len %u\n", __func__, dst->sa_len), MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR);
    error = EINVAL;
    goto out;
  }

  // verify sa_len for AF_INET6:

  if (dst->sa_family == AF_INET6 &&
      dst->sa_len != sizeof(mpte->__mpte_dst_v6)) {
    mptcplog((LOG_ERR, "%s IPv6 dst len %u\n", __func__, dst->sa_len), MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR);
    error = EINVAL;
    goto out;
  }

  // code doesn't bail if sa_family was neither AF_INET nor AF_INET6

  if (!(mpte->mpte_flags & MPTE_SVCTYPE_CHECKED)) {
    if (mptcp_entitlement_check(mp_so) < 0) {
      error = EPERM;
      goto out;
    }

    mpte->mpte_flags |= MPTE_SVCTYPE_CHECKED;
  }

  // memcpy with sa_len up to 255:

  if ((mp_so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0) {
    memcpy(&mpte->mpte_dst, dst, dst->sa_len);
  }

Mirando alrededor en la estructura que desbordas, notas que puedes alcanzar ambos campos aquí:

if (mpte->mpte_itfinfo_size > MPTE_ITFINFO_SIZE) _FREE(mpte->mpte_itfinfo, M_TEMP);

mpte_itfinfo_size está justo antes de mpte_itfinfo.

Cuando la estructura es inicializada, el puntero mpte_itfinfo apunta a un pequeño array inline. Si se añaden más subflujos de los que caben, se colocan en un buffer de heap, y mpte_itfinfo apuntará a ese buffer.

Si tuvieras otro bug (por ejemplo, el bug de divulgación de heap del kernel de async_wake) podrías sobrescribir el campo mpte_itfinfo con cualquier objeto de zona válido y sería liberado (de hecho, también podrías sobrescribirlo con un offset dentro de ese objeto para aún más diversión).

Sin embargo, no tenemos eso.

En su lugar, otro enfoque es sobrescribir parcialmente el puntero. Si lo sobrescribimos parcialmente con bytes NULL, podemos apuntarlo a un valor alineado a 256 bytes, 65k, 16MB o 4GB.

En este exploit elijo una sobrescritura de 3 bytes con NULL, lo que causará un kfree de la dirección mpte_itfinfo redondeada hacia abajo al siguiente límite de 16MB.

El flujo de explotación es el siguiente:

  • Asignar alternadamente 16MB de ipc_kmsgs seguidos por un montón de sockets mptcp. El objetivo aquí es obtener una asignación kalloc.2048 en ese límite de 16MB.
  • Usar el bug para liberar uno de los ipc_kmsgs, moviendo esa página a la lista intermedia y colocando la asignación alineada a 16MB en una freelist de páginas intermedias de kalloc.2048.
  • Asignar un montón de pipes llenos de 2047 bytes; los buffers de respaldo de estos pipes provendrán de kalloc.2048, con suerte incluyendo nuestra dirección alineada a 16MB.
  • Disparar el bug una segunda vez, liberando la misma dirección y luego asignar un montón de buffers ipc_kmsg preasignados desde kalloc.2048.
  • Ahora tenemos, con suerte, un ipc_kmsg (al que podemos enviar mensajes y luego recibir) y un buffer de pipe (que podemos leer y escribir) superpuestos.
  • Uso el truco del puerto de excepción de hilo de extra_recipe para enviar mensajes al buffer ipc_kmsg preasignado. Cada vez revisamos cada uno de los pipes para ver si alguno contiene el mensaje. Cuando encontramos el par (ipc_kmsg,pipe) correcto, podemos reescribir el mensaje para enviarnos un puerto falso que reside dentro del buffer del pipe. Estructuro ese puerto falso como el de async_wake (que basé en yalu 10.2 de @qwertyoruiopz y @marcograss) para obtener una primitiva de lectura temprana del kernel.
  • Usando la primitiva de lectura del kernel, encuentro la tarea del kernel y creo un puerto falso que permite una lectura/escritura más fácil de la memoria del kernel mediante mach_vm_read/mach_vm_write.

Advertencia: Para conectar sockets mptcp necesitas el entitlement com.apple.developer.networking.multipath, que requiere un certificado de desarrollador de Apple, que cualquiera puede comprar a Apple.

Fiabilidad: Esta es una herramienta de investigación de seguridad y está muuuuuy lejos de ser perfecta. Sin embargo, debería funcionar la mayoría de las veces, y cuando funciona, debería hacer un buen trabajo de limpieza para que no cause panic más tarde.

Para mejorar la probabilidad de que funcione:

  • apaga el wifi y pon el modo avión
  • reinicia
  • espera 30 segundos después de reiniciar
  • ejecuta la aplicación desde Xcode

Dispositivos compatibles: Debería funcionar en iOS 11.0 - 11.3.1 inclusive. He probado en: iPod Touch 6g, iPhone 6s, iPhone SE, iPhone 7, iPhone 8

API: #include "sploit.h" y llama a go() para ejecutar el exploit. Si funciona, puedes usar las funciones en kmem.h para leer y escribir memoria del kernel.

Notas: Varias personas han hecho bindiff públicamente de este bug desde el parche (o su 0day fue parcheado ;) lee su material para más detalles: @elvanderb dio una charla relámpago sobre el bug en rump.beer en París el 31 de mayo: https://www.rump.beer/2018/slides/ios_48h.pdf @jaakerblom publicó un exploit funcional en github el 1 de junio: https://github.com/potmdehex/multipath_kfree La técnica de John es similar a la mía pero él hace un desbordamiento de dos bytes en lugar de tres, y lo reemplaza con objetos diferentes. ¡buen material!

Descargar herramienta