Injection de commande et fonction system

La vulnérabilité de la fonction ‘system

La fonction system() exécute la commande entrée en paramètre en appelant /bin/sh -c et revient après l’exécution complète de cette commande.

Syntaxe :

#include <stdlib.h>
int system(const char *commande);

La fonction system est considérée comme vulnérable si on permet à l’utilisateur d’entrer la commande à exécuter, car dans ce cas on donne le contrôle au niveau système .

Exemple 1:

#include <stdio.h>                                                                          
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
/* lire le contenu d'un fichier texte avec les commandes cat et system */                                                                     
int main(char* argc, char** argv) { 
       char cat[] = "cat ";
       char *cmd = (char*)malloc((sizeof(cat)+sizeof(argv[1])+1)); 
       strncpy(cmd, cat, sizeof(cat)); 
       strncat(cmd, argv[1], sizeof(argv[1]));   
       system(cmd); 
       free(cmd);
       return(0);
}

L’exemple ci-dessus permet de lire le contenu d’un fichier texte qui est la phrase “Bonjour tous le monde !” , le nom de fichier devant être entré par l’utilisateur via la ligne de commande. Mais si on y ajoute “; ls” , on comprend qu’il exécute la commande ‘ls’ et qu’il affiche la liste du dossier courant du processus.

Maintenant si on modifie les propriétés de l’exécutable de telle sorte qu’il soit réellement exécuter par root et si on passe en paramètre le nom de fichier file.txt; ls -rf /la fonction system va d’abord exécuter la commande cat avec le nom de fichier “file.txt“, puis va exécuter la commande suivante qui affiche le contenu intégral du disque. Alors l’utilisateur peut choisir n’importe quelle commande et l’exécuter avec les privilèges de root.

Comment je peux détecter cette injection de commande ?

Le moyen le plus efficace pour prévenir les vulnérabilités d’injection de commandes du système d’exploitation est de ne jamais appeler les commandes du système d’exploitation à partir du code de la couche application. Et si ce n’est pas possible, alors la solution la plus évidente est la validation des entrées pour la fonction system‘, par exemple la chaîne saisie par l’utilisateur ne doit pas contenir l’un des séparateurs suivants :

  • ;
  • &
  • &&
  • ||
  • |
  • \n
  • `commande`
  • $(commande)

Exemple 2 :

#include <stdio.h>                                                                          
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
/* Validation des inputs d'utilisateur */                                                                     
int main(char* argc, char** argv) { 
    char cat[]="cat ";
    char nomFichier[40];
    scanf("%s", nomFichier);
    char *cmd = (char *)malloc((sizeof(cat)+sizeof(nomFichier)+1)); 
    strncpy(cmd,cat,sizeof(cat));
    /* vérification du nom de fichier en entrée (est-ce qu'il contient l'un de ces séparateurs ?) */
    if ( (strstr(nomFichier, ";")!= NULL)  ||
         (strstr(nomFichier, "&")!= NULL)  ||
         (strstr(nomFichier, "&&")!= NULL) ||
         (strstr(nomFichier, "|")!= NULL)  ||
         (strstr(nomFichier, "||")!= NULL) ||
         (strstr(nomFichier, "$")!= NULL)) {
        printf("Nom de fichier erroné \n ");
        return(0);
    }
    strncat(cmd, nomFichier,sizeof(nomFichier));   
    system(cmd); 
    free(cmd);
    return 0;                                                             
}

après l’exécution on obtiendra le résultat suivant :

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.