Foro de elhacker.net

Programación => Ingeniería Inversa => Mensaje iniciado por: .:UND3R:. en 23 Febrero 2015, 16:30 pm



Título: Detección de VMware - ScoopyNG
Publicado por: .:UND3R:. en 23 Febrero 2015, 16:30 pm
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 :
Código
  1. /* ScoopyNG - The VMware detection tool
  2.  * Version v1.0
  3.  *
  4.  * Tobias Klein, 2008
  5.  * www.trapkit.de
  6.  */
  7.  
  8. #include <windows.h>
  9. #include <excpt.h>
  10. #include <stdio.h>
  11.  
  12. #define DEBUG 0
  13. #define EndUserModeAddress (*(UINT_PTR*)0x7FFE02B4)
  14.  
  15. typedef LONG (NTAPI *NTSETLDTENTRIES)(DWORD, DWORD, DWORD, DWORD, DWORD, DWORD);
  16.  
  17. unsigned long
  18. get_idt_base (void)
  19. {
  20. unsigned char idtr[6];
  21. unsigned long idt = 0;
  22.  
  23. _asm sidt idtr
  24. idt = *((unsigned long *)&idtr[2]);
  25.  
  26. return (idt);
  27. }
  28.  
  29. unsigned long
  30. get_ldtr_base (void)
  31. {
  32. unsigned char   ldtr[5] = "\xef\xbe\xad\xde";
  33. unsigned long   ldt = 0;
  34.  
  35. _asm sldt ldtr
  36. ldt = *((unsigned long *)&ldtr[0]);
  37.  
  38. return (ldt);
  39. }
  40.  
  41. unsigned long
  42. get_gdt_base (void)
  43. {
  44. unsigned char   gdtr[6];
  45. unsigned long   gdt = 0;
  46.  
  47. _asm sgdt gdtr
  48. gdt = *((unsigned long *)&gdtr[2]);
  49.  
  50. return (gdt);
  51. }
  52.  
  53. void
  54. test1 (void)
  55. {
  56. unsigned int idt_base = 0;
  57.  
  58. idt_base = get_idt_base ();
  59.  
  60. printf ("[+] Test 1: IDT\n");
  61. printf ("IDT base: 0x%x\n", idt_base);
  62.  
  63. if ((idt_base >> 24) == 0xff) {
  64. printf ("Result  : VMware detected\n\n");
  65. return;
  66. }
  67.  
  68. else {
  69. printf ("Result  : Native OS\n\n");
  70. return;
  71. }
  72. }
  73.  
  74. void
  75. test2 (void)
  76. {
  77. unsigned int ldt_base = 0;
  78.  
  79. ldt_base = get_ldtr_base ();
  80.  
  81. printf ("\n[+] Test 2: LDT\n");
  82. printf ("LDT base: 0x%x\n", ldt_base);
  83.  
  84. if (ldt_base == 0xdead0000) {
  85. printf ("Result  : Native OS\n\n");
  86. return;
  87. }
  88.  
  89. else {
  90. printf ("Result  : VMware detected\n\n");
  91. return;
  92. }
  93. }
  94.  
  95. void
  96. test3 (void)
  97. {
  98. unsigned int gdt_base = 0;
  99.  
  100. gdt_base = get_gdt_base ();
  101.  
  102. printf ("\n[+] Test 3: GDT\n");
  103. printf ("GDT base: 0x%x\n", gdt_base);
  104.  
  105. if ((gdt_base >> 24) == 0xff) {
  106. printf ("Result  : VMware detected\n\n");
  107. return;
  108. }
  109.  
  110. else {
  111. printf ("Result  : Native OS\n\n");
  112. return;
  113. }
  114. }
  115.  
  116. // Alfredo Andrés Omella's (S21sec) STR technique
  117. void
  118. test4 (void)
  119. {
  120. unsigned char mem[4] = {0, 0, 0, 0};
  121.  
  122. __asm str mem;
  123.  
  124. printf ("\n[+] Test 4: STR\n");
  125. printf ("STR base: 0x%02x%02x%02x%02x\n", mem[0], mem[1], mem[2], mem[3]);
  126.  
  127. if ((mem[0] == 0x00) && (mem[1] == 0x40))
  128. printf ("Result  : VMware detected\n\n");
  129. else
  130. printf ("Result  : Native OS\n\n");
  131. }
  132.  
  133. void
  134. test5 (void)
  135. {
  136. unsigned int a, b;
  137.  
  138. __try {
  139. __asm {
  140.  
  141. // save register values on the stack
  142. push eax
  143. push ebx
  144. push ecx
  145. push edx
  146.  
  147. // perform fingerprint
  148. mov eax, 'VMXh' // VMware magic value (0x564D5868)
  149. mov ecx, 0Ah // special version cmd (0x0a)
  150. mov dx, 'VX' // special VMware I/O port (0x5658)
  151.  
  152. in eax, dx // special I/O cmd
  153.  
  154. mov a, ebx // data
  155. mov b, ecx // data (eax gets also modified but will not be evaluated)
  156.  
  157. // restore register values from the stack
  158. pop edx
  159. pop ecx
  160. pop ebx
  161. pop eax
  162. }
  163. } __except (EXCEPTION_EXECUTE_HANDLER) {}
  164.  
  165. #if DEBUG == 1
  166. printf ("\n [ a=%x ; b=%d ]\n\n", a, b);
  167. #endif
  168.  
  169. printf ("\n[+] Test 5: VMware \"get version\" command\n");
  170.  
  171. if (a == 'VMXh') { // is the value equal to the VMware magic value?
  172. printf ("Result  : VMware detected\nVersion : ");
  173. if (b == 1)
  174. printf ("Express\n\n");
  175. else if (b == 2)
  176. printf ("ESX\n\n");
  177. else if (b == 3)
  178. printf ("GSX\n\n");
  179. else if (b == 4)
  180. printf ("Workstation\n\n");
  181. else
  182. printf ("unknown version\n\n");
  183. }
  184. else
  185. printf ("Result  : Native OS\n\n");
  186. }
  187.  
  188. void
  189. test6 (void)
  190. {
  191. unsigned int a = 0;
  192.  
  193. __try {
  194. __asm {
  195.  
  196. // save register values on the stack
  197. push eax
  198. push ebx
  199. push ecx
  200. push edx
  201.  
  202. // perform fingerprint
  203. mov eax, 'VMXh' // VMware magic value (0x564D5868)
  204. mov ecx, 14h // get memory size command (0x14)
  205. mov dx, 'VX' // special VMware I/O port (0x5658)
  206.  
  207. in eax, dx // special I/O cmd
  208.  
  209. mov a, eax // data
  210.  
  211. // restore register values from the stack
  212. pop edx
  213. pop ecx
  214. pop ebx
  215. pop eax
  216. }
  217. } __except (EXCEPTION_EXECUTE_HANDLER) {}
  218.  
  219. printf ("\n[+] Test 6: VMware \"get memory size\" command\n");
  220.  
  221. if (a > 0)
  222. printf ("Result  : VMware detected\n\n");
  223. else
  224. printf ("Result  : Native OS\n\n");
  225. }
  226.  
  227. int
  228. test7_detect (LPEXCEPTION_POINTERS lpep)
  229. {
  230. printf ("\n[+] Test 7: VMware emulation mode\n");
  231.  
  232. if ((UINT_PTR)(lpep->ExceptionRecord->ExceptionAddress) > EndUserModeAddress)
  233. printf ("Result  : VMware detected (emulation mode detected)\n\n");
  234. else
  235. printf ("Result  : Native OS or VMware without emulation mode\n"
  236. "          (enabled acceleration)\n\n");
  237.  
  238. return (EXCEPTION_EXECUTE_HANDLER);
  239. }
  240.  
  241. void __declspec(naked)
  242. test7_switchcs ()
  243. {
  244. __asm {
  245. pop eax
  246. push 0x000F
  247. push eax
  248. retf
  249. }
  250. }
  251.  
  252. // Derek Soeder's (eEye Digital Security) VMware emulation test
  253. void
  254. test7 (void)
  255. {
  256. NTSETLDTENTRIES ZwSetLdtEntries;
  257. LDT_ENTRY csdesc;
  258.  
  259. ZwSetLdtEntries = (NTSETLDTENTRIES)GetProcAddress (GetModuleHandle ("ntdll.dll"), "ZwSetLdtEntries");
  260.  
  261. memset (&csdesc, 0, sizeof (csdesc));
  262.  
  263. csdesc.LimitLow = (WORD)(EndUserModeAddress >> 12);
  264. csdesc.HighWord.Bytes.Flags1 = 0xFA;
  265. csdesc.HighWord.Bytes.Flags2 = 0xC0 | ((EndUserModeAddress >> 28) & 0x0F);
  266.  
  267. ZwSetLdtEntries (0x000F, ((DWORD*)&csdesc)[0], ((DWORD*)&csdesc)[1], 0, 0, 0);
  268.  
  269. __try {
  270. test7_switchcs();
  271. __asm {
  272.            or eax, -1
  273.            jmp eax
  274.        }
  275.    }
  276.    __except (test7_detect (GetExceptionInformation())) { }
  277. }
  278.  
  279. int
  280. main (void)
  281. {
  282. printf ("\n\n####################################################\n");
  283. printf ("::       ScoopyNG - The VMware Detection Tool     ::\n");
  284. printf ("::              Windows version v1.0              ::\n\n");
  285.  
  286. test1 ();
  287. test2 ();
  288. test3 ();
  289. test4 ();
  290. test5 ();
  291. test6 ();
  292. test7 ();
  293.  
  294. printf ("::                   tk,  2008                    ::\n");
  295. printf ("::               [ www.trapkit.de ]               ::\n");
  296. printf ("####################################################\n\n");
  297.  
  298. return 0;
  299. }

Créditos: www.trapkit.de


Título: Re: Detección de VMware - ScoopyNG
Publicado por: MCKSys Argentina en 23 Febrero 2015, 18:39 pm
Excelente .:UND3R:.

Voy a hacer unas pruebas para ver como mitigar las detecciones.  :P

Saludos!


Título: Re: Detección de VMware - ScoopyNG
Publicado por: .:UND3R:. en 24 Febrero 2015, 02:19 am
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).