Question

Existe-t-il un moyen d'identifier, depuis une VM, que votre code s'exécute dans une VM ?

Je suppose qu'il existe des moyens plus ou moins simples d'identifier des systèmes de VM spécifiques, surtout si les extensions du fournisseur sont installées sur la VM (comme pour VirtualBox ou VMWare).Mais existe-t-il un moyen général d'identifier que vous n'exécutez pas directement sur le processeur ?

Était-ce utile?

La solution

Une grande partie des recherches à ce sujet sont consacrées à la détection des attaques dites « pilule bleue », c'est-à-dire un hyperviseur malveillant qui tente activement d'échapper à la détection.

L'astuce classique pour détecter une VM consiste à remplir l'ITLB, à exécuter une instruction qui doit être virtualisé (ce qui efface nécessairement cet état du processeur lorsqu'il donne le contrôle à l'hyperviseur), puis exécutez un peu plus de code pour détecter si l'ITLB est toujours rempli.Le premier article à ce sujet se trouve ici, et une explication plutôt colorée d'un blog du chercheur et alternative Lien Wayback Machine vers l'article du blog (images cassées).

L'essentiel des discussions à ce sujet est qu'il existe toujours un moyen de détecter un hyperviseur malveillant, et qu'il est beaucoup plus simple d'en détecter un qui n'essaie pas de se cacher.

Autres conseils

Red Hat dispose d'un programme qui détecte sous quel produit de virtualisation (le cas échéant) il est exécuté : virt-what.

Utiliser un outil géré par un tiers tel que celui-ci constitue une meilleure stratégie à long terme que d'essayer de déployer votre propre logique de détection :plus d'yeux (tests avec davantage de produits de virtualisation), etc.

Une approche plus empirique consiste à rechercher les pilotes de périphériques de machine virtuelle connus.Vous pouvez écrire des requêtes WMI pour localiser, par exemple, la carte graphique VMware, le lecteur de disque, la carte réseau, etc.Cela conviendrait si vous saviez que vous n'aviez à vous soucier que des types d'hôtes de VM connus dans votre environnement.Voici un exemple de faire cela en Perl, qui pourrait être porté dans la langue de votre choix.

Cela dépend de ce que vous recherchez :

  • Si la VM ne vous cache pas volontairement, vous pouvez utiliser un hook connu.Comme la recherche de pilotes VmWare ou la présence de certaines chaînes en mémoire ou de certains autres signes révélateurs.

  • Si la VM veut vraiment que vous fassiez des choses spéciales pour elle, elle aura un crochet évident en place, comme modifier l'ID du processeur ou ajouter des registres spéciaux auxquels vous pourrez accéder pour le détecter.Ou s'il s'agit d'un périphérique spécial situé à un emplacement connu de la mémoire (en supposant que vous puissiez obtenir un accès brut à l'espace mémoire physique de votre monde).Notez que les conceptions de machines modernes comme IBM Power6 et Sun UltraSparc T1/T2 sont conçues pour TOUJOURS exécuter un hyperviseur, et jamais directement sur du matériel brut.L'interface avec le « matériel » qu'utilise un OS est en fait l'interface d'une couche logicielle hyperviseur, sans aucun moyen de la contourner.Dans ce cas, la détection est triviale puisqu’il s’agit d’un « oui » constant.C'est l'orientation future probable de tous les systèmes informatiques qui peuvent se permettre cette surcharge, regardez la prise en charge des conceptions récentes comme la puce Freescale QorIQ P4080, par exemple (www.freescale.com/qoriq).

  • Si la VM essaie intentionnellement de se cacher et que vous recherchez sa présence, il s'agit d'un jeu du chat et de la souris où la perturbation du timing et les différents profils de performances d'une VM vont presque toujours la trahir.Évidemment, cela dépend de la façon dont la VM est implémentée et du niveau de prise en charge matérielle en place dans l'architecture (je pense qu'un mainframe zSeries est bien meilleur pour cacher la présence d'une VM ou d'une pile de VM sous votre système d'exploitation particulier qu'un x86 classique. la machine est, par exemple).Voir http://jakob.engbloms.se/archives/97 pour une discussion sur ce sujet.Il est possible d’essayer de se cacher en tant que VM, mais la détection est susceptible de toujours gagner si elle fait suffisamment d’efforts.

Une fois, je suis tombé sur un extrait de code assembleur qui vous indiquait si vous étiez dans une VM... J'ai cherché sur Google mais je n'ai pas trouvé l'article original.

Par contre j'ai trouvé ça : Détectez si votre programme s'exécute dans une machine virtuelle.

J'espère que cela aide.

Dans la plupart des cas, vous ne devriez pas essayer.Vous ne devriez pas vous soucier si quelqu'un exécute votre code dans une VM, sauf dans quelques cas spécifiques.

Si vous en avez besoin, sous Linux, la méthode la plus courante consiste à consulter /sys/devices/virtual/dmi/id/product_name, qui répertoriera le nom de l'ordinateur portable/de la carte mère sur la plupart des systèmes réels et de l'hyperviseur sur la plupart des systèmes virtuels. dmidecode | grep Product est une autre méthode courante, mais je pense que cela nécessite un accès root.

Voici une (java + fenêtres) solution pour identifier si la machine sous-jacente est physique ou virtuelle.

Exemples de machines virtuelles :

Fabricant

  • Xen
  • Microsoft Corporation
  • innotek GmbH
  • chapeau rouge
  • VMware, Inc.

Modèle

  • HVM domU
  • Machine virtuelle
  • Boîte Virtuelle
  • KVM
  • Plateforme virtuelle VMware

    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.util.ArrayList;
    import java.util.List;
    
    public abstract class OSUtil {
    
    public static final List<String> readCmdOutput(String command) {
        List<String> result = new ArrayList<>();
    
        try {
            Process p=Runtime.getRuntime().exec("cmd /c " + command);
            p.waitFor();
            BufferedReader reader=new BufferedReader(
                    new InputStreamReader(p.getInputStream())
                    );
            String line;
            while((line = reader.readLine()) != null) {
                if(line != null && !line.trim().isEmpty()) {
                    result.add(line);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    
        return result;
    }
    
    public static final String readCmdOutput(String command, int lineNumber) {
        List<String> result = readCmdOutput(command);
        if(result.size() < lineNumber) {
            return null;
        }
    
        return result.get(lineNumber - 1);
    }
    
    public static final String getBiosSerial() {
        return readCmdOutput("WMIC BIOS GET SERIALNUMBER", 2);
    }
    
    public static final String getHardwareModel() {
        return readCmdOutput("WMIC COMPUTERSYSTEM GET MODEL", 2);
    }
    
    public static final String getHardwareManufacturer() {
        return readCmdOutput("WMIC COMPUTERSYSTEM GET MANUFACTURER", 2);
    }
    
    public static void main(String[] args) {
        System.out.println("BIOS Serial: " + getBiosSerial());
        System.out.println("Hardware Model: " + getHardwareModel());
        System.out.println("Hardware Manufacturer: " + getHardwareManufacturer());
    }
    }
    

Vous pouvez utiliser le résultat pour décider s'il s'agit d'une VM ou d'une machine physique :

Sortie de la machine physique :

Série du BIOS :2HC3J12
Modèle de matériel :Inspiron7570
Fabricant de matériel :Dell Inc.

Sortie de la machine virtuelle :

Série du BIOS :0
Modèle de matériel :Innotec GmbH
Fabricant de matériel :Boîte virtuelle

Un bon exemple est que vous effectuez apparemment une requête WMI pour le fabricant de la carte mère, et si elle renvoie "Microsoft", vous êtes dans une VM.Je pensais que c'était uniquement pour VMWare.Il existe probablement différentes manières de déterminer chaque logiciel hôte de VM.

Cet article ici http://blogs.technet.com/jhoward/archive/2005/07/26/407958.aspx propose de bonnes suggestions et des liens vers plusieurs façons de détecter si vous êtes dans une VM (VMWare et VirtualPC au moins).

Vous pourrez peut-être identifier si vous êtes dans une machine virtuelle en examinant l'adresse MAC de votre connexion réseau.Xen, par exemple, recommande généralement d'utiliser une plage d'adresses spécifique 00:16:3e:xx:xx:xx.

Ceci n'est pas garanti car c'est à l'administrateur du système de spécifier l'adresse MAC qu'il souhaite.

Sur les systèmes Linux, vous pouvez essayer de rechercher des fichiers courants sur /proc.

Exemple, l'existence de /proc/vz/ vous dit est un OpenVZ.

Voici un guide complet pour détecter l'environnement de la VM sous Linux sans avoir à "boire des pilules" :)

TrapKIT fournit ScoopyNG, un outil d'identification VMware -- il tente de contourner les techniques d'évasion, mais ne cible pas nécessairement un logiciel de virtualisation autre que VMware.Les sources et les binaires sont disponibles.

Si la VM fait bien le travail, le client ne devrait pas voir qu'elle est virtualisée.On peut cependant s’intéresser à d’autres indices.

J'imagine que rechercher des pilotes connus ou des logiciels spécifiques à l'environnement VM serait le meilleur moyen possible.

Par exemple, sur un client VMWare exécutant Windows, vmxnet.sys serait le pilote réseau, affiché comme Adaptateur AMD PCNet accéléré par VMware.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top