sistema para invitado imagenes imagen cargar vmware virtualbox virtual-pc xen

vmware - para - ¿Detecta el sistema operativo virtualizado desde una aplicación?



sistema invitado (14)

Necesito detectar si mi aplicación se está ejecutando dentro de una instancia de OS virtualizado o no.

Encontré un artículo con información útil sobre el tema. El mismo artículo aparece en varios lugares, no estoy seguro de la fuente original. VMware implementa una instrucción x86 no válida para devolver información sobre sí mismo, mientras que VirtualPC usa un número mágico y un puerto de E / S con una instrucción IN.

Esto es factible, pero parece ser un comportamiento no documentado en ambos casos. Supongo que una versión futura de VMWare o VirtualPC podría cambiar el mecanismo. ¿Hay una mejor manera? ¿Hay algún mecanismo compatible para cualquiera de los productos?

Del mismo modo, ¿hay alguna manera de detectar Xen o VirtualBox ?

No me preocupan los casos en los que la plataforma intenta esconderse deliberadamente. Por ejemplo, los honeypots usan la virtualización pero a veces oscurecen los mecanismos que usaría el malware para detectarlo. No me importa que mi aplicación piense que no está virtualizada en estos honeypots, solo estoy buscando una solución de "mejor esfuerzo".

La aplicación es principalmente Java, aunque espero usar código nativo más JNI para esta función en particular. El soporte para Windows XP / Vista es lo más importante, aunque los mecanismos descritos en el artículo al que se hace referencia son características genéricas de x86 y no dependen de ninguna instalación de sistema operativo en particular.


¿Has oído hablar de la píldora azul, la píldora roja? . Es una técnica utilizada para ver si se está ejecutando dentro de una máquina virtual o no. El origen del término proviene de la película matriz donde a Neo se le ofrece una píldora azul o roja (para permanecer dentro de la matriz = azul, o para ingresar al mundo ''real'' = rojo).

El siguiente es un código que detectará si está ejecutando dentro de ''la matriz'' o no:
(código tomado de este sitio que también contiene información interesante sobre el tema en cuestión):

int swallow_redpill () { unsigned char m[2+4], rpill[] = "/x0f/x01/x0d/x00/x00/x00/x00/xc3"; *((unsigned*)&rpill[3]) = (unsigned)m; ((void(*)())&rpill)(); return (m[5]>0xd0) ? 1 : 0; }

La función devolverá 1 cuando se está ejecutando dentro de una máquina virutal, y 0 de lo contrario.



Bajo Linux utilicé el comando: dmidecode (lo tengo tanto en CentOS como en Ubuntu)

del hombre:

dmidecode es una herramienta para descargar los contenidos de la tabla DMI (algunos dicen SMBIOS) de una computadora en un formato legible por humanos.

Así que busqué en la salida y descubrí que es probablemente Microsoft Hyper-V

Handle 0x0001, DMI type 1, 25 bytes System Information Manufacturer: Microsoft Corporation Product Name: Virtual Machine Version: 5.0 Serial Number: some-strings UUID: some-strings Wake-up Type: Power Switch Handle 0x0002, DMI type 2, 8 bytes Base Board Information Manufacturer: Microsoft Corporation Product Name: Virtual Machine Version: 5.0 Serial Number: some-strings

Otra forma es buscar con qué fabricante está relacionada la dirección MAC de eth0: http://www.coffer.com/mac_find/

Si devuelve Microsoft, vmware y etc., entonces probablemente sea un servidor virtual.


Compruebe la herramienta virt-what . Utiliza el código dmidecode previamente mencionado para determinar si se encuentra en un host virtualizado y el tipo.


Creo que seguir adelante, confiar en trucos como la virtualización SIDT rota no ayudará realmente, ya que el hardware tapona todos los agujeros que la extraña y desordenada arquitectura x86 ha dejado. Lo mejor sería presionar a los proveedores de VM para que indiquen de manera estándar que usted está en una VM, al menos para el caso en que el usuario lo haya permitido explícitamente. Pero si asumimos que estamos permitiendo explícitamente que se detecte la máquina virtual, también podemos colocar marcadores visibles allí, ¿no? Sugeriría simplemente actualizar el disco en sus máquinas virtuales con un archivo que le indique que está en una máquina virtual, un pequeño archivo de texto en la raíz del sistema de archivos, por ejemplo. O inspeccione el MAC de ETH0 y configúrelo para una cadena conocida.


En Linux, puede informar sobre / proc / cpuinfo. Si está en VMware, por lo general surge de manera diferente que si está en metal desnudo, pero no siempre. Virtuozzo muestra una transferencia al hardware subyacente.


En virtualbox, suponiendo que tiene control sobre el invitado VM y tiene dmidecode, puede usar este comando:

dmidecode -s bios-version

y regresará

VirtualBox


Esta función C detectará VM Guest OS:

(Probado en Windows, compilado con Visual Studio)

#include <intrin.h> bool isGuestOSVM() { unsigned int cpuInfo[4]; __cpuid((int*)cpuInfo,1); return ((cpuInfo[2] >> 31) & 1) == 1; }


Intenté un enfoque diferente sugerido por mi amigo. Las máquinas virtuales que se ejecutan en VMWARE no tienen la propiedad CPU TEMPERATURE. es decir, no muestran la temperatura de la CPU. Estoy usando la aplicación del termómetro de la CPU para verificar la temperatura de la CPU.

(Windows ejecutándose en VMWARE)

(Windows se ejecuta en una CPU real)

Así que codigo un programa pequeño C para detectar la temperatura del sensor

#include "stdafx.h" #define _WIN32_DCOM #include <iostream> using namespace std; #include <comdef.h> #include <Wbemidl.h> #pragma comment(lib, "wbemuuid.lib") int main(int argc, char **argv) { HRESULT hres; // Step 1: -------------------------------------------------- // Initialize COM. ------------------------------------------ hres = CoInitializeEx(0, COINIT_MULTITHREADED); if (FAILED(hres)) { cout << "Failed to initialize COM library. Error code = 0x" << hex << hres << endl; return 1; // Program has failed. } // Step 2: -------------------------------------------------- // Set general COM security levels -------------------------- hres = CoInitializeSecurity( NULL, -1, // COM authentication NULL, // Authentication services NULL, // Reserved RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation NULL, // Authentication info EOAC_NONE, // Additional capabilities NULL // Reserved ); if (FAILED(hres)) { cout << "Failed to initialize security. Error code = 0x" << hex << hres << endl; CoUninitialize(); return 1; // Program has failed. } // Step 3: --------------------------------------------------- // Obtain the initial locator to WMI ------------------------- IWbemLocator *pLoc = NULL; hres = CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *)&pLoc); if (FAILED(hres)) { cout << "Failed to create IWbemLocator object." << " Err code = 0x" << hex << hres << endl; CoUninitialize(); return 1; // Program has failed. } // Step 4: ----------------------------------------------------- // Connect to WMI through the IWbemLocator::ConnectServer method IWbemServices *pSvc = NULL; // Connect to the root/cimv2 namespace with // the current user and obtain pointer pSvc // to make IWbemServices calls. hres = pLoc->ConnectServer( _bstr_t(L"ROOT//CIMV2"), // Object path of WMI namespace NULL, // User name. NULL = current user NULL, // User password. NULL = current 0, // Locale. NULL indicates current NULL, // Security flags. 0, // Authority (for example, Kerberos) 0, // Context object &pSvc // pointer to IWbemServices proxy ); if (FAILED(hres)) { cout << "Could not connect. Error code = 0x" << hex << hres << endl; pLoc->Release(); CoUninitialize(); return 1; // Program has failed. } cout << "Connected to ROOT//CIMV2 WMI namespace" << endl; // Step 5: -------------------------------------------------- // Set security levels on the proxy ------------------------- hres = CoSetProxyBlanket( pSvc, // Indicates the proxy to set RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx NULL, // Server principal name RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx NULL, // client identity EOAC_NONE // proxy capabilities ); if (FAILED(hres)) { cout << "Could not set proxy blanket. Error code = 0x" << hex << hres << endl; pSvc->Release(); pLoc->Release(); CoUninitialize(); return 1; // Program has failed. } // Step 6: -------------------------------------------------- // Use the IWbemServices pointer to make requests of WMI ---- // For example, get the name of the operating system IEnumWbemClassObject* pEnumerator = NULL; hres = pSvc->ExecQuery( bstr_t("WQL"), bstr_t(L"SELECT * FROM Win32_TemperatureProbe"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator); if (FAILED(hres)) { cout << "Query for operating system name failed." << " Error code = 0x" << hex << hres << endl; pSvc->Release(); pLoc->Release(); CoUninitialize(); return 1; // Program has failed. } // Step 7: ------------------------------------------------- // Get the data from the query in step 6 ------------------- IWbemClassObject *pclsObj = NULL; ULONG uReturn = 0; while (pEnumerator) { HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); if (0 == uReturn) { break; } VARIANT vtProp; // Get the value of the Name property hr = pclsObj->Get(L"SystemName", 0, &vtProp, 0, 0); wcout << " OS Name : " << vtProp.bstrVal << endl; VariantClear(&vtProp); VARIANT vtProp1; VariantInit(&vtProp1); pclsObj->Get(L"Caption", 0, &vtProp1, 0, 0); wcout << "Caption: " << vtProp1.bstrVal << endl; VariantClear(&vtProp1); pclsObj->Release(); } // Cleanup // ======== pSvc->Release(); pLoc->Release(); pEnumerator->Release(); CoUninitialize(); return 0; // Program successfully completed. }

Salida en una máquina Vmware

Salida en una CPU real


Intente leyendo las estructuras de SMBIOS , especialmente las estructuras con la información de BIOS .

En Linux puede usar la utilidad dmidecode para explorar la información.


Me gustaría recomendar un artículo publicado en Usenix HotOS ''07, Comptibility is Not Transparency: VMM Detection Myths and Realities , que concluye varias técnicas para saber si la aplicación se está ejecutando en un entorno virtualizado.

Por ejemplo, use la instrucción sidt como lo hace redpill (pero esta instrucción también puede hacerse transparente mediante la traducción dinámica), o compare el tiempo de ejecución de cpuid con otras instrucciones no virtualizadas.


No. Esto es imposible de detectar con total precisión. Algunos sistemas de virtualización, como QEMU , emulan una máquina completa hasta los registros de hardware. Pasemos esto: ¿qué es lo que estás tratando de hacer? Quizás podamos ayudar con eso.


Utilizo esta clase C# para detectar si el sistema operativo invitado se ejecuta dentro de un entorno virtual ( solo Windows ):

sysInfo.cs

using System; using System.Management; using System.Text.RegularExpressions; namespace ConsoleApplication1 { public class sysInfo { public static Boolean isVM() { bool foundMatch = false; ManagementObjectSearcher search1 = new ManagementObjectSearcher("select * from Win32_BIOS"); var enu = search1.Get().GetEnumerator(); if (!enu.MoveNext()) throw new Exception("Unexpected WMI query failure"); string biosVersion = enu.Current["version"].ToString(); string biosSerialNumber = enu.Current["SerialNumber"].ToString(); try { foundMatch = Regex.IsMatch(biosVersion + " " + biosSerialNumber, "VMware|VIRTUAL|A M I|Xen", RegexOptions.IgnoreCase); } catch (ArgumentException ex) { // Syntax error in the regular expression } ManagementObjectSearcher search2 = new ManagementObjectSearcher("select * from Win32_ComputerSystem"); var enu2 = search2.Get().GetEnumerator(); if (!enu2.MoveNext()) throw new Exception("Unexpected WMI query failure"); string manufacturer = enu2.Current["manufacturer"].ToString(); string model = enu2.Current["model"].ToString(); try { foundMatch = Regex.IsMatch(manufacturer + " " + model, "Microsoft|VMWare|Virtual", RegexOptions.IgnoreCase); } catch (ArgumentException ex) { // Syntax error in the regular expression } return foundMatch; } } }

Uso:

if (sysInfo.isVM()) { Console.WriteLine("VM FOUND"); }


VMware tiene un Mecanismo para determinar si el software se está ejecutando en una máquina virtual de VMware Artículo de la base de conocimiento que tiene algún código fuente.

Microsoft también tiene una página sobre "Determinar si el hipervisor está instalado" . MS detalla este requisito de un hipervisor en la sección de prueba de IsVM "de su documento " Prueba de validación de virtualización de servidor "

Los documentos de VMware y MS mencionan el uso de la instrucción CPUID para verificar el bit de hipervisor presente (bit 31 del registro ECX)

El rastreador de errores RHEL tiene uno para "debe establecer el bit ISVM (ECX: 31) para la hoja CPUID 0x00000001" para configurar el bit 31 del registro ECX bajo el kernel Xen.

Entonces, sin entrar en los detalles del proveedor, parece que podría usar la verificación del CPUID para saber si se está ejecutando virtualmente o no.