tetrane / reven-community

Join the REVEN community. Ask questions, talk about reverse engineering, discuss REVEN, and show off your work!
13 stars 1 forks source link

[BUG] VMProtect application running issue #30

Open renzhexigua opened 2 years ago

renzhexigua commented 2 years ago

Describe the bug

Scenario: Malware analysis replay

I want to record a VMProtect(v2.7) dropper(32-bit) that self-dropped-then-load another VMProtec(v2.7) driver(64-bit) on a Windows 7 x64 VM as I only have a Free license.

VT sample link

These two samples can run normally on normal virtual machine platforms, like VMware and VBox. And their malicious activities will be observed as well because they do not use anti-VM technology, but they do use anti-debugging methods.

On REVEN community Free platform, running the first dropper will pop up an APPCrash Window:

企业微信截图_16684142021134

And load the second driver manually will trigger a BSOD:

企业微信截图_16684146298583

I'm curious if the REVEN community version has compatibility issues when running VMProtect programs. Or am I missing something here? As I don't have a professional/enterprise license, I cannot test on those environments using Windows 10 OS.

To Reproduce Steps to reproduce the behavior:

  1. Create and import a fresh Windows 7 64-bit VM. (test OS: Windows 7 Ultimate SP1 x64 version)
  2. Download and execute the sample from VT link above. (APPCrash Error)
  3. Or load the dropped driver under %SYSTEMROOT%\system32\drivers directly. (I use the OSRLOADER tool) (BSOD Error)

Expected behavior The dropped driver can be loaded and run normally so that I can record its full transitions.

Host Environment

Additional context Both normal and abnormal scenarios use the same OS image base file(Windows 7 Ultimate SP1 x64 version), the only difference is that one runs on the normal VM platform(VMware/VBox), and the other runs on REVEN(qemu).

Quentin01 commented 2 years ago

Hello,

Thank you for your clear and complete issue.

From our knowledge, the free edition doesn't have compatibility issues with VMProtect as we don't think it is using any hardware special instructions (like VTx or recent x64 instruction set). If you have more information on the subject we will be glad to hear it.

Unfortunately, we don't have access to your sample on VT, so we can't try to reproduce it ourselves. If you are willing to give us the sample using another method let us know.

The next steps for us that you can also do on your side will be to record the crash using REVEN and check why the app is crashing. If it's due to an unsupported instruction this could easily be seen in the resulting trace starting from the crash.

Hope this helps.

renzhexigua commented 2 years ago

Update 1/n:

After some discussions with @Quentin01 , we found that the cause of the BSOD problem came from an address relocation issue. A global variable's address that should be fixed by VMProtect stub or the OS still holds the wrong value.

image

The sys's image base is 0x140000000, and the RDX still holds an address based on that base.

While, if you execute and debug it on a VMware/VBox, etc, VM environment, the RDX will hold a relocated address value instead.

image (1)

The issue doesn't seem to come from REVEN itself but from the OS configuration or the fact that the OS is doing different things depending on the virtualization software used.

I'll update you here if there are new findings.

johdcmlaker2000 commented 2 years ago

do you try to install the same OS build to VMware and to check dropper will run?

Quentin01 commented 2 years ago

do you try to install the same OS build to VMware and to check dropper will run?

From what we understood, it's already the case.

Both normal and abnormal scenarios use the same OS image base file(Windows 7 Ultimate SP1 x64 version), the only difference is that one runs on the normal VM platform(VMware/VBox), and the other runs on REVEN(qemu).

renzhexigua commented 2 years ago

Update 2/n:

Emulation/TCG mode will impact this driver's behavior.

I created a fresh and simplest VM using the same OS base image (Windows 7 Ultimate SP1 x64 version) from scratch with libvirt/virsh utilities:

virt-install --name=Win7 \
             --ram=1024 \
             --vcpus=1 \
             --disk path=vol.qcow2 \
             --cdrom=/path/to/Win7.iso \
             --os-variant win7

This domain will use the KVM mode by default when I execute virsh start Win7 directly, and you can get this info in two ways:

In this configuration, the driver could be loaded and started normally. But after I changed the hypervisor to qemu(full emulation) and launched it again:

image

The BSOD issue reappeared as I encountered on REVEN before. This means that I have found a factor to reproduce the problem without the REVEN.

image

With this new discovery, I did another set of comparative tests. Fortunately, the command line that REVEN uses is not too complicated.

{ /usr/bin/qemu-system-x86_64 | /path/to/panda-system-x86_64 } \
     -m 1024M -hda /path/to/VMs/Windows7_x64.qcow2.snapshots/root.qcow2 \
    -usbdevice tablet -chardev socket,path=/tmp/2022-11-14T171819.014177+0800.sock,server,nowait,id=monsock \
    -monitor chardev:monsock -net nic -net user,id=mynet0,net=10.0.2.0/24,dhcpstart=10.0.2.15\
    -enable-kvm

and

{ /usr/bin/qemu-system-x86_64 | /path/to/panda-system-x86_64 } \
     -m 1024M -hda /path/to/VMs/Windows7_x64.qcow2.snapshots/root.qcow2 \
    -usbdevice tablet -chardev socket,path=/tmp/2022-11-14T171819.014177+0800.sock,server,nowait,id=monsock \
    -monitor chardev:monsock -net nic -net user,id=mynet0,net=10.0.2.0/24,dhcpstart=10.0.2.15\

Notes: the disk snapshot (root.qcow2) here was created by REVEN before.

The tests without -enable-kvm option still failed.

Quentin01 commented 2 years ago

Hi,

It is possible you have stumbled upon a difference between the TCG CPU & native one.

We've already encountered a similar issue in the past, as detailed in one of our blog article. In our situation, the instruction fnstenv wasn't writing the last address where an FPU instruction was executed leading to a shellcode jumping to the wrong address.

If this is a similar situation, considering VMProtect is a protection software, I guess it's possible they could leverage such differences voluntarily. In our case we fixed the issue by using REVEN's Virtualbox-based recorder to record the trace instead. However our record/replay system using Virtualbox isn't working as well as Panda (QEMU based) - in your case, on a Windows 7 x64 it could work but probably won't (it works best on Windows 7 x86 system).

From this point on, the best path forward we see is to go looking for the difference in execution paths and maybe find a way to fix it, or at least identify it. For that, you can use your recorded crash in REVEN in conjunction with a live execution in your virtualizer and WinDBG (as you have shown in your screenshot).

Notably on our side, a first backward taint on rdx (storing the faulty address 0x14000e340) points to an interesting location in driver.sys+0x15b40. Showing the memory history on this location shows the address 0x14000e340 being built byte per byte. You could try placing a memory breakpoint on this addressdriver.sys+0x15b40 in WinDbg and compare at which point the value differ between the trace and the real execution. Then, apply similar methods iteratively to try & narrow down the reasons this differences occur.

Sorry that we can't help you more, let us know if you find something else on your side!