Écrasement de l'exe runc

Lorsque runc exécute un processus à l'intérieur d'un conteneur, le conteneur peut abuser de la façon dont runc se ré-exécute via /proc/self/exe. Une image malveillante amène le processus d'entrée à obtenir un handle en écriture sur le binaire runc de l'hôte et à l'écraser, de sorte que la prochaine opération de conteneur exécute le code de l'attaquant en tant que root sur l'hôte.

2 min de lecturemis à jour le 12 oct. 2026florianamette1 contributeur
Demander à votre assistant (MCP)Modifier sur GitHub

Pour créer ou entrer dans un conteneur, runc se ré-exécute à l'intérieur des namespaces du conteneur via /proc/self/exe, un lien symbolique que le noyau maintient vers l'exécutable en cours d'exécution, qui pointe ici vers le binaire runc de l'hôte. L'évasion classique abuse du moment où le propre code du conteneur s'exécute avec un chemin de descripteur de fichier qui se résout encore vers ce binaire de l'hôte. Une image malveillante fait en sorte que son processus d'entrée ouvre /proc/self/exe (le runc de l'hôte) en écriture, ou qu'il soit un chargeur dynamique ou un shim de script permettant au conteneur d'influencer ce que runc ré-exécute, et écrase le binaire. Comme runc s'exécute en tant que root sur l'hôte pour chaque action du cycle de vie du conteneur, le binaire écrasé exécute le code de l'attaquant en tant que root sur l'hôte la prochaine fois qu'un conteneur est démarré ou intégré.

Confirmez le runtime et la fenêtre de versions :

bash
runc --version 2>/dev/null                  # pre-fix runc (older 1.0-rc line) is affected
readlink /proc/self/exe                     # resolves to the runtime binary during entry

Technique#

bash
# A malicious image ships an entrypoint that, when runc execs into it:
# 1. Opens /proc/self/exe, which still resolves to the host runc binary
# 2. Holds the descriptor until runc has dropped into the container, then
#    reopens it via /proc/self/fd/<n> for writing and overwrites the ELF
# 3. Writes a payload binary in place of runc
# Minimal shape of the entry payload:
exec 3< /proc/self/exe                       # fd to the host runc
# busy-wait until the fd is writable (runc has finished its exec), then:
cat payload_elf > /proc/self/fd/3            # overwrite host runc on disk

Le prochain create/start/exec de conteneur sur l'hôte invoque le runc désormais malveillant, exécutant la charge en tant que root sur l'hôte.

Notes d'exploitation#

  • L'attaquant doit exécuter du code dans un conteneur depuis une image ou un processus qu'il contrôle ; c'est pourquoi il s'agit d'un risque majeur lorsqu'une plateforme exécute des images non fiables ou autorise un exec fourni par l'utilisateur.
  • Les correctifs font en sorte que runc opère sur une copie privée de lui-même en mémoire (un memfd scellé) de sorte que /proc/self/exe ne se résout plus vers le binaire de l'hôte sur disque ; les runtimes corrigés mettent la technique en échec.
  • Un écrasement réussi affecte chaque opération de conteneur ultérieure sur l'hôte, c'est donc à la fois une évasion et un mécanisme de persistance à l'échelle de l'hôte.

Références#