Pregunta

¿Existe alguna manera de identificar, desde una VM, que su código se ejecuta dentro de una VM?

Supongo que hay formas más o menos sencillas de identificar sistemas VM específicos, especialmente si la VM tiene instaladas las extensiones del proveedor (como VirtualBox o VMWare).Pero, ¿existe una forma general de identificar que no está ejecutando directamente en la CPU?

¿Fue útil?

Solución

Gran parte de la investigación al respecto se dedica a detectar los llamados ataques de "píldora azul", es decir, un hipervisor malicioso que intenta activamente evadir la detección.

El truco clásico para detectar una VM es llenar el ITLB, ejecutar una instrucción que debe ser virtualizado (lo que necesariamente borra dicho estado del procesador cuando le da el control al hipervisor), luego ejecute más código para detectar si el ITLB todavía está lleno.El primer documento se encuentra aquí, y una explicación bastante colorida de un blog del investigador y alternativa Enlace de Wayback Machine al artículo del blog (imágenes rotas).

La conclusión de las discusiones sobre esto es que siempre hay una manera de detectar un hipervisor malicioso, y es mucho más sencillo detectar uno que no intenta ocultarse.

Otros consejos

Red Hat tiene un programa que detecta en qué producto de virtualización (si corresponde) se está ejecutando: virt-what.

Usar una herramienta mantenida por terceros como esta es una mejor estrategia a largo plazo que intentar implementar su propia lógica de detección:más ojos (pruebas contra más productos de virtualización), etc.

Un enfoque más empírico es buscar controladores de dispositivos VM conocidos.Podría escribir consultas WMI para localizar, por ejemplo, el adaptador de pantalla de VMware, la unidad de disco, el adaptador de red, etc.Esto sería adecuado si supiera que sólo tiene que preocuparse por los tipos de host de VM conocidos en su entorno.Aquí está un ejemplo de hacer esto en Perl, que podría trasladarse al idioma de su elección.

Depende de lo que busques:

  • Si la máquina virtual no se esconde de usted a propósito, puede utilizar algún gancho conocido.Como buscar controladores de VmWare o la presencia de ciertas cadenas en la memoria u otros signos reveladores.

  • Si la VM realmente quiere que usted haga cosas especiales por ella, tendrá algún gancho obvio, como modificar la ID del procesador o agregar algunos registros especiales a los que pueda acceder para detectarla.O es un dispositivo especial en una ubicación conocida en la memoria (suponiendo que pueda obtener acceso sin formato al espacio de memoria física de su mundo).Tenga en cuenta que los diseños de máquinas modernas como IBM Power6 y Sun UltraSparc T1/T2 están diseñados para ejecutar SIEMPRE un hipervisor y nunca directamente en hardware sin formato.La interfaz con el "hardware" que utiliza un sistema operativo es, de hecho, la interfaz de una capa de software de hipervisor, sin forma de evitarla.En este caso la detección es trivial ya que se trata de un "sí" constante.Esta es la probable dirección futura para todos los sistemas informáticos que puedan afrontar los gastos generales; mire el soporte en diseños recientes como el chip Freescale QorIQ P4080, por ejemplo (www.freescale.com/qoriq).

  • Si la máquina virtual intenta ocultarse intencionalmente y usted persigue su presencia, es un juego del gato y el ratón en el que la alteración del tiempo y el diferente perfil de rendimiento de una máquina virtual casi siempre lo delatarán.Obviamente, esto depende de cómo se implemente la VM y de cuánto soporte de hardware exista en la arquitectura (creo que un mainframe zSeries es mucho mejor para ocultar la presencia de una VM o una pila de VM en su sistema operativo particular que un x86 normal). máquina es, por ejemplo).Ver http://jakob.engbloms.se/archives/97 para alguna discusión sobre este tema.Es posible intentar ocultarse como una máquina virtual, pero es muy probable que la detección siempre gane si se intenta lo suficiente.

Una vez me encontré con un fragmento de código ensamblador que te decía si estabas en una máquina virtual... Busqué en Google pero no pude encontrar el artículo original.

Aunque encontré esto: Detecta si tu programa se está ejecutando dentro de una Máquina Virtual.

Espero eso ayude.

En la mayoría de los casos, no deberías intentarlo.No debería importarle si alguien está ejecutando su código en una máquina virtual, excepto en algunos casos específicos.

Si es necesario, en Linux la forma más común es mirar /sys/devices/virtual/dmi/id/product_name, que mostrará el nombre de la computadora portátil/placa base en la mayoría de los sistemas reales y el hipervisor en la mayoría de los sistemas virtuales. dmidecode | grep Product Es otro método común, pero creo que requiere acceso de root.

Aquí hay un (java + ventanas) solución para identificar si la máquina subyacente es física o virtual.

Ejemplos de máquinas virtuales:

Fabricante

  • xén
  • Corporación Microsoft
  • innotek GmbH
  • sombrero rojo
  • VMware, Inc.

Modelo

  • HVM domU
  • Máquina virtual
  • VirtualBox
  • KVM
  • Plataforma virtual 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());
    }
    }
    

Puede utilizar el resultado para decidir si se trata de una máquina virtual o una máquina física:

Salida de la máquina física:

Serie del BIOS:2HC3J12
Modelo de hardware:Inspiron 7570
Fabricante de hardware:Dell Inc.

Salida de la máquina virtual:

Serie del BIOS:0
Modelo de hardware:Innotec GmBH
Fabricante de hardware:Caja virtual

Un buen ejemplo es que aparentemente se realiza una consulta WMI para el fabricante de la placa base y, si devuelve "Microsoft", estás en una máquina virtual.Creo que esto es sólo para VMWare.Es probable que existan diferentes formas de saberlo para cada software de host de VM.

Este artículo aquí http://blogs.technet.com/jhoward/archive/2005/07/26/407958.aspx tiene algunas buenas sugerencias y enlaces a un par de formas de detectar si está en una VM (VMWare y VirtualPC al menos).

Es posible que puedas identificar si estás en una máquina virtual mirando la dirección MAC de tu conexión de red.Xen, por ejemplo, normalmente recomienda utilizar un rango específico de direcciones 00:16:3e:xx:xx:xx.

Esto no está garantizado ya que depende del administrador del sistema especificar qué dirección MAC prefiere.

En sistemas Linux, puede intentar buscar archivos comunes en /proc.

Por ejemplo, la existencia de /proc/vz/ le dice que es un OpenVZ.

Aquí hay una guía completa para detectar el entorno de VM bajo Linux sin tener que "tomar pastillas" :)

TrapKIT proporciona ScoopyNG, una herramienta para la identificación de VMware -- intenta solucionar las técnicas de evasión, pero no necesariamente apunta a ningún software de virtualización que no sea VMware.Tanto el código fuente como los binarios están disponibles.

Si la VM hace bien el trabajo, debería ser invisible para el cliente que está siendo virtualizada.Sin embargo, se pueden buscar otras pistas.

Me imagino que buscar controladores conocidos o software específico para el entorno de VM sería la mejor manera posible.

Por ejemplo, en un cliente VMWare que ejecuta Windows, vmxnet.sys sería el controlador de red, mostrado como Adaptador AMD PCNet acelerado por VMware.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top