Indagando por el recóndito Internet encontré una herramienta muy interesante llamada:
ScoopyNG lo que hace esta herramienta es realizar una serie de pruebas (test) para verificar si se está ejecutando una máquina virtual VMware, la página del proyecto:
http://www.trapkit.de/research/vmm/scoopyng/index.html
Viene compilado en .exe pero lo mejor de todo es que viene incluido el source code (lo que me motivó a hacer este pequeño post) Esto es de gran utilidad ya que puede ser agregado en sus aplicaciones (no necesariamente todos los test y no necesariamente debe ser un programa en C, lo pueden portar):
Source Code
ScoopyNG.c :
/* ScoopyNG - The VMware detection tool
* Version v1.0
*
* Tobias Klein, 2008
* www.trapkit.de
*/
#include <windows.h>
#include <excpt.h>
#include <stdio.h>
#define DEBUG 0
#define EndUserModeAddress (*(UINT_PTR*)0x7FFE02B4)
typedef LONG (NTAPI *NTSETLDTENTRIES)(DWORD, DWORD, DWORD, DWORD, DWORD, DWORD);
unsigned long
get_idt_base (void)
{
unsigned char idtr[6];
unsigned long idt = 0;
_asm sidt idtr
idt = *((unsigned long *)&idtr[2]);
return (idt);
}
unsigned long
get_ldtr_base (void)
{
unsigned char ldtr[5] = "\xef\xbe\xad\xde";
unsigned long ldt = 0;
_asm sldt ldtr
ldt = *((unsigned long *)&ldtr[0]);
return (ldt);
}
unsigned long
get_gdt_base (void)
{
unsigned char gdtr[6];
unsigned long gdt = 0;
_asm sgdt gdtr
gdt = *((unsigned long *)&gdtr[2]);
return (gdt);
}
void
test1 (void)
{
unsigned int idt_base = 0;
idt_base = get_idt_base ();
printf ("IDT base: 0x%x\n", idt_base
);
if ((idt_base >> 24) == 0xff) {
printf ("Result : VMware detected\n\n"); return;
}
else {
printf ("Result : Native OS\n\n"); return;
}
}
void
test2 (void)
{
unsigned int ldt_base = 0;
ldt_base = get_ldtr_base ();
printf ("\n[+] Test 2: LDT\n"); printf ("LDT base: 0x%x\n", ldt_base
);
if (ldt_base == 0xdead0000) {
printf ("Result : Native OS\n\n"); return;
}
else {
printf ("Result : VMware detected\n\n"); return;
}
}
void
test3 (void)
{
unsigned int gdt_base = 0;
gdt_base = get_gdt_base ();
printf ("\n[+] Test 3: GDT\n"); printf ("GDT base: 0x%x\n", gdt_base
);
if ((gdt_base >> 24) == 0xff) {
printf ("Result : VMware detected\n\n"); return;
}
else {
printf ("Result : Native OS\n\n"); return;
}
}
// Alfredo Andrés Omella's (S21sec) STR technique
void
test4 (void)
{
unsigned char mem[4] = {0, 0, 0, 0};
__asm str mem;
printf ("\n[+] Test 4: STR\n"); printf ("STR base: 0x%02x%02x%02x%02x\n", mem
[0], mem
[1], mem
[2], mem
[3]);
if ((mem[0] == 0x00) && (mem[1] == 0x40))
printf ("Result : VMware detected\n\n"); else
printf ("Result : Native OS\n\n"); }
void
test5 (void)
{
unsigned int a, b;
__try {
__asm {
// save register values on the stack
push eax
push ebx
push ecx
push edx
// perform fingerprint
mov eax, 'VMXh' // VMware magic value (0x564D5868)
mov ecx, 0Ah // special version cmd (0x0a)
mov dx, 'VX' // special VMware I/O port (0x5658)
in eax, dx // special I/O cmd
mov a, ebx // data
mov b, ecx // data (eax gets also modified but will not be evaluated)
// restore register values from the stack
pop edx
pop ecx
pop ebx
pop eax
}
} __except (EXCEPTION_EXECUTE_HANDLER) {}
#if DEBUG == 1
printf ("\n [ a=%x ; b=%d ]\n\n", a
, b
); #endif
printf ("\n[+] Test 5: VMware \"get version\" command\n");
if (a == 'VMXh') { // is the value equal to the VMware magic value?
printf ("Result : VMware detected\nVersion : "); if (b == 1)
else if (b == 2)
else if (b == 3)
else if (b == 4)
else
printf ("unknown version\n\n"); }
else
printf ("Result : Native OS\n\n"); }
void
test6 (void)
{
unsigned int a = 0;
__try {
__asm {
// save register values on the stack
push eax
push ebx
push ecx
push edx
// perform fingerprint
mov eax, 'VMXh' // VMware magic value (0x564D5868)
mov ecx, 14h // get memory size command (0x14)
mov dx, 'VX' // special VMware I/O port (0x5658)
in eax, dx // special I/O cmd
mov a, eax // data
// restore register values from the stack
pop edx
pop ecx
pop ebx
pop eax
}
} __except (EXCEPTION_EXECUTE_HANDLER) {}
printf ("\n[+] Test 6: VMware \"get memory size\" command\n");
if (a > 0)
printf ("Result : VMware detected\n\n"); else
printf ("Result : Native OS\n\n"); }
int
test7_detect (LPEXCEPTION_POINTERS lpep)
{
printf ("\n[+] Test 7: VMware emulation mode\n");
if ((UINT_PTR)(lpep->ExceptionRecord->ExceptionAddress) > EndUserModeAddress)
printf ("Result : VMware detected (emulation mode detected)\n\n"); else
printf ("Result : Native OS or VMware without emulation mode\n" " (enabled acceleration)\n\n");
return (EXCEPTION_EXECUTE_HANDLER);
}
void __declspec(naked)
test7_switchcs ()
{
__asm {
pop eax
push 0x000F
push eax
retf
}
}
// Derek Soeder's (eEye Digital Security) VMware emulation test
void
test7 (void)
{
NTSETLDTENTRIES ZwSetLdtEntries;
LDT_ENTRY csdesc;
ZwSetLdtEntries = (NTSETLDTENTRIES)GetProcAddress (GetModuleHandle ("ntdll.dll"), "ZwSetLdtEntries");
memset (&csdesc
, 0, sizeof (csdesc
));
csdesc.LimitLow = (WORD)(EndUserModeAddress >> 12);
csdesc.HighWord.Bytes.Flags1 = 0xFA;
csdesc.HighWord.Bytes.Flags2 = 0xC0 | ((EndUserModeAddress >> 28) & 0x0F);
ZwSetLdtEntries (0x000F, ((DWORD*)&csdesc)[0], ((DWORD*)&csdesc)[1], 0, 0, 0);
__try {
test7_switchcs();
__asm {
or eax, -1
jmp eax
}
}
__except (test7_detect (GetExceptionInformation())) { }
}
int
main (void)
{
printf ("\n\n####################################################\n"); printf (":: ScoopyNG - The VMware Detection Tool ::\n"); printf (":: Windows version v1.0 ::\n\n");
test1 ();
test2 ();
test3 ();
test4 ();
test5 ();
test6 ();
test7 ();
printf (":: [ www.trapkit.de ] ::\n"); printf ("####################################################\n\n");
return 0;
}
Créditos: www.trapkit.de
Excelente .:UND3R:.
Voy a hacer unas pruebas para ver como mitigar las detecciones. :P
Saludos!
Excelente .:UND3R:.
Voy a hacer unas pruebas para ver como mitigar las detecciones. :P
Saludos!
Yo lo encontré hermoso, por cierto sería ideal poder implementar una especie de parche que evitara toda las detecciones anteriormente mencionadas pero la verdad dudo mucho que yo pudiera hacerlo (muy avanzado).