2

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?

1

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.

|improve this answer|||||
  • It's a virtual machine. The VM software should get to control what values are returned from CPUID. – user253751 Oct 29 '19 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 '19 at 13:27
  • 1
    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. – MechMK1 Oct 29 '19 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 '19 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 '19 at 15:09
0

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.

|improve this answer|||||
  • It's a virtual machine. The VM software should get to control what values are returned from CPUID. – user253751 Oct 29 '19 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 '19 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 '19 at 6:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.