FlawOpen

flawopen.com/Teardowns/cve-2023-6246-glibc-syslog-heap-buffer-overflow

● CVE-2023-6246 · CVSS 7.8 · Haute
Recherche · FlawOpen

CVE-2023-6246 : overflow heap de glibc syslog

CVE-2023-6246 est un débordement de heap dans syslog de glibc, déclenché par un en-tête long. Installez le paquet glibc corrigé de votre distribution.

💡 Explication en Langage Simple (ELI5)

Imaginez un employé qui mesure un colis et son étiquette avec une petite règle. L’étiquette ne tient pas, donc le calcul n’enregistre pas l’espace nécessaire. Il commande alors une boîte minuscule et tente d’y imprimer toute l’étiquette et le contenu. Dans glibc, un en-tête syslog long pouvait laisser la taille requise indéterminée et faire allouer trop peu de mémoire heap par le journaliseur.

Concepts Clés et Termes

glibc
La GNU C Library fournit des fonctions centrales du runtime C utilisées par la plupart des programmes Linux.
__vsyslog_internal()
Implémentation interne de glibc utilisée par syslog() et vsyslog() pour formater le message et son SYSLOG_HEADER avant son envoi au journaliseur système.
SYSLOG_HEADER
Préfixe de priorité et d’identification formaté avant le message syslog. Il peut inclure le nom du programme ou un identifiant fourni à openlog().
Heap-based buffer overflow (CWE-122)
Une écriture dépasse les limites d’un tampon alloué sur le heap. Ici, le calcul échouait quand l’en-tête avec un nom long ne tenait pas dans le tampon fixe initial.

Correspondances de référentiels

  • Référence CWE pour la faiblesse décrite dans ce guide : CWE-122

Analyse de Cause Racine

L’avis glibc indique que __vsyslog_internal() ne mettait pas à jour la taille requise lors du formatage d’un SYSLOG_HEADER contenant un nom de programme long. Dans le code vulnérable, la longueur l de l’en-tête pouvait atteindre ou dépasser le tampon de pile de 1 024 octets ; la branche qui formatait le corps du message et définissait bufsize était alors ignorée. L’allocation heap suivante utilisait une taille non définie ou nulle, puis écrivait l’en-tête et le message dans un espace trop petit. Qualys précise que le nom long peut provenir du basename d’un argv[0] contrôlé par l’appelant ou d’un identifiant openlog() de plus de 1 024 octets ; un programme setuid vulnérable qui journalise par ce chemin peut rendre le défaut sensible. Qualys a démontré une élévation locale de privilèges via su sur Fedora 38. Le risque dépend de l’accès local, de la configuration et du chemin d’appel ; ce n’est pas un exploit syslog distant générique.

Déroulement de l'Attaque Étape par Étape

Étape 1

Précondition locale

Un processus local doit atteindre syslog() ou vsyslog() par un programme utilisant la glibc affectée. L’impact de sécurité suppose un appelant privilégié et un chemin qui ne remplace pas le préfixe du nom du programme par un identifiant sûr et borné.

Étape 2

En-tête long

L’en-tête dépasse le tampon initial|Le SYSLOG_HEADER inclut un nom de programme long (__progname, dérivé du basename de argv[0]) ou un identifiant openlog() long. Qualys indique que la valeur déclenchante doit dépasser 1 024 octets.

Étape 3

Calcul incomplet

La branche de calcul de taille est ignorée|Lorsque l’en-tête ne tient pas dans le tampon de pile de 1 024 octets, le code vulnérable ignore la branche qui calcule bufsize. L’allocation heap n’a alors pas assez d’espace pour l’en-tête et le message formaté.

Étape 4

Impact mémoire

L’écriture dépasse l’allocation|Le journaliseur écrit l’en-tête et le message dans un tampon trop petit et corrompt le heap. Qualys a démontré une élévation locale via su sur Fedora 38 ; ne généralisez pas cette exposition à toutes les applications ou distributions.

Code Source : Vulnérable vs Sécurisé

L’ancienne branche laissait bufsize à zéro lorsque l’en-tête ne tenait pas dans le tampon de pile ; l’allocation heap pouvait donc être trop petite. Le correctif marque ce tampon comme inutilisable, l’emploie pour mesurer le corps, enregistre l + vl, puis reprend le chemin d’allocation existant avec la taille nécessaire. Ce sont des extraits ciblés upstream, pas des fonctions complètes autonomes.

Extrait source: misc/syslog.c

IMPLÉMENTATION VULNÉRABLE
/* Extrait ciblé de misc/syslog.c avant le commit 6bd0e4efcc78. */
char bufs[1024];
char *buf = NULL;
size_t bufsize = 0;
...
if (0 <= l && l < sizeof bufs)
  {
    va_list apc;
    va_copy (apc, ap);
    int vl = __vsnprintf_internal (bufs + l, sizeof bufs - l, fmt, apc,
                                   mode_flags);
    if (0 <= vl && vl < sizeof bufs - l)
      buf = bufs;
    bufsize = l + vl;
    va_end (apc);
  }
/* Un en-tête long contourne la branche précédente qui définit la taille. */
PATCH SÉCURISÉ ET ROBUSTE
/* Extrait ciblé de misc/syslog.c après le commit 6bd0e4efcc78. */
char bufs[1024];
char *buf = bufs;
size_t bufsize;
...
if (0 <= l && l < sizeof bufs)
  {
    pos = bufs + l;
    len = sizeof (bufs) - l;
  }
else
  {
    buf = NULL;
    pos = bufs;
    len = sizeof (bufs);
  }
vl = __vsnprintf_internal (pos, len, fmt, apc, mode_flags);
if (!(0 <= vl && vl < len))
  buf = NULL;
bufsize = l + vl;

Liste de Contrôle de Sécurité pour l'Ingénierie

Sources