27/12/2024

LinuxServices

binfmt_misc : convertir un simple fichier en binaire sous Linux

I. Présentation

Vous le savez peut-être, GNU/Linux peut faire aussi bien que Microsoft Windows en matière de typage de fichiers. En effet, depuis la version du noyau Linux 2.1.43, il est possible pour les administrateurs système de recenser les interpréteurs des différents binaires, à partir d’un nombre magique ou de l’extension du fichier. Cela permet à l’interpréteur idoine d’être appelé lorsqu’un fichier correspondant aux différents critères doit être exécuté.

En résumé, on peut considérer cette fonctionnalité noyau comme une version plus souple et plus configurable du mécanisme d’interpréteur exécutable appelé le shebang : #!.

Je vais donc vous parler dans ce billet de binfmt_misc (aussi appelé Miscellaneous Binary Format). Les formats d’exécutables sont enregistrés au travers d’un système de fichiers particulier : binfmt_misc, monté habituellement sous le pseudo-système de fichiers /proc.

 

REMARQUE : Si cela revient à rendre exécutable n’importe quel fichier, vous me direz qu’il suffit d’exécuter la commande ‘chmod +x’ sur celui-ci. Seulement, le noyau Linux risque de nous renvoyer une erreur à cause du format de ce même fichier qui n’est pas, de son point de vue, reconnu comme exécutable.

Avant de développer notre sujet, un petit rappel concernant les formats de fichiers sous Unix/Linux. Les types de fichiers sous Unix (et par héritage sous GNU/Linux), sont déterminés grâce à la commande file. Mais, on peut tout à fait scruter le contenu du fichier via la commande suivante qui extrait la 1ère ligne de celui-ci :

# od -c <Fichier> | head -n 1

Exemple : si l’on prend le fichier /bin/ls, on trouve le résultat suivant :

Ce résultat est intéressant, car il fait apparaître le type 177 associé au texte ELF. Ceci est confirmé, lorsqu’on interroge le fichier /bin/ls au travers de la commande file :

Il s’agit bien d’un fichier binaire exécutable au format ELF-64bits appelable au travers de la bibliothèque /lib64/ld-linux-x86-64.so.2. Dans ce tutoriel, je vous propose de transformer ainsi vos fichiers .jar, .mp3, .c ou autres, en fichier exécutable : à savoir que la commande souhaitée sera automatiquement exécutée.

II. A l'exécution

Afin d’exécuter un fichier binaire, le noyau lit les premiers octets dudit fichier et vérifie qu’il correspond bien à un format binaire (binfmt) connu. Or, il existe un mécanisme d’ajout de formats binaires à ceux déjà supportés dans le noyau (c’est-à-dire les types elf évoqués ci-dessus, et les scripts Shell). Il s’agit du format misc. Maintenant, pour pouvoir interpréter tout type de fichiers comme un binaire, il faut activer ce type de format. Pour vérifier si celui-ci est présent sur votre système, il suffit d’exécuter la commande suivante :

$ cat /proc/sys/fs/binfmt_misc/status

REMARQUE : par défaut, sur les distributions Linux récentes, la réponse à cette commande devrait être ‘enabled’. Si ce n’est pas le cas, il faut alors installer le module binfmt_misc et monter le répertoire d’ancrage :

$ modprobe binfmt_misc
$ mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc

Maintenant, prenons le cas concret d’un fichier gzip que l’on souhaite autoriser à être exécuté en direct sou GNU/Linux. Pour cela, il faut se souvenir que plutôt que de reconnaître le fichier à son extension et exécuter ensuite l’utilitaire gzip, on va faire en sorte de détecter ce type de fichier. Un tel fichier se reconnaît à ses deux premiers octets qui doivent avoir la valeur respective de 0x1f et 0x8b. Il suffit alors d’enregistrer dans le fichier register, se trouvant dans l’arborescence /proc/sys/fs/binfmt_misc l’association du type et de sa fonctionnalité :

$ echo ‘:gzip :M ::\x1f\x8b ::/bin/gunzip :’ > /proc/sys/fs/binfmt_misc/register

Dans le cas d’un simple fichier texte, ce que l’on cherche à faire c’est généralement de l’éditer (ou du moins de lister son contenu via la commande less). On peut donc exécuter l’instruction suivante permettant d’enregistrer ce mode de fonctionnement :

$ echo ‘:format-txt:E::txt::/usr/bin/less:’ > /proc/sys/fs/binfmt_misc/register

REMARQUE : à ce stade, un message d’erreur est considéré comme anormal. Il faut donc revérifier la saisie complète et stricte des caractères de la ligne ci-dessus.

Si l’on exécute l’instruction ci-dessous on devrait recevoir un message d’exécution de la commande /usr/bin/less :

$ cat /proc/sys/fs/binfmt_misc/format-txt
enabled
interpreter /usr/bin/less
flags:
extension .txt

A ce stade, il ne reste plus qu’à marquer le fichier texte en tant qu’exécutable via la commande chmod :

$ chmod a+x <Fichier>.txt

On peut alors exécuter ce fichier en tapant la commande suivante :

$ ./<Fichier>.txt

REMARQUE : en se basant sur ce même principe, on peut ainsi facilement rendre un fichier .rpm exécutable ou n’importe quel autre type de fichier audio ou vidéo.

III. Les formats d'enregistrement

Le fichier registrer contient les lignes que l’on a définies comme des types exécutables. Chaque ligne est de la forme suivante :

:<nom>:<Type>:<Offset>:<Magic>:<Masque>:<Interpreter>:<Flags>

<Nom> représente le nom du format binaire. Le <Type> peut prendre la valeur ‘E’ lorsque le format est identifié par son extension de fichier et que l’on précise alors <Magic> comme étant l’extension associée au format binaire (les champs <Offset> et <Masque> sont alors ignorés). Si la valeur du champ <Type> est ‘M’, le format est alors identifié par son champ <Magic> avec un offset absolu du fichier et <Masque> précise quel(s) bit(s) dans le champ <Magic> sont significatifs. (Voir l’exemple du format gzip ci-dessus).

Ensuite, le champ <Interperter> décrit le programme qui doit être exécuté pour le format de fichier associé. Le champ <Flags> peut prendre les valeurs ci-dessous :

  • P: préserve argv0.
  • : ouvre le programme et passe son descripteur de fichier en mode binaire.
  • C: préserve les “credentials“ du programme plutôt que son interpréteur.
  • F : fixe le noyau ouvert en mode binaire (laissant celui-ci disponible au montage dans les espaces nommés et les cantonnements chroot.

IV. Exploitation du système binfmt_misc

Avant de savoir activer ou désactiver le mécanisme binfmt_misc il convient de savoir repérer si son système de fichiers est monté. Pour se faire, il suffit d’exécuter la commande suivante :

# grep /binfmt /proc/mounts
binfmt_misc /proc/sys/fs/binfmt_misc binfmt_misc rw,relatime 0 0

Il est également possible de déterminer si cette fonctionnalité est présente au sein du noyau. Si l’on dispose des sources de compilation du noyau, il suffit simplement d’exécuter la commande suivante :

# zcat /proc/config.gz | grep -I binfmt_misc
CONFIG_BINFMT_MISC=y

Si le système n’était pas monté, il suffirait de le faire via l’instruction ci-dessous, que l’on a déjà mentionnée précédemment :

# mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc

Maintenant, pour activer binfmt_misc, il suffit de taper la commande suivante :

# echo 1 > /proc/sys/fs/binfmt_misc/status

À l’inverse, pour désactiver le mécanisme binfmt_misc on doit exécuter l’instruction ci-dessous :

# echo 0 > /proc/sys/fs/binfmt_misc/status

REMARQUE : en éditant la valeur -1 dans le fichier /proc/sys/fs/binfmt_misc/status, on peut alors supprimer une association particulière ou toutes les associations. Après quoi, il ne faut pas oublier de démonter le système de fichiers associé:

# umount /proc/sys/fs/binfmt_misc

Lorsque le mécanisme binfmt_misc est actif, on peut utiliser l’outil findmnt pour localiser le point de montage de l’interpréteur :

V. Automatisation

Il n’y a qu’un petit problème avec ce mécanisme. Comme beaucoup de fonctionnalités intégrées sous forme de modules, lors d’un redémarrage les associations précédemment effectuées sous une session antérieure sont perdues. Afin de rendre systématiques toutes ces associations dans le fichier register, on va créer un fichier de configuration binfmt.conf que l’on placera dans le répertoire /etc.

Exemple : voici un petit aperçu des associations standards :

# pour en savoir plus sur le format des lignes de configuration
# que l'on peut envoyer a /proc/sys/fs/binfmt_misc/register
# lire /usr/src/linux/Documentation/binfmt_misc.txt
# on associe les .pdf à Acrobat reader
 :pdf-acrobat:E::pdf::/opt/acrobat/bin/acroread:

# on associe les .png et .gif à ElectricEyes
 :png-gimp:E::png::/opt/gnome/bin/ee:
 :gif-gimp:E::gif::/opt/gnome/bin/ee:

# on associe les .rpm à kpackage
 :rpm-kpackage:E::rpm::/usr/bin/kpackage:

# on associe les .txt et .doc à gless
 :txt-gless:E::txt::/opt/gnome/bin/gless:

Après cela, on peut ajouter la ligne ‘/usr/sbin/binfmt’ au fichier /etc/rc.d/rc.sysinit (ou dans rc.local sur une CentOS) afin que les associations soient chargées dès le démarrage du système GNU/Linux.

Ensuite, nous allons écrire un petit script dans /usr/sbin appelé binfmt dans lequel nous placerons les instructions suivantes :

Ce script lit une à une les lignes du fichier /etc/binfmt.conf en rejetant celles commençant par le caractère ‘#’ de commentaire, et les envoie directement dans le fichier /proc/sys/fs/binfmt_misc/register. Ce programme permet également de détecter le cas échéant si le module est bien activé et si la fonctionnalité binfmt_misc est opérationnelle.

REMARQUE : en cas d’erreur lors de l’activation ou la désactivation de cette fonctionnalité, il est toujours possible d’interroger le ring buffer de la manière suivante :

# dmesg|grep binfmt_misc

Il faut aussi penser à interroger le module courant de la fonctionnalité en exécutant la commande suivante :

 

VI. Conclusion

On peut ainsi parfaire les fonctionnalités d’exécution de Linux en plaçant dans le fichier /etc/binfmt.conf l’ensemble des associations que l’on souhaite rendre exécutables. Elles seront alors reconnues par tout gestionnaire de système de fichiers sous Linux sans aucune manipulation supplémentaire.

ATTENTION : il ne faut pas manquer de marquer comme exécutable, la plupart des fichiers que l’on aura associé. C’est le cas notamment, par défaut, des fichiers se trouvant sur des partitions vfat et/ou iso9660.

Mon côté paranoïaque fait que je m’interroge malgré tout sur cette merveilleuse idée que représente le format misc : ne serait-ce pas là aussi une faille de sécurité ? Car après tout si un pirate prend possession de notre serveur, rien ne l’empêche de rendre exécutable ses propres programmes .php, .perl, .java

Mais, bon, cela n’en reste pas moins une fonctionnalité intéressante (et ma foi peu connu de Linux). Ceci vous permettra notamment de rendre vos fichiers .mp3, .au ou autres formats d’applications tout à fait exécutables, automatiquement, en appelant le bon programme associé.

author avatar
Philippe PIERRE
A exercé de nombreuses années en tant qu'administrateur de base de données et comme administrateur Système Unix/Linux. Il a enseigné les réseaux au CNAM (Paris). Aujourd'hui, employé en tant qu'ingénieur infrastructure, au sein d'un laboratoire pharmaceutique et administrant un cluster de calculs HPC, il connaît parfaitement les environnements GNU/Linux dans le cadre d'une entreprise et des systèmes de haute disponibilité. Il aime partager son expérience.
Partagez cet article Partager sur Twitter Partager sur Facebook Partager sur Linkedin Envoyer par mail

2 commentaires sur “binfmt_misc : convertir un simple fichier en binaire sous Linux

    • Bonsoir. Merci pour votre soutien.
      Effectivement de nombreux outils permettent de faire de la détection préventive.
      Merci pour le lien je vais récupérer cela. Il faut vraiment que je me mette à développer en Python.
      Mais, binfmt_misc comme toute technique possède deux aspects: un positif permettant ici de rendre des fichiers exécutables rapidement et l’autre plus risqué pouvant engendrer des failles de sécurité.
      Je pense qu’il faut savoir faire la part des choses et connaître cette technique. Même si celle-ci est quelque peu à risque.
      Bonne soirée.

      Répondre

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.