3

I am trying to analyze a malware in a virtual machine (linux), but it uses the cpuid output to verify if it is in a virtual machine/sandbox, and refuses to run malign code if inside a virtualized environment.

Is it possible to change/fake the output of the cpuid instruction, so that when the malware checks for the cpuid flags, it sees the cpuid of a non-virtualized machine?

I know that I can bypass that by changing the KVM config (like in section 'VM Detection countermeasures' from this tutorial), but I want to know if it is possible to do so from inside the guest machine, without changing the config in the host computer?

I thought about this possible solution:

1- $ set cpuid instruction output to X

2- $ run malware

3- when malware calls cpuid, it will see the flags of a non-virtualized environment and will execute malign code

Is there a command that does item 1? Or is there any other way that I can accomplish this without changing the KVM config from the host?

2 Answers 2

3

The CPUID returned value need to be store somewhere before being check against some known virtualization CPUID value.

It's hard to change your "hardware" sandbox CPUID value, but you can always fool the malware by editing the CPUID that your system is returning.

In a disassembler, try to locate where the cpuid instruction is used. You should see something like:

 xor    eax, eax
 mov    eax,0x40000000
 cpuid
 cmp ecx,0x4D566572
 jne <somewhere_else>

The cpuid syscall description is the following:

Returns processor identification and feature information to the EAX, EBX, ECX, and EDX registers, according to the input value entered initially in the EAX register.

In the above code snippet, the cpuid instruction is initialize with the AEX argument = "0x40000000", witch will ask to return the "Hypervisor brand" of your system.

Then, after the cpuid syscall, the ECX register's value is checked against "0x4D566572", which is a VMware related CPUID value.

In order to bypass this verification, set a breakpoint right after the cpuid instruction, and edit the registers as you want in to simulate a "non-virtual" environment.

You can also patch the malicious binary by replacing the cpuid code by some NOPs. This will completely remove the cpuid check.

Or you can edit the conditional jump that follow the cpuid value comparison, and make it useless.

5
  • It's a virtual machine. The VM software should get to control what values are returned from CPUID.
    – user253751
    Oct 29, 2019 at 13:20
  • 1
    That's right. For VMware products, you can edit the .vmx file of your system and check for the cpuid.1.ecx="0---:----:----:----:----:----:----:----" line.
    – Guillaume
    Oct 29, 2019 at 13:27
  • 2
    Keep in mind that patching the check out may or may not modify the rest of the executable, depending on how sophisticated the malware is.
    – user163495
    Oct 29, 2019 at 14:02
  • I tried to do that, but it also detects that and assembler is active. I was able to bypass by changing the vm config (KVM/qemu), but I would like to do that from inside the vm.
    – rmauter
    Oct 29, 2019 at 14:44
  • Did you checked how it is detected ? When working with anti-debug / anti-VM techniques "from inside the VM" , you have to trace back each techniques until you are able to bypass them all. Is your debugger being detected while patching the CPUID related register ? If you patched the binary, is their some sort of integrity control ?
    – Guillaume
    Oct 29, 2019 at 15:09
1

CPUID values are stored in a model specific register (MSR) platforms.

Reading and writing to these registers is handled by the rdmsr and wrmsr instructions, respectively. As these are privileged instructions, they can be executed only by the operating system. Use of the Linux msr kernel module creates a pseudo-file /dev/cpu/xID/msr (with a unique xID for each processor or processor core). A user with permissions to read and/or write to this file can use the file I/O API to access these registers.

Alternate example: VC++ __readmsr Generates the rdmsr instruction, which reads the model-specific register specified by register and returns its value, but the function is only available in kernel mode, and the routine is only available as an intrinsic.

3
  • It's a virtual machine. The VM software should get to control what values are returned from CPUID.
    – user253751
    Oct 29, 2019 at 13:20
  • Thanks for your response, but can you formulate more the answer? If I understand correctly, I should enter kernel mode and edit the pseudo-file /dev/cpu/xID/msr? Would it be possible to recompile the kernel to change the values of those instructions and run outside kernel mode?
    – rmauter
    Oct 29, 2019 at 14:49
  • What I want to imply is that you cannot normally do such modifications but if you want to and can work at kernel-level, then such an alteration may be possible by manipulating the output read from the MSR. So if you have kernel-level access, 1st thing is to read that file and check out its content.
    – Overmind
    Oct 30, 2019 at 6:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .