Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
multi_path — CVE-2018-4241: débordement de tas du noyau XNU dû à une mauvaise vérification des limites dans MPTCP pour iOS 11 - 11.3.1publié par Ian Beer | Kitploit
Outils/GitHubGitHub/0neday/multi_path
Frameworks d'ExploitationSécurité iOSCriminalistique MémoireAnalyse des VulnérabilitésExploitationSécurité MobileExploitation de Binaires
GitHub0neday/multi_path

multi_path

CVE-2018-4241: débordement de tas du noyau XNU dû à une mauvaise vérification des limites dans MPTCP pour iOS 11 - 11.3.1publié par Ian Beer

Voir le dépôt
41il y a 8 ansPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

multi_path - exploit pour le problème p0 1558 (CVE-2018-4241)

@i41nbeer

mptcp_usr_connectx est le gestionnaire de l'appel système connectx pour la famille de sockets AP_MULTIPATH.

La logique de cette fonction ne parvient pas à traiter correctement les sockaddrs source et destination qui ne sont pas AF_INET ou 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);
  }

En regardant dans la structure que vous débordez, vous remarquez que vous pouvez atteindre les deux champs ici :

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

mpte_itfinfo_size se trouve juste avant mpte_itfinfo.

Quand la structure est initialisée, le pointeur mpte_itfinfo pointe vers un petit tableau inline. Si plus de sous-flux sont ajoutés qu'il n'y en a dans le tableau, ils sont alors placés dans un buffer du tas, et mpte_itfinfo pointera vers celui-ci.

Si vous aviez un autre bug (par exemple la divulgation du tas noyau de async_wake), vous pourriez écraser le champ mpte_itfinfo avec n'importe quel objet de zone valide et il serait libéré (en fait, vous pourriez aussi l'écraser avec un offset dans cet objet pour encore plus de fun !)

Cependant, nous n'avons pas ça.

Une autre approche consiste à écraser partiellement le pointeur. Si nous l'écrasons partiellement avec des octets NULL, nous pouvons le faire pointer vers une valeur alignée sur 256 octets, 65k, 16 Mo ou 4 Go.

Dans cet exploit, je choisis un écrasement NULL de 3 octets, ce qui provoquera un kfree de l'adresse de mpte_itfinfo arrondie à la limite des 16 Mo suivante.

Le flux d'exploitation est le suivant :

  • Allouer alternativement 16 Mo de ipc_kmsgs suivis d'un tas de sockets mptcp. Le but ici est d'obtenir une allocation kalloc.2048 à cette limite de 16 Mo.
  • Utiliser le bug pour libérer un des ipc_kmsgs, déplacer cette page vers la liste intermédiaire et placer l'allocation alignée sur 16 Mo dans une freelist de pages intermédiaires kalloc.2048.
  • Allouer un tas de pipes remplis de 2047 octets ; les buffers de sauvegarde de ces pipes viendront de kalloc.2048, espérons-le incluant notre adresse alignée sur 16 Mo.
  • Déclencher le bug une deuxième fois, libérant la même adresse, puis allouer cette fois un tas de buffers ipc_kmsg préalloués depuis kalloc.2048.
  • Maintenant, nous avons espérons-le un ipc_kmsg (auquel nous pouvons envoyer des messages puis recevoir) et un buffer de pipe (que nous pouvons lire et écrire) qui se chevauchent.
  • J'utilise l'astuce du port d'exception de thread de extra_recipe pour envoyer des messages au buffer ipc_kmsg préalloué. Chaque fois, nous vérifions chaque pipe pour voir si l'un d'eux contient le message. Lorsque nous trouvons la bonne paire (ipc_kmsg, pipe), nous pouvons réécrire le message pour nous envoyer un faux port qui réside dans le buffer du pipe. Je structure ce faux port comme celui de async_wake (que j'ai basé sur yalu 10.2 par @qwertyoruiopz et @marcograss) pour obtenir une primitive de lecture noyau précoce.
  • En utilisant la primitive de lecture noyau, je trouve la tâche noyau et crée un faux port qui permet une lecture/écriture plus facile de la mémoire noyau via mach_vm_read/mach_vm_write.

Mise en garde : Pour connecter les sockets mptcp, vous avez besoin de l'entitlement com.apple.developer.networking.multipath qui nécessite un certificat développeur Apple, que n'importe qui peut acheter auprès d'Apple.

Fiabilité : C'est un outil de recherche en sécurité et il est looooin d'être parfait. Cependant, il devrait fonctionner la plupart du temps, et quand il fonctionne, il devrait bien nettoyer pour ne pas planter plus tard.

Pour améliorer la probabilité qu'il fonctionne :

  • éteindre le wifi et passer en mode avion
  • redémarrer
  • attendre 30 secondes après le redémarrage
  • exécuter l'application depuis Xcode

Appareils supportés : Cela devrait fonctionner sur iOS 11.0 à 11.3.1 inclus. J'ai testé sur : iPod Touch 6g, iPhone 6s, iPhone SE, iPhone 7, iPhone 8

API : #include "sploit.h" et appelez go() pour exécuter l'exploit. S'il a fonctionné, vous pouvez utiliser les fonctions de kmem.h pour lire et écrire la mémoire du noyau

Notes: @elvanderb a donné une conférence éclair sur le bug à rump.beer à Paris le 31 mai : https://www.rump.beer/2018/slides/ios_48h.pdf @jaakerblom a publié un exploit fonctionnel sur github le 1er juin : https://github.com/potmdehex/multipath_kfree La technique de John est similaire à la mienne mais il fait un débordement de deux octets plutôt que trois, et remplace par des objets différents. du bon boulot !

Télécharger l’outil