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
cve-2023-20768 — Análise de CVE do kernel Android e PoC para uma confusão de tipo no alocador ION da MediaTek, abrangendo diffing de causa raiz, gatilho sem privilégios e avaliação de explorabilidade. | Kitploit
Ferramentas/GitHubGitHub/murf-xd/cve-2023-20768
Segurança AndroidAnálise de VulnerabilidadesExploraçãoEngenharia ReversaSegurança MóvelAnálise de BináriosExploração de Binários
GitHubmurf-xd/cve-2023-20768

cve-2023-20768

Análise de CVE do kernel Android e PoC para uma confusão de tipo no alocador ION da MediaTek, abrangendo diffing de causa raiz, gatilho sem privilégios e avaliação de explorabilidade.

Ver Repositório
há 16 diasAinda 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

CVE-2023-20768 no Samsung Galaxy M32 — um estudo de alcançabilidade

Resumo. CVE-2023-20768 é uma confusão de tipo (CWE-843) no alocador ION da MediaTek. Verifiquei se ela é realmente explorável em um Samsung SM-M325F (Galaxy M32, Helio G80) rodando o firmware de julho de 2022. O código vulnerável está presente, e provei que ele executa neste dispositivo quando acionado por um processo sem privilégios. Não consegui transformá-la em uma arma. O caminho do ioctl é limitado por validação de entrada, e o caminho que contém a verdadeira leitura fora dos limites só processa buffers ION genuínos, porque uma segunda verificação no ponteiro dma_buf_ops rejeita qualquer coisa que eu pudesse forjar. Este relatório cobre como cheguei a essa conclusão, incluindo uma conclusão intermediária que se revelou errada.

O CVE é público e já foi corrigido. Todos os testes foram feitos no meu próprio dispositivo, com root via Magisk.

Por que este dispositivo

O bug está no código ION da MediaTek, não no Linux upstream nem em nada escrito pela Samsung. A MediaTek distribui seu próprio fork do alocador ION do Android no BSP que vai para todos os fornecedores que usam seus chips. O M32 usa um Helio G80, então recebe esse código. O mesmo telefone com um SoC Exynos não seria afetado de forma alguma.

Causa raiz

Extraí as imagens vmlinux de 2022 (vulnerável) e 2023 (corrigida) e as comparei no IDA. Duas funções do ION mudaram:

Função20222023
ion_drv_file_to_bufferstrstr(name, "dmabuf")is_dma_buf_file()
_ion_ioctlstrcmp(name, "ion")is_dma_buf_file()

is_dma_buf_file não existe na imagem de 2022. Ela aparece na de 2023. Então ambas as funções decidiam se um struct file era um dma_buf olhando para um nome, e a correção substituiu isso por uma verificação de tipo real. Confundir um objeto aqui significa que o kernel lê um não-dma_buf como se fosse um.

Alcançando o código a partir do userspace

Das duas, _ion_ioctl é a que um processo sem privilégios consegue alcançar:

root@kitploit:~
open("/dev/ion")
  -> ion_ioctl                      (.unlocked_ioctl)
  -> ION_IOC_CUSTOM  (0xC0104906)
  -> ion_custom_ioctl
  -> _ion_ioctl
  -> case 0: ION_SYS_CACHE_SYNC
  -> find_vma(user_VA)              (call site at _ion_ioctl+0x9f0)
  -> strcmp(vma->vm_file...name, "ion")

A requisição é uma ion_custom_data { u32 cmd = 0; u64 arg; } apontando para um ion_sys_data de 120 bytes:

spoof.c constrói isso.

Provando que o despacho ocorre

Não pude simplesmente rastreá-lo. O dispositivo bloqueia kprobe_events, set_ftrace_filter e function_graph por meio da política SELinux da Samsung e do endurecimento do kernel, e os printks do ION são limitados por debug, então o dmesg permanece silencioso.

Então usei códigos de retorno como um oráculo. Quatro requisições, e o padrão do que retorna indica para onde a execução foi:

O caso C retornando sucesso significa que o switch realmente está despachando com base em sys_cmd. A e B diferirem significa que o VA está sendo processado, o que coloca a execução dentro de find_vma. Esse é o caminho vulnerável, alcançado sem root.

Onde parou

Alcançar a verificação não é o mesmo que vencê-la. Testei o que o strcmp realmente aceita:

  • Um buffer ION real mapeado via ION_IOC_SHARE e depois mmap passa, retorna 0.
  • Um memfd chamado memfd:ion falha, -EFAULT.
  • Um arquivo comum literalmente chamado ion também falha, -EFAULT.

Portanto, o campo comparado em vm_file+0x60 não é o nome do arquivo. Ele é interno ao dma_buf, quase certamente dma_buf->exp_name, que o ION define como "ion". A verificação é insegura por design, mas nada que eu possa criar a partir do userspace consegue definir esse campo.

Então fiz fuzzing no caminho: sync_type de 0 a 7, tamanhos {0, 1, 0x1000, 0x100000, 0xffffffff}, VAs {buffer ION real, memfd, 0}, 120 casos, além de uma sonda de handle liberado para um use-after-free. Sem crash, o dispositivo permaneceu de pé. Tamanhos acima do limite saem antes de find_vma e retornam 0. Os sync types 3 a 5 caem no caminho do m4u e retornam -EPERM. Qualquer valor acima de 5 retorna -EINVAL. Um handle liberado retorna -EINVAL, então o ION o valida e não há UAF ali.

A outra função, e um caminho errado

A verdadeira leitura fora dos limites está em ion_drv_file_to_buffer. Ela faz ldr [private_data+0x28], lendo o private_data de um não-dma_buf como se fosse um dma_buf. Há uma comparação ops == &ion_dma_buf_ops (a tabela está em 0xFFFFFF800A097F18), mas ela ocorre depois dessa leitura, então não a impede. Mais adiante, __do_dump_share_fd lê campos em +0x28, +0x48, +0x50, +0xb8, +0xe4 do buffer retornado e os imprime, e ldr x8, [buf+0x28]; ldr [x8+0x30] é um desreferenciamento de ponteiro selvagem para um objeto confundido.

O gatilho é ion_dump_all_share_fds, que usa iterate_fd para percorrer os descritores de arquivo de cada processo cliente do ION. Minha primeira conclusão foi que isso só roda quando você lê um nó do debugfs do ION, e este kernel tem CONFIG_DEBUG_FS desativado. Verifiquei isso de três maneiras: /proc/config.gz, debugfs ausente de /proc/filesystems e mount -t debugfs retornando ENODEV. Descartei o caminho como estruturalmente inalcançável.

Isso estava errado. dump_header, o despejo de memória do OOM killer, contém um bl ion_mm_heap_memory_detail direto em 0xffffff8008204b9c, e dump_header é chamado a partir de out_of_memory e oom_kill_process. Nenhum debugfs é necessário.

memcg_oom.c confirma isso. Ele cria um cgroup sob /dev/memcg, limita tanto memory.limit_in_bytes quanto memory.memsw.limit_in_bytes a 8MB (limitar apenas o primeiro permite que o filho escape para o swap zram), e faz um fork de um filho que aloca até morrer. O dmesg então mostra:

root@kitploit:~
dump_header <- oom_kill_process <- out_of_memory <- mem_cgroup_oom_synchronize

seguido pela saída completa de ion_mm_heap_memory_detail e __do_dump_share_fd resolvendo dma_bufs gralloc reais. Portanto, a função vulnerável executa durante algo que qualquer processo sem privilégios pode causar. Há também um terceiro gatilho, ShowStatus de hang_detect_dump_thread no watchdog da MediaTek.

Por que ainda não funciona

Segurei 32 memfds chamados memfd:dmabuf e acionei o mesmo OOM do memcg. Se algum dos meus tivesse sido passado para ion_drv_file_to_buffer, o strstr passaria, private_data seria NULL, e o kernel imprimiria [ION]ion_drv_file_to_buffer warnning, dmabuf is NULL em KERN_ERR. Essa linha nunca apareceu. Apenas clientes de gráficos e gralloc foram despejados. Ou a tabela de fd de um cliente comum de /dev/ion não é o que iterate_fd percorre aqui, ou o memfd falha silenciosamente antes do print.

De qualquer forma, o despejo do OOM só lida com os dma_bufs legítimos do sistema, que passam limpos. memfd também é o único tipo de fd cujo nome consigo controlar o suficiente para conter "dmabuf", e ele não consegue falhar.

Veredito

A vulnerabilidade está presente. O código vulnerável é alcançável e de fato executa nesta compilação, acionável sem root. Ele não é transformável em arma a partir do userspace aqui. O caminho do ioctl é limitado pela validação do handle, uma verificação de tamanho e access_ok. O caminho do despejo só vê buffers ION reais, e a falsificação é bloqueada por ops == &ion_dma_buf_ops. Ir mais longe exigiria um objeto não-ION controlável cujo exp_name seja "ion", ou uma primitiva diferente, como um UAF de buffer ION, ou uma corrida TOCTOU.

Arquivos

  • spoof.c — PoC do ioctl de cache-sync e o oráculo diferencial
  • memcg_oom.c — gatilho de OOM do memcg para o caminho do despejo
  • trigger.c, oom_trigger.c — tentativas anteriores de gatilho
  • boot_images/ — imagens de kernel extraídas (2022 e 2023) e o banco de dados do IDA para a compilação de 2022
Baixar ferramenta
OffsetCampo
+0x00sys_cmd = 0
+0x08handle do ION (aloque um primeiro, heap_id_mask = 0x1 funciona)
+0x10endereço virtual do usuário
+0x18metade baixa = tamanho, metade alta = sync_type em {0,1,2}
CasoRequisiçãoResultado
Asys_cmd=0, VA forjado-EFAULT
Bsys_cmd=0, VA = 00
Csys_cmd=40
Dsys_cmd=99-EFAULT