Domanda

Esiste un modo per identificare, dall'interno di una VM, che il tuo codice è in esecuzione all'interno di una VM?

Immagino che ci siano modi più o meno semplici per identificare specifici sistemi VM, soprattutto se sulla VM sono installate le estensioni del provider (come per VirtualBox o VMWare).Ma esiste un modo generale per identificare che non stai utilizzando direttamente la CPU?

È stato utile?

Soluzione

Gran parte della ricerca in materia è dedicata al rilevamento dei cosiddetti attacchi "pillola blu", ovvero un hypervisor dannoso che tenta attivamente di eludere il rilevamento.

Il classico trucco per rilevare una VM è popolare ITLB, eseguire un'istruzione that dovere essere virtualizzato (che necessariamente cancella tale stato del processore quando dà il controllo all'hypervisor), quindi esegui altro codice per rilevare se ITLB è ancora popolato.Si trova il primo documento su di esso Qui, e una spiegazione piuttosto colorita da a blog del ricercatore e alternativo Collegamento di Wayback Machine all'articolo del blog (immagini interrotte).

La conclusione delle discussioni su questo argomento è che esiste sempre un modo per rilevare un hypervisor dannoso ed è molto più semplice rilevarne uno che non sta tentando di nascondersi.

Altri suggerimenti

Red Hat dispone di un programma che rileva con quale (se presente) prodotto di virtualizzazione viene eseguito: virt-what.

Utilizzare uno strumento gestito da terze parti è una strategia migliore a lungo termine rispetto al tentativo di implementare la propria logica di rilevamento:più occhi (test rispetto a più prodotti di virtualizzazione), ecc.

Un approccio più empirico consiste nel verificare la presenza di driver di dispositivo VM noti.È possibile scrivere query WMI per individuare, ad esempio, l'adattatore video VMware, l'unità disco, l'adattatore di rete, ecc.Sarebbe adatto se sapessi che devi preoccuparti solo dei tipi di host VM conosciuti nel tuo ambiente.Ecco un esempio di come farlo in Perl, che potrebbe essere portato nella lingua di tua scelta.

Dipende da cosa cerchi:

  • Se la VM non ti si nasconde di proposito, puoi usare qualche hook conosciuto.Come cercare i driver VmWare o la presenza di determinate stringhe in memoria o altri segni rivelatori.

  • Se la VM vuole davvero che tu faccia cose speciali per lei, avrà qualche ovvio aggancio in atto, come la modifica dell'ID del processore o l'aggiunta di alcuni registri speciali a cui puoi accedere per rilevarlo.Oppure è un dispositivo speciale in una posizione nota nella memoria (presumendo che tu possa ottenere un accesso diretto allo spazio di memoria fisica del tuo mondo).Tieni presente che i design delle macchine moderne come IBM Power6 e Sun UltraSparc T1/T2 sono progettati per eseguire SEMPRE un hypervisor e mai direttamente su hardware grezzo.L'interfaccia con l'"hardware" utilizzata da un sistema operativo è in realtà l'interfaccia di un livello software hypervisor, senza alcun modo per aggirarla.In questo caso, il rilevamento è banale poiché è un "sì" costante.Questa è la probabile direzione futura per tutti i sistemi informatici che possono permettersi spese generali, guarda il supporto in progetti recenti come il chip Freescale QorIQ P4080, ad esempio (www.freescale.com/qoriq).

  • Se la VM sta intenzionalmente cercando di nascondersi e tu stai inseguendo la sua presenza, è un gioco del gatto con il topo in cui il disturbo temporale e il diverso profilo prestazionale di una VM quasi sempre la tradiranno.Ovviamente, questo dipende da come viene implementata la VM e da quanto supporto hardware è presente nell'architettura (penso che un mainframe zSeries sia molto più bravo a nascondere la presenza di una VM o di uno stack di VM sotto il tuo particolare sistema operativo rispetto a un normale x86 macchina è, ad esempio).Vedere http://jakob.engbloms.se/archives/97 per qualche discussione su questo argomento.È possibile provare a nascondersi come VM, ma è molto probabile che il rilevamento vinca sempre se ci si impegna abbastanza.

Una volta mi sono imbattuto in uno snippet di codice assembly che ti diceva se eri in una VM.... Ho cercato su Google ma non sono riuscito a trovare l'articolo originale.

Ho trovato questo però: Rileva se il tuo programma è in esecuzione all'interno di una macchina virtuale.

Spero che sia d'aiuto.

Nella maggior parte dei casi, non dovresti provarci.Non dovrebbe interessarti se qualcuno sta eseguendo il tuo codice in una VM, tranne in alcuni casi specifici.

Se necessario, in Linux il modo più comune è guardare /sys/devices/virtual/dmi/id/product_name, che elencherà il nome del laptop/scheda madre sulla maggior parte dei sistemi reali e dell'hypervisor sulla maggior parte dei sistemi virtuali. dmidecode | grep Product è un altro metodo comune, ma penso che richieda l'accesso root.

Ecco un (java+finestre) soluzione per identificare se la macchina sottostante è fisica o virtuale.

Esempi di macchine virtuali:

Produttore

  • Xen
  • Microsoft Corporation
  • innotek GmbH
  • cappello rosso
  • VMware, Inc.

Modello

  • HVM domU
  • Macchina virtuale
  • VirtualBox
  • KVM
  • Piattaforma virtuale 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());
    }
    }
    

Puoi utilizzare l'output per decidere se si tratta di una VM o di una macchina fisica:

Output della macchina fisica:

Seriale del BIOS:2HC3J12
Modello dell'hardware:Inspiron 7570
Produttore dell'hardware:Dell Inc.

Output della macchina virtuale:

Seriale del BIOS:0
Modello dell'hardware:Innotec GmbH
Produttore dell'hardware:Scatola virtuale

Un buon esempio è che apparentemente si esegue una query WMI per il produttore della scheda madre e se restituisce "Microsoft" ci si trova in una VM.Pensavo che questo fosse solo per VMWare.Probabilmente esistono diversi modi per determinarlo per ciascun software host di VM.

Questo articolo qui http://blogs.technet.com/jhoward/archive/2005/07/26/407958.aspx ha alcuni buoni suggerimenti e collegamenti a un paio di modi per rilevare se ti trovi in ​​una VM (almeno VMWare e VirtualPC).

Potresti essere in grado di identificare se ti trovi in ​​una macchina virtuale guardando l'indirizzo MAC della tua connessione di rete.Xen, ad esempio, consiglia in genere di utilizzare un intervallo specifico di indirizzi 00:16:3e:xx:xx:xx.

Ciò non è garantito poiché spetta all'amministratore del sistema specificare quale indirizzo MAC desidera.

Nei sistemi Linux, puoi provare a cercare file comuni su /proc.

Ad esempio, l'esistente di /proc/vz/ dirti è un OpenVZ.

Ecco una guida completa per rilevare l'ambiente della VM sotto Linux senza dover "bere pillole" :)

TrapKIT fornisce ScoopyNG, uno strumento per l'identificazione di VMware - tenta di aggirare le tecniche di evasione, ma non prende necessariamente di mira software di virtualizzazione diversi da VMware.Sono disponibili sia i sorgenti che i file binari.

Se la VM svolge bene il lavoro, dovrebbe essere invisibile al client che viene virtualizzata.Tuttavia si possono cercare altri indizi.

Immagino che la ricerca di driver noti o software specifici per l'ambiente VM sarebbe il miglior modo possibile.

Ad esempio, su un client VMWare che esegue Windows, vmxnet.sys sarebbe il driver di rete, visualizzato come adattatore AMD PCNet con accelerazione VMware.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top