LordNoteworthy / al-khaser

Public malware techniques used in the wild: Virtual Machine, Emulation, Debuggers, Sandbox detection.
GNU General Public License v2.0
5.85k stars 1.17k forks source link

System Resources layout as a potential VM detection vector #112

Open gsuberland opened 6 years ago

gsuberland commented 6 years ago

I was reading XPN's article about a TotalMeltdown exploit and saw that they had updated their code to check which physical addresses were mapped when doing their search for an _EPROCESS struct, to avoid BSOD. They do this via the RESOURCEMAP registry key, which has some REG_RESOURCE_LIST type values. I hadn't come across that registry value type before and it turns out that it's a fairly in-depth struct that describes hardware resources.

This got me thinking - do the physical memory maps change between a host and a VM, and are VM maps generally the same on every box? I can answer the first one: yes. I wrote a tool to dump the address lists and here are the results:

Host box 1 (Win10, 32GB RAM):

[*] Getting physical memory regions from registry
[*] Reading data from Hardware\ResourceMap\System Resources\Physical Memory\.Translated
  --> Memory region found: 0000000000001000 - 000000000009d000
  --> Memory region found: 00000000cb52d000 - 00000000cb98c000
[*] Reading data from Hardware\ResourceMap\System Resources\Reserved\.Translated
  --> Memory region found: 0000000000001000 - 000000000009d000
[*] Reading data from Hardware\ResourceMap\System Resources\Loader Reserved\.Raw
  --> Memory region found: 0000000000000000 - 00000000000a0000
  --> Memory region found: 00000000cb526000 - 00000000cb52d000
  --> Memory region found: 00000000fec00000 - 00000000fec01000

Host box 2 (Win10, 32GB RAM, Hyper-V enabled):

[*] Getting physical memory regions from registry
[*] Reading data from Hardware\ResourceMap\System Resources\Physical Memory\.Translated
  --> Memory region found: 0000000000001000 - 000000000009d000
[*] Reading data from Hardware\ResourceMap\System Resources\Reserved\.Translated
  --> Memory region found: 0000000000001000 - 000000000009d000
  --> Memory region found: 00000000001f5000 - 00000000001fe000
  --> Memory region found: 00000000002fe000 - 00000000003fe000
[*] Reading data from Hardware\ResourceMap\System Resources\Loader Reserved\.Raw
  --> Memory region found: 0000000000000000 - 00000000000a0000
  --> Memory region found: 00000000001f5000 - 00000000001fe000
  --> Memory region found: 0000000000293000 - 0000000000297000
  --> Memory region found: 0000000000875000 - 000000000095a000
  --> Memory region found: 000000000364c000 - 0000000003675000
  --> Memory region found: 000000006929d000 - 000000007fa00000

VirtualBox VM on host 1 (Win8.1 x64, 2GB RAM assigned):

[*] Getting physical memory regions from registry
[*] Reading data from Hardware\ResourceMap\System Resources\Physical Memory\.Translated
  --> Memory region found: 0000000000001000 - 000000000009f000
[*] Reading data from Hardware\ResourceMap\System Resources\Reserved\.Translated
  --> Memory region found: 0000000000001000 - 000000000000e000
[*] Reading data from Hardware\ResourceMap\System Resources\Loader Reserved\.Raw
  --> Memory region found: 0000000000000000 - 000000000000e000
  --> Memory region found: 00000000000f0000 - 0000000000100000

VirtualBox VM on host 1 (Win8.1 x64, 10GB RAM assigned):

[*] Getting physical memory regions from registry
[*] Reading data from Hardware\ResourceMap\System Resources\Physical Memory\.Translated
  --> Memory region found: 0000000000001000 - 000000000009f000
[*] Reading data from Hardware\ResourceMap\System Resources\Reserved\.Translated
  --> Memory region found: 0000000000001000 - 000000000000e000
[*] Reading data from Hardware\ResourceMap\System Resources\Loader Reserved\.Raw
  --> Memory region found: 0000000000000000 - 000000000000e000
  --> Memory region found: 00000000000f0000 - 0000000000130000

Hyper-V VM on host 2 (Win10, dynamic RAM):

[*] Getting physical memory regions from registry
[*] Reading data from Hardware\ResourceMap\System Resources\Physical Memory\.Translated
  --> Memory region found: 0000000000001000 - 00000000000a0000
[*] Reading data from Hardware\ResourceMap\System Resources\Reserved\.Translated
  --> Memory region found: 0000000000001000 - 00000000000a0000
[*] Reading data from Hardware\ResourceMap\System Resources\Loader Reserved\.Raw
  --> Memory region found: 0000000000000000 - 00000000000a0000
  --> Memory region found: 000000007eee9000 - 000000007ef1b000

HyperV VM on host 2 (Win10, 2GB RAM assigned):

[*] Getting physical memory regions from registry
[*] Reading data from Hardware\ResourceMap\System Resources\Physical Memory\.Translated
  --> Memory region found: 0000000000001000 - 00000000000a0000
[*] Reading data from Hardware\ResourceMap\System Resources\Reserved\.Translated
  --> Memory region found: 0000000000001000 - 00000000000a0000
[*] Reading data from Hardware\ResourceMap\System Resources\Loader Reserved\.Raw
  --> Memory region found: 0000000000000000 - 00000000000a0000
  --> Memory region found: 000000007eee9000 - 000000007ef1b000

There are patterns here that we can probably exploit, although I'd like more data samples to be sure.

A preliminary test would be:

I could do with more data points before I write this up, so @LordNoteworthy it'd be great if you could try this on your side with various VM solutions.

Here's the code for the test utility: PhysMemResourceList.c.txt

If you're feeling lazy and don't wanna compile the above you can use my compiled binary (requires VC Runtime 14 x86): PhysMemResourceList.zip

Let me know what results you get :)

gsuberland commented 6 years ago

Aside: there are other REG_RESOURCE_LIST values in the registry and they contain all sorts of hardware information that we can probably fingerprint in various ways. My code only dumps the memory entries from the lists and ignores everything else. See CM_RESOURCE_LIST and related structs for more info.

gsuberland commented 6 years ago

@LordNoteworthy Can you run the PhysMemoryResourceList tool above on a few platforms and paste the results please? Once I've got data samples I can write this up as a check.

LordNoteworthy commented 6 years ago

@gsuberland

VirtualBox VM (Windows 7 x64, 4GB assigned)

[*] Getting physical memory regions from registry
[*] Reading data from Hardware\ResourceMap\System Resources\Physical Memory\.Translated
  --> Memory region found: 0000000000001000 - 000000000009f000
[*] Reading data from Hardware\ResourceMap\System Resources\Reserved\.Translated

  --> Memory region found: 0000000000001000 - 0000000000008000
[*] Reading data from Hardware\ResourceMap\System Resources\Loader Reserved\.Raw

  --> Memory region found: 0000000000000000 - 0000000000008000
  --> Memory region found: 0000000000110000 - 0000000000140000

VirtualBox VM (Windows 7 x86, 2GB assigned)

[*] Getting physical memory regions from registry
[*] Reading data from Hardware\ResourceMap\System Resources\Physical Memory\.Tra
nslated
  --> Memory region found: 0000000000001000 - 000000000009f000
  --> Memory region found: 0000000000100000 - 000000007fff0000
[*] Reading data from Hardware\ResourceMap\System Resources\Reserved\.Translated

  --> Memory region found: 0000000000001000 - 0000000000005000
  --> Memory region found: 0000000000030000 - 0000000000040000
[*] Reading data from Hardware\ResourceMap\System Resources\Loader Reserved\.Raw

  --> Memory region found: 0000000000000000 - 0000000000005000
  --> Memory region found: 0000000000030000 - 0000000000040000
  --> Memory region found: 000000000009f000 - 00000000000a0000
  --> Memory region found: 00000000000f0000 - 0000000000100000
  --> Memory region found: 000000007fff0000 - 0000000080000000
  --> Memory region found: 00000000fec00000 - 00000000fec01000
  --> Memory region found: 00000000fee00000 - 00000000fee01000
  --> Memory region found: 00000000fffc0000 - 0000000100000000

VirtualBox VM (Windows 10 x64, 4GB assigned)

[*] Getting physical memory regions from registry
[*] Reading data from Hardware\ResourceMap\System Resources\Physical Memory\.Translated
  --> Memory region found: 0000000000001000 - 000000000009f000
[*] Reading data from Hardware\ResourceMap\System Resources\Reserved\.Translated
  --> Memory region found: 0000000000001000 - 0000000000017000
[*] Reading data from Hardware\ResourceMap\System Resources\Loader Reserved\.Raw
  --> Memory region found: 0000000000000000 - 0000000000017000
  --> Memory region found: 0000000000102000 - 0000000000103000

My host is linux, I will post more about VMWare.

gsuberland commented 3 years ago

I ended up doing some more research into this at work. Writeup here.

https://labs.nettitude.com/blog/vm-detection-tricks-part-1-physical-memory-resource-maps/

I'll port the code into here when I get chance.