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
multi_path — CVE-2018-4241: overflow dell'heap del kernel XNU a causa di un cattivo controllo dei limiti in MPTCP per iOS 11 - 11.3.1rilasciato da Ian Beer | Kitploit
Strumenti/GitHubGitHub/0neday/multi_path
Framework di ExploitSicurezza iOSMemory ForensicsAnalisi delle VulnerabilitàExploitSicurezza MobileBinary Exploitation
GitHub0neday/multi_path

multi_path

CVE-2018-4241: overflow dell'heap del kernel XNU a causa di un cattivo controllo dei limiti in MPTCP per iOS 11 - 11.3.1rilasciato da Ian Beer

Vedi Repository
418 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

multi_path - exploit per il problema p0 1558 (CVE-2018-4241)

@i41nbeer

mptcp_usr_connectx è il gestore per la syscall connectx per la famiglia di socket AP_MULTIPATH.

La logica di questa funzione non riesce a gestire correttamente gli indirizzi sockaddr di origine e destinazione che non sono 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);
  }

Guardando nella struttura che si overflowa all'interno, si nota che si possono colpire entrambi i campi qui:

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

mpte_itfinfo_size è appena prima di mpte_itfinfo.

Quando la struttura viene inizializzata, il puntatore mpte_itfinfo punta a un piccolo array inline. Se vengono aggiunti più subflow di quanti ne possano contenere, vengono invece inseriti in un buffer heap, e mpte_itfinfo punterà a quello.

Se si avesse un altro bug (ad esempio il bug di divulgazione dell'heap del kernel da async_wake) si potrebbe sovrascrivere il campo mpte_itfinfo con qualsiasi oggetto di zona valido e verrebbe liberato (in effetti, si potrebbe anche sovrascrivere con un offset all'interno di quell'oggetto per ancora più divertimento!)

Tuttavia, non abbiamo quello.

Invece un altro approccio è sovrascrivere parzialmente il puntatore. Se lo sovrascriviamo parzialmente con byte NULL, possiamo puntarlo a un valore allineato a 256 byte, 65k, 16MB o 4GB.

In questo exploit scelgo una sovrascrittura di 3 byte NULL, che causerà un kfree dell'indirizzo mpte_itfinfo arrotondato per difetto al successivo limite di 16MB.

Il flusso di sfruttamento è il seguente:

Allocare alternativamente 16MB di ipc_kmsgs seguiti da un mucchio di socket mptcp. L'obiettivo è ottenere un'allocazione kalloc.2048 a quel limite di 16MB.

Usare il bug per liberare uno degli ipc_kmsgs, spostando quella pagina nella lista intermedia e mettendo l'allocazione allineata a 16MB su una freelist di pagine intermedie kalloc.2048.

Allocare un mucchio di pipe piene di 2047 byte; i buffer di supporto per queste pipe proverranno da kalloc.2048, si spera incluso il nostro indirizzo allineato a 16MB.

Attivare il bug una seconda volta, liberando lo stesso indirizzo e questa volta allocare un mucchio di buffer ipc_kmsg preallocati da kalloc.2048.

Ora si spera di avere un ipc_kmsg (a cui possiamo far inviare messaggi e poi riceverli) e un buffer di pipe (che possiamo leggere e scrivere) sovrapposti tra loro.

Uso il trucco del thread exception port da extra_recipe per far inviare messaggi al buffer ipc_kmsg preallocato. Ogni volta controlliamo ciascuna delle pipe per vedere se qualcuna contiene il messaggio. Quando troviamo la coppia (ipc_kmsg, pipe) giusta, possiamo riscrivere il messaggio per inviarci una porta fittizia che risiede all'interno del buffer della pipe. Strutturo quella porta fittizia come quella di async_wake (che ho basato su yalu 10.2 di @qwertyoruiopz e @marcograss) per darmi una primitiva di lettura precoce del kernel.

Usando la primitiva di lettura del kernel trovo il task del kernel e creo una porta fittizia che permette una lettura/scrittura più facile della memoria del kernel tramite mach_vm_read/mach_vm_write.

Avvertenza: Per connettere i socket mptcp è necessaria l'entitlement com.apple.developer.networking.multipath che richiede un certificato sviluppatore Apple, che chiunque può acquistare da Apple.

Affidabilità: Questo è uno strumento di ricerca sulla sicurezza ed è molto lontano dall'essere perfetto. Tuttavia, dovrebbe funzionare la maggior parte delle volte, e quando funziona dovrebbe fare un buon lavoro di pulizia in modo che non vada in panico in seguito.

Per migliorare la probabilità che funzioni:

  • spegnere il wifi e attivare la modalità aereo
  • riavviare
  • attendere 30 secondi dopo il riavvio
  • eseguire l'app da xcode

Dispositivi supportati: Dovrebbe funzionare su iOS 11.0 - 11.3.1 inclusi. Ho testato su: iPod Touch 6g, iPhone 6s, iPhone SE, iPhone 7, iPhone 8

API: #include "sploit.h" e chiamare go() per eseguire l'exploit. Se ha funzionato, è possibile utilizzare le funzioni in kmem.h per leggere e scrivere la memoria del kernel

Note: Molte persone hanno fatto un bindiff pubblico di questo bug dalla patch (o il loro 0day è stato patchato ;) leggete i loro lavori per maggiori dettagli: @elvanderb ha tenuto un lightning talk sul bug al rump.beer a Parigi il 31 maggio: https://www.rump.beer/2018/slides/ios_48h.pdf @jaakerblom ha pubblicato un exploit funzionante su github il 1 giugno: https://github.com/potmdehex/multipath_kfree La tecnica di John è simile alla mia ma lui fa un overflow di due byte invece di tre, e sostituisce con oggetti diversi. roba buona!

Scarica lo strumento