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
multi_path — CVE-2018-4241: estouro de heap do kernel XNU devido a verificação de limites inadequada no MPTCP para iOS 11 - 11.3.1lançado por Ian Beer | Kitploit
Ferramentas/GitHubGitHub/0neday/multi_path
Frameworks de ExploraçãoSegurança iOSForensia de MemóriaAnálise de VulnerabilidadesExploraçãoSegurança MóvelExploração de Binários
GitHub0neday/multi_path

multi_path

CVE-2018-4241: estouro de heap do kernel XNU devido a verificação de limites inadequada no MPTCP para iOS 11 - 11.3.1lançado por Ian Beer

Ver Repositório
41há 8 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

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

@i41nbeer

mptcp_usr_connectx é o handler para a syscall connectx da família de sockets AP_MULTIPATH.

A lógica desta função falha ao lidar corretamente com sockaddrs de origem e destino que não são 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);
  }

Olhando ao redor na estrutura que você transborda, percebe que pode atingir ambos os campos aqui:

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

mpte_itfinfo_size está logo antes de mpte_itfinfo.

Quando a estrutura é inicializada, o ponteiro mpte_itfinfo aponta para um pequeno array inline. Se mais subfluxos forem adicionados do que caberão ali, eles são colocados em um buffer de heap, e mpte_itfinfo apontará para esse buffer.

Se você tivesse outro bug (por exemplo, o bug de divulgação de heap do kernel do async_wake), poderia sobrescrever o campo mpte_itfinfo com qualquer objeto de zona válido e ele seria liberado (na verdade, você também poderia sobrescrevê-lo com um offset dentro desse objeto para ainda mais diversão!)

No entanto, não temos isso.

Em vez disso, outra abordagem é sobrescrever parcialmente o ponteiro. Se o sobrescrevermos parcialmente com bytes NULL, podemos apontá-lo para um valor alinhado a 256 bytes, 65k, 16MB ou 4GB.

Neste exploit, escolho uma sobrescrita de 3 bytes NULL, que causará um kfree do endereço mpte_itfinfo arredondado para baixo até o próximo limite de 16MB.

O fluxo de exploração é o seguinte:

  • Alocar alternadamente 16MB de ipc_kmsgs seguidos por um monte de sockets mptcp. O objetivo aqui é obter uma alocação kalloc.2048 naquele limite de 16MB.
  • Usar o bug para liberar um dos ipc_kmsgs, movendo essa página para a lista intermediária e colocando a alocação alinhada a 16MB em uma freelist de página intermediária kalloc.2048.
  • Alocar um monte de pipes preenchidos de 2047 bytes; os buffers de suporte para esses pipes virão do kalloc.2048, esperançosamente incluindo nosso endereço alinhado a 16MB.
  • Acionar o bug uma segunda vez, liberando o mesmo endereço e então alocar um monte de buffers ipc_kmsg pré-alocados do kalloc.2048.
  • Agora, esperançosamente, temos um ipc_kmsg (para o qual podemos enviar mensagens e depois recebê-las) e um buffer de pipe (que podemos ler e escrever) sobrepostos um ao outro.
  • Eu uso o truque da porta de exceção de thread do extra_recipe para enviar mensagens ao buffer ipc_kmsg pré-alocado. Cada vez, verificamos cada um dos pipes para ver se algum contém a mensagem. Quando encontramos o par (ipc_kmsg, pipe) correto, podemos reescrever a mensagem para enviar a nós mesmos uma porta falsa que reside dentro do buffer do pipe. Estruturo essa porta falsa como a do async_wake (que baseei no yalu 10.2 por @qwertyoruiopz e @marcograss) para me dar uma primitiva inicial de leitura do kernel.
  • Usando a primitiva de leitura do kernel, encontro a tarefa do kernel e crio uma porta falsa que permite leitura/escrita mais fácil da memória do kernel via mach_vm_read/mach_vm_write.

Ressalva: Para conectar sockets mptcp, você precisa da permissão com.apple.developer.networking.multipath, que requer um certificado de desenvolvedor Apple, que qualquer um pode comprar da Apple.

Confiabilidade: Esta é uma ferramenta de pesquisa de segurança e está muuuuito longe de ser perfeita. No entanto, deve funcionar na maioria das vezes, e quando funciona, deve fazer um bom trabalho de limpeza para que não entre em pânico depois.

Para melhorar a probabilidade de funcionar:

  • desligar o wifi e entrar no modo avião
  • reiniciar
  • esperar 30 segundos após reiniciar
  • executar o aplicativo a partir do xcode

Dispositivos suportados: Deve funcionar no iOS 11.0 - 11.3.1 inclusive. Testei em: iPod Touch 6g, iPhone 6s, iPhone SE, iPhone 7, iPhone 8

API: #include "sploit.h" e chame go() para executar o exploit. Se funcionou, você pode usar as funções em kmem.h para ler e escrever memória do kernel

Notas: Várias pessoas fizeram bindiff público deste bug a partir do patch (ou seu 0day foi corrigido ;) leia o material deles para mais detalhes: @elvanderb deu uma palestra relâmpago sobre o bug no rump.beer em Paris em 31 de maio: https://www.rump.beer/2018/slides/ios_48h.pdf @jaakerblom publicou um exploit funcional no github em 1º de junho: https://github.com/potmdehex/multipath_kfree A técnica de John é semelhante à minha, mas ele faz um overflow de dois bytes em vez de três, e substitui com objetos diferentes. material bom!

Baixar ferramenta