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
cve-2023-20768 — Analyse de CVE du noyau Android et PoC pour une confusion de types dans l'allocateur ION de MediaTek, couvrant le diffing de la cause racine, le déclenchement sans privilèges et l'évaluation de l'exploitabilité. | Kitploit
Outils/GitHubGitHub/murf-xd/cve-2023-20768
Sécurité AndroidAnalyse des VulnérabilitésExploitationRétro-ingénierieSécurité MobileAnalyse de BinairesExploitation de Binaires
GitHubmurf-xd/cve-2023-20768

cve-2023-20768

Analyse de CVE du noyau Android et PoC pour une confusion de types dans l'allocateur ION de MediaTek, couvrant le diffing de la cause racine, le déclenchement sans privilèges et l'évaluation de l'exploitabilité.

Voir le dépôt
il y a 15 joursPas 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

CVE-2023-20768 sur le Samsung Galaxy M32 — une étude d'atteignabilité

Résumé. CVE-2023-20768 est une confusion de type (CWE-843) dans l'allocateur ION de MediaTek. J'ai vérifié si elle est réellement exploitable sur un Samsung SM-M325F (Galaxy M32, Helio G80) sous le firmware de juillet 2022. Le code vulnérable est présent, et j'ai prouvé qu'il s'exécute sur cet appareil lorsqu'il est déclenché par un processus non privilégié. Je n'ai pas pu le transformer en exploit. Le chemin ioctl est borné par la validation des entrées, et le chemin qui contient la véritable lecture hors bornes ne traite que de véritables buffers ION, car une seconde vérification sur le pointeur dma_buf_ops rejette tout ce que je pourrais forger. Ce writeup explique comment j'en suis arrivé à cette conclusion, y compris une conclusion intermédiaire qui s'est révélée fausse.

La CVE est publique et corrigée. Tous les tests ont été effectués sur mon propre appareil, rooté avec Magisk.

Pourquoi cet appareil

Le bug se trouve dans le code ION de MediaTek, pas dans le Linux amont ni dans quoi que ce soit écrit par Samsung. MediaTek fournit son propre fork de l'allocateur Android ION dans le BSP distribué à tous les constructeurs qui utilisent ses puces. Le M32 utilise un Helio G80, il reçoit donc ce code. Le même téléphone avec un SoC Exynos ne serait pas du tout concerné.

Cause racine

J'ai extrait les images vmlinux de 2022 (vulnérable) et 2023 (corrigée) et je les ai comparées dans IDA. Deux fonctions ION ont changé :

Fonction20222023
ion_drv_file_to_bufferstrstr(name, "dmabuf")is_dma_buf_file()
_ion_ioctlstrcmp(name, "ion")is_dma_buf_file()

is_dma_buf_file n'existe pas dans l'image de 2022. Elle apparaît dans celle de 2023. Les deux fonctions décidaient donc si un struct file était un dma_buf en regardant un nom, et le correctif a remplacé cela par une véritable vérification de type. Confondre un objet ici signifie que le noyau lit un non-dma_buf comme s'il s'agissait d'un dma_buf.

Atteindre le code depuis l'espace utilisateur

Des deux, _ion_ioctl est celle qu'un processus non privilégié peut atteindre :

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")

La requête est un ion_custom_data { u32 cmd = 0; u64 arg; } pointant vers un ion_sys_data de 120 octets :

spoof.c construit cela.

Prouver que le dispatch s'exécute

Je ne pouvais pas simplement tracer. L'appareil bloque kprobe_events, set_ftrace_filter et function_graph via la politique SELinux de Samsung et le durcissement du noyau, et les printk d'ION sont masqués par des gardes de debug, donc dmesg reste silencieux.

J'ai donc utilisé les codes de retour comme oracle. Quatre requêtes, et la configuration de ce qui revient vous indique où l'exécution est passée :

C qui renvoie un succès signifie que le switch dispatch vraiment sur sys_cmd. A et B qui diffèrent signifie que la VA est traitée, ce qui place l'exécution dans find_vma. C'est le chemin vulnérable, atteint sans root.

Là où ça s'est arrêté

Atteindre la vérification n'est pas la même chose que la contourner. J'ai testé ce que le strcmp accepte réellement :

  • Un véritable buffer ION mappé via ION_IOC_SHARE puis mmap passe, renvoie 0.
  • Un memfd nommé memfd:ion échoue, -EFAULT.
  • Un fichier ordinaire littéralement nommé ion échoue aussi, -EFAULT.

Le champ comparé à vm_file+0x60 n'est donc pas le nom de fichier. Il est interne à dma_buf, presque certainement dma_buf->exp_name, qu'ION définit à "ion". La vérification est non fiable par conception, mais rien de ce que je peux créer depuis l'espace utilisateur ne peut définir ce champ.

J'ai ensuite fuzzé le chemin : sync_type 0 à 7, tailles {0, 1, 0x1000, 0x100000, 0xffffffff}, VA {véritable buffer ion, memfd, 0}, 120 cas, plus une sonde de handle libéré pour un use-after-free. Aucun crash, l'appareil est resté allumé. Les tailles démesurées sortent avant find_vma et renvoient 0. Les types de sync 3 à 5 empruntent le chemin m4u et renvoient -EPERM. Tout ce qui est au-dessus de 5 renvoie -EINVAL. Un handle libéré renvoie -EINVAL, donc ION le valide et il n'y a pas de UAF ici.

L'autre fonction, et une fausse piste

La véritable lecture hors bornes se trouve dans ion_drv_file_to_buffer. Elle fait ldr [private_data+0x28], lisant le private_data d'un non-dma_buf comme s'il s'agissait d'un dma_buf. Il y a une comparaison ops == &ion_dma_buf_ops (la table est à 0xFFFFFF800A097F18), mais elle a lieu après cette lecture, donc elle ne l'empêche pas. En aval, __do_dump_share_fd lit les champs à +0x28, +0x48, +0x50, +0xb8, +0xe4 du buffer renvoyé et les affiche, et ldr x8, [buf+0x28]; ldr [x8+0x30] est un déréférencement de pointeur sauvage pour un objet confondu.

Le déclencheur est ion_dump_all_share_fds, qui utilise iterate_fd pour parcourir les descripteurs de fichiers de chaque processus client ION. Ma première conclusion était que cela ne s'exécute que lorsqu'on lit un nœud debugfs d'ION, et ce noyau a CONFIG_DEBUG_FS désactivé. Je l'ai vérifié de trois manières : /proc/config.gz, debugfs absent de /proc/filesystems, et mount -t debugfs qui renvoie ENODEV. J'ai considéré ce chemin comme structurellement inaccessible.

C'était faux. dump_header, le vidage mémoire du killer OOM, contient un bl ion_mm_heap_memory_detail direct à 0xffffff8008204b9c, et dump_header est appelé depuis out_of_memory et oom_kill_process. Aucun debugfs nécessaire.

memcg_oom.c le confirme. Il crée un cgroup sous /dev/memcg, plafonne à la fois memory.limit_in_bytes et memory.memsw.limit_in_bytes à 8 Mo (plafonner uniquement le premier laisse l'enfant s'échapper dans le swap zram), et fork un enfant qui alloue jusqu'à mourir. dmesg affiche alors :

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

suivi de la sortie complète de ion_mm_heap_memory_detail et de __do_dump_share_fd résolvant de véritables gralloc dma_bufs. La fonction vulnérable s'exécute donc, pendant quelque chose que n'importe quel processus non privilégié peut provoquer. Il existe aussi un troisième déclencheur, ShowStatus de hang_detect_dump_thread dans le watchdog MediaTek.

Pourquoi cela ne fonctionne toujours pas

J'ai maintenu 32 memfds nommés memfd:dmabuf et déclenché le même OOM memcg. Si l'un des miens avait été passé à ion_drv_file_to_buffer, le strstr serait passé, private_data aurait été NULL, et le noyau aurait affiché [ION]ion_drv_file_to_buffer warnning, dmabuf is NULL en KERN_ERR. Cette ligne n'est jamais apparue. Seuls les clients graphiques et gralloc ont été vidés. Soit la table de fd d'un simple client /dev/ion n'est pas ce que iterate_fd parcourt ici, soit memfd échoue silencieusement avant le print.

Dans les deux cas, le vidage OOM ne traite que les dma_bufs légitimes du système, qui passent proprement. memfd est aussi le seul type de fd dont je peux contrôler suffisamment le nom pour contenir « dmabuf », et il ne peut pas faillir.

Verdict

La vulnérabilité est présente. Le code vulnérable est atteignable et s'exécute réellement sur cette build, déclenchable sans root. Il n'est pas transformable en exploit depuis l'espace utilisateur ici. Le chemin ioctl est borné par la validation du handle, une vérification de taille et access_ok. Le chemin de vidage ne voit que de véritables buffers ION, et la contrefaçon est bloquée par ops == &ion_dma_buf_ops. Aller plus loin nécessiterait un objet non-ION contrôlable dont exp_name est "ion", ou une autre primitive telle qu'un UAF de buffer ION, ou une course TOCTOU.

Fichiers

  • spoof.c — PoC ioctl de cache-sync et oracle différentiel
  • memcg_oom.c — déclencheur OOM memcg pour le chemin de vidage
  • trigger.c, oom_trigger.c — tentatives de déclenchement antérieures
  • boot_images/ — images du noyau extraites (2022 et 2023) et la base de données IDA pour la build 2022
Télécharger l’outil
DécalageChamp
+0x00sys_cmd = 0
+0x08handle ion (en allouer un d'abord, heap_id_mask = 0x1 fonctionne)
+0x10adresse virtuelle utilisateur
+0x18moitié basse = taille, moitié haute = sync_type dans {0,1,2}
CasRequêteRésultat
Asys_cmd=0, VA usurpée-EFAULT
Bsys_cmd=0, VA = 00
Csys_cmd=40
Dsys_cmd=99-EFAULT