>>Returning back to the discussion where I suggested it would be nice to
>>build OS kernels that would fail deliberately when virtualized to close
>>off that class of malware, especially on the new Intel Skylake chips
>>that have fixed so many virtualization bugs that they can (reportedly)
>>run VT inside VT and nest virtualization so efficiently you can
>>virtualize ridiculous numbers of VMs even inside each other, with so
>>little overhead and few virtualization artifacts that they are nearly
>>undetectable when virtualized.
>There are at least two issues here.
>
>First, some of us *want* to run OpenBSD in a virtualised environment, so
there would have to be multiple code paths/sysctl to deal with this. Also,
what you're asking for is very x86 specific.

These days, I would guess more stuff runs virtualized than not.
A kernel compile/build time configuration would be sufficient here. Yes, and
even more specific than that, I am concerned about the latest Skylake
generation x86 and follow ons - earlier processors have readily documented
bugs that can be used to identify hypervisors. (and these can be used
independently of the specific brand of hypervisor)

>
>Second, it is simply not true that virtualisation is nearly undetectable.
This is of course a moving target, but I'd be amazed if close examination of
processor features made a VM undetectable. Mostly VMs go out of their way to
let >the guest OS know they're running in a VM, so paravirtual drivers can be
used.
>

Since we are talking about malicious applications of hypervisors, and
virtualization features, we can assume that a specialized hypervisor backdoor,
will probably try to not be so blatant and may not be as easy to detect as a
garden variety VM. A small hypervisor, that limits its scope to interfering
with only a few specific functions would not leave so many artifacts to
detect, in effect passing through most functionality to the real hardware.
(see example below)

>The virtualised hardware has a passing relation to actual hardware. Taking
the easy way out, insist on any server hardware being based on Nehalem or
later chipsets, and you'd immediately block the use of Xen, KVM, and >probably
most other VMs. Until reasonably recently, a Xen HVM domU features a modern
(post pentium 3) processor attached to a 440BX chipset. This is, of course,
non existent in the real world. There are many, many other >quirks that
identify VMs, they do not make a serious effort to hide their presence.

This is a lot of hand waving ("many") without actual details. Xen, bhyve and
lots of other, ahem, simpler, VM systems have unique documented quirks (how's
that for understatement). I'm concerned mostly about the more complex and less
quirky and fingerprintable HyperV, VMware, or derivatives thereof with the
identification APIs removed or disabled, but primarily the threat lurks in
unknown small, specialized hypervisors which might have a very small footprint
to identify. Ideally I'm looking for something that will work across all
hypervisors, to detect virtualization generically instead of VM implementation
specific quirks or tricks and even better if it works across multiple
chipsets, but as stated above I am primarily concerned with the latest
generation of x86 chips where the principal threat lies, as a long set of VM
and chipset specific checks sounds like an ugly to maintain mess (see tricks
below). I concede this may not be possible but we won't know until looking for
such.

Here is an example of a small, difficult to detect custom hypervisor (though
this one is used for defensive purposes) and a pretty cool research paper
which also discusses things relevant to this topic:
http://www-brs.ub.ruhr-uni-bochum.de/netahtml/HSS/Diss/WillemsCarsten/diss.pd
f

Some approaches:

Timing loops have always been suggested as a first idea, but in practice are
unwieldy and inaccurate. Network packet timing has also been suggested, but
again I don't know if these approaches will work anymore in new high
efficiency virtualization. Other folks have suggested looking for memory
layout anomalies introduced by virtualization. This seems to me to hold the
most promise.

For reference I include below some documented tricks to identify common VMs.
These tricks in the end are crap. They are just signatures for a snapshot of a
moving target and would not really be useful for defense. I am hoping someone
might have some other clever ideas, and that looking at the list below might
stimulate some creativity. Memory layout integrity seems to me to be the only
avenue that may be feasible right now, but maybe someone else has some other
approach that hasn't been considered yet, as there are a lot of smart folks
here.

Cheers,
--dr



Tricks (but not much treats)
========================

Ed Skoudis and Tom Liston enumerated many VM detection tools and some
anti-anti-VM techniques in their now quite dated 2006 paper:

http://handlers.sans.org/tliston/ThwartingVMDetection_Liston_Skoudis.pdf

and Symantec enumerated some potential techniques in this (now also dated)
paper:

http://www.symantec.com/avcenter/reference/Virtual_Machine_Threats.pdf


More Tricks:

VirtualBox
•       http://pastebin.com/RU6A2UuB (9 different methods, registry, dropped 
VBOX
dlls, pipe names etc)
•       http://pastebin.com/xhFABpPL (Machine provider name)
•       http://pastebin.com/v8LnMiZs (Innotek trick)
•       http://pastebin.com/fPY4MiYq (Bios Brand and Bios Version)
•       http://pastebin.com/Geggzp4G (Bios Brand and Bios Version)
•       http://pastebin.com/T0s5gVGW (Parsing SMBiosData searching for
newly-introduced or bizarre type)
•       http://pastebin.com/AjHWApes (Cadmus Mac Address Trick)
•       http://pastebin.com/wh4NAP26 (VBoxSharedFolderFS Trick)
•       http://pastebin.com/Nsv5B1yk (Resume Flag Trick)
VirtualPc
•       http://pastebin.com/wuqcUaiEhttp://pastebin.com/VDDRcmdLhttp://pastebin.com/exAK5XQx (Reset Trick)
•       http://pastebin.com/HVActZMC (CPUID Trick)
Hypervisor detection
•       http://pastebin.com/2gv72r7d

// VMware detection as described by Elias Bachaalany
function IsInsideVMware: Boolean;
begin
  Result := True;

  try
    asm
      push edx;
      push ecx;
      push ebx;

      mov eax, 'VMXh';
      mov ebx, 0;
      mov ecx, 10;
      mov edx, 'VX';

      in eax, dx;

      cmp ebx, 'VMXh';
      setz [Result];

      pop ebx;
      pop ecx;
      pop edx;
    end;
  except
    Result := False;
  end;
end;

function IsHyperV: Boolean;
asm
  cpuid;
  test ecx, ecx;
  sets [Result];
end;
The following function checks for Hyper-V via the Vendor Branding string (on
VMware this returns "VMwareVMware":
function IsRunningUnderHyperV: BOOL; stdcall;
var
  VMBranding: array[0..12] of AnsiChar;
begin
  asm
    mov eax, $40000000;
    cpuid;
        mov dword ptr [VMBranding+0], ebx;  // Get the VM branding string
        mov dword ptr [VMBranding+4], ecx;
        mov dword ptr [VMBranding+8], edx;
  end;
  VMBranding[12] := #0;

  Result := CompareText(String(VMBranding), 'Microsoft Hv') = 0;
end;

There are also details on other tricks at this codeproject VM identification
project:

http://www.codeproject.com/Articles/9823/Detect-if-your-program-is-running-in
side-a-Virtual

In the end, these are all useless.

Reply via email to