ScoopyNG
Jump to navigation
Jump to search
Description
ScoopyNG is a Proof of Concept (PoC) to detect whether it is run inside VMware. According to the author, it is "able to detect VMware even if "anti-detection-mechanisms" are deployed."
Following tests are performed:
Test | Description |
---|---|
Test #1 | sidt instruction |
Test #2 | sldt (Red Pill and No Pill) instructions |
Test #3 | sgdt intruction |
Test #4 | str intruction |
Test #5 | Use the backdoor I/O port 0x0a option |
Test #6 | Use the backdoor I/O port 0x14 options, |
Test #7 | This check relies on a bug in older VMware versions running in emulation mode. |
Installation
Download link: http://www.trapkit.de/research/vmm/scoopyng/ScoopyNG.zip
Example
Below is the output of ScoopyNG run inside 2 different configurations:
Native OS (Windows 8.1 update 1 64 bit) | VMware (Windows 7 SP1 64 bit) |
---|---|
C:\>ScoopyNG.exe #################################################### :: ScoopyNG - The VMware Detection Tool :: :: Windows version v1.0 :: [+] Test 1: IDT IDT base: 0xf55bc0c0 Result : Native OS [+] Test 2: LDT LDT base: 0xdead0000 Result : Native OS [+] Test 3: GDT GDT base: 0xf55bc040 Result : Native OS [+] Test 4: STR STR base: 0x40000000 Result : Native OS [+] Test 5: VMware "get version" command Result : Native OS [+] Test 6: VMware "get memory size" command Result : Native OS [+] Test 7: VMware emulation mode Result : Native OS or VMware without emulation mode (enabled acceleration) :: tk, 2008 :: :: [ www.trapkit.de ] :: ################################################### |
C:\>ScoopyNG.exe #################################################### :: ScoopyNG - The VMware Detection Tool :: :: Windows version v1.0 :: [+] Test 1: IDT IDT base: 0x40d0080 Result : Native OS [+] Test 2: LDT LDT base: 0xdead0000 Result : Native OS [+] Test 3: GDT GDT base: 0x40d0000 Result : Native OS [+] Test 4: STR STR base: 0x40000000 Result : Native OS [+] Test 5: VMware "get version" command Result : VMware detected Version : Workstation [+] Test 6: VMware "get memory size" command Result : VMware detected [+] Test 7: VMware emulation mode Result : Native OS or VMware without emulation mode (enabled acceleration) :: tk, 2008 :: :: [ www.trapkit.de ] :: #################################################### |
Source code
/* 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 ("[+] Test 1: IDT\n");
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)
printf ("Express\n\n");
else if (b == 2)
printf ("ESX\n\n");
else if (b == 3)
printf ("GSX\n\n");
else if (b == 4)
printf ("Workstation\n\n");
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 (":: tk, 2008 ::\n");
printf (":: [ www.trapkit.de ] ::\n");
printf ("####################################################\n\n");
return 0;
}