>>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/wuqcUaiE • http://pastebin.com/VDDRcmdL • http://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.