kevoreilly / CAPEv2

Malware Configuration And Payload Extraction
https://capesandbox.com/analysis/
Other
1.99k stars 424 forks source link

Al-khaser bypass is misleading #2337

Closed packmad closed 1 month ago

packmad commented 1 month ago

Dear developers, First of all, thank you for your open product, which we (our team and I) use for our research projects.

When we first installed CAPE, one of the first tests we did was to run Al-khaser to get an idea of the techniques that were not mitigated (then possibly counteract the code to give the blue pills). However, as all evasion techniques were mitigated, we proceeded happily :)

Today we discovered that there is a custom rule for Al-khaser's print function that changes all results! This rule introduces a huge flaw in CAPE's evaluation, and we believe it should be removed. The purpose of Al-khaser is precisely to test the evasion capabilities of sandboxes, and this rule does not allow it to do this properly.

Instead (and we will try to help with this by pushing new rules), you should try to mitigate the various techniques, not the function that shows the results.

This is the list of the evasive techniques that detect CAPEv2

[Fri Oct  4 13:11:04 2024] [*] Checking If Parent Process is explorer.exe  -> 1
[Fri Oct  4 13:11:04 2024] [*] Checking SeDebugPrivilege  -> 1
[Fri Oct  4 13:11:05 2024] [*] Checking NtYieldExecution  -> 1
[Fri Oct  4 13:11:05 2024] [*] Checking if process is in a job   -> 1
[Fri Oct  4 13:11:05 2024] [*] Checking VirtualAlloc write watch (API calls)  -> 1
[Fri Oct  4 13:11:20 2024] [*] Walking process memory with GetModuleInformation  -> 1
[Fri Oct  4 13:11:23 2024] [*] Walking process memory for hidden modules  -> 1
[Fri Oct  4 13:11:24 2024] [*] Checking Local Descriptor Table location  -> 1
[Fri Oct  4 13:11:30 2024] [*] Checking Number of cores in machine using WMI  -> 1
[Fri Oct  4 13:11:31 2024] [*] Checking hard disk size using WMI  -> 1
[Fri Oct  4 13:11:36 2024] [*] Checking lack of user input  -> 1
[Fri Oct  4 13:11:36 2024] [*] Checking if CPU hypervisor field is set using cpuid(0x1) -> 1
[Fri Oct  4 13:11:36 2024] [*] Checking hypervisor vendor using cpuid(0x40000000) -> 1
[Fri Oct  4 13:13:11 2024] [*] Checking Current Temperature using WMI  -> 1
[Fri Oct  4 13:13:22 2024] [*] Checking ProcessId using WMI  -> 1
[Fri Oct  4 13:13:22 2024] [*] Checking power capabilities  -> 1
[Fri Oct  4 13:13:30 2024] [*] Checking CPU fan using WMI  -> 1
[Fri Oct  4 13:13:39 2024] [*] Checking Win32_CacheMemory with WMI  -> 1
[Fri Oct  4 13:13:46 2024] [*] Checking Win32_PhysicalMemory with WMI  -> 1
[Fri Oct  4 13:13:54 2024] [*] Checking Win32_MemoryDevice with WMI  -> 1
[Fri Oct  4 13:14:03 2024] [*] Checking Win32_MemoryArray with WMI  -> 1
[Fri Oct  4 13:14:11 2024] [*] Checking Win32_VoltageProbe with WMI  -> 1
[Fri Oct  4 13:14:19 2024] [*] Checking Win32_PortConnector with WMI  -> 1
[Fri Oct  4 13:14:28 2024] [*] Checking Win32_SMBIOSMemory with WMI  -> 1
[Fri Oct  4 13:14:48 2024] [*] Checking ThermalZoneInfo performance counters with WMI  -> 1
[Fri Oct  4 13:14:56 2024] [*] Checking CIM_Memory with WMI  -> 1
[Fri Oct  4 13:15:04 2024] [*] Checking CIM_Sensor with WMI  -> 1
[Fri Oct  4 13:15:13 2024] [*] Checking CIM_NumericSensor with WMI  -> 1
[Fri Oct  4 13:15:21 2024] [*] Checking CIM_TemperatureSensor with WMI  -> 1
[Fri Oct  4 13:15:30 2024] [*] Checking CIM_VoltageSensor with WMI  -> 1
[Fri Oct  4 13:15:40 2024] [*] Checking CIM_PhysicalConnector with WMI  -> 1
[Fri Oct  4 13:15:50 2024] [*] Checking CIM_Slot with WMI  -> 1
[Fri Oct  4 13:16:54 2024] [*] Checking ACPI tables   -> 1
[Fri Oct  4 13:16:54 2024] [*] Checking for Hyper-V global objects  -> 1
kevoreilly commented 1 month ago

Hello and thanks for the feedback. Reading your story I can understand your frustration. However, it's a bit unfair to describe this entire list as things that "detect CAPEv2". CAPE is a usermode sandbox that runs on a multitude of hypervisors as well as bare metal.

[Fri Oct  4 07:54:26 2024] [*] Checking if CPU hypervisor field is set using cpuid(0x1) -> 0

Things like the hypervisor bit are really nothing to do with CAPE and all to do with virtual machine setup. This bit is not detected in my vms for example, and we do a lot to try and encourage good vm setup (for example https://www.doomedraven.com/2016/05/kvm.html mentions how to hide the hypervisor bit) but this is down to the user and hypervisor, and not something that CAPE should be blamed for. You didn't even mention which hypervisor you are using, nor how it was set up.

I hear your suggestion to 'mitigate the various techniques, not the function that shows the results'. But if we take the previous example of the hypervisor bit, as a usermode sandbox it's not possible to directly mitigate the output from the processor's CPUID instruction. The only way a usermode sandbox could reasonably be expected to help hide this from malware is by interfering with the result of the test. At least this is something!

There aren't many options for a usermode sandbox to hide this technique from a malware sample, but fortunately CAPE does have a unique and powerful debugger which is very stealthy and can be dynamically programmed during detonation by yara signature to set breakpoints on code and dynamically perform actions such as control flow manipulation. So it can, for example, break on the CPUID instruction and emulate it, or break after and modify the register values.

This is one of CAPE's greatest assets but a huge challenge for the project is making this capability well known and accessible to the end user. One of the only ways I have to try and 'sell' this capability is to demonstrate it by creating an array of yara signatures to show off its power whilst also making CAPE perform as well as possible against as much evasive malware and tests as possible. It's in this vein that I have also created dynamic bypasses for tools such as Pafish and Al-khaser.

So that is why this bypass for Al-khaser exists, of course its objective is to demonstrate how to bypass detection in the simplest way possible. It turns out there is a single function which evaluates (and prints) results so rather than bypassing individual tests it just targets the simplest intervention. It could of course put breakpoints on individual tests and subvert their results one by one, but that would be inefficient.

Did you notice that the Al-khaser debugger detection tests all failed? When you describe this bypass as merely a 'custom rule' that changes the results I think that does it a massive disservice, as if it were somehow fudging the results rather than demonstrating a powerful capability. During detonation, cape's monitor dynamically scans memory, detects a code sequence and programs the debugger to set a breakpoint on a specific instruction. The breakpoint is set and execution proceeds to sail through all Al-khaser's anti-debugger tests, hitting the breakpoint for every failed test and actively switching the results.

Really any intervention performed by cape, whether by debugger or API hooks, could be described as being misleading. For example, there are numerous anti-evasion techniques performed by API hooks such as hiding the number of processors/cores by modifying the results of API calls. Would you describe these too as 'custom rules that change the results'? Because really this boils down to the same thing, and other techniques or APIs might see through these interventions. Other examples worth considering are yara signatures that generically detect techniques, such as Syscall.yar which tries to detect variants of direct syscalls and capture them. If this signature worked against Al-khaser and avoided a syscall check, would it be misleading? Perhaps as it is more generic, not detecting a particular tool or malware family, it would be viewed as fair enough and better than nothing. If it then missed malware using a different variant of the same technique, it might then be accused of being misleading - seems like an impossible situation.

Perhaps we should make even more effort in documenting virtual machine setup by mentioning the presence of not just this capability in cape, but also the presence of the existing dynamic evasion bypasses as well, in case users to wish to use things like Al-khaser to assess the evasion capabilities. I will look at adding a note to the documentation somewhere that to test CAPE stripped of its inbuilt evasion bypasses, running with yarascan=0 might be worth trying. But since this bypass is a demonstration of (and part of) one of cape's greatest strengths, on balance I don't think it should just be binned.

packmad commented 1 month ago

Thanks for your reply. I still maintain that it must be disabled by default. If it was, I would immediately realise that I would have to tweak the qemu installation to bypass those controls.

There are already plenty of examples of how to use the yara+debugger combo (again, great idea, we are very happy with CAPE).

Then... the product is yours, but really, for those who use it it could make a difference in testing before "production".

M2C

doomedraven commented 1 month ago

yes im agree on this, is a bad ass example how powerfull cape is, but it al-khaser and pafish should be disabled as it doesn't allow properly test VM. So that mislead some testing

YungBinary commented 3 weeks ago

@packmad This is what you'll need to add to your VM's XML:

  <features>
    ...
    <kvm>
      <hidden state="on"/>
    </kvm>
    ...
  </features>

And add "kvm=off" to the QEMU command line args:

    <qemu:arg value="-cpu"/>
    <qemu:arg value="host,kvm=off"/>
packmad commented 3 weeks ago

@packmad This is what you'll need to add to your VM's XML:

  <features>
    ...
    <kvm>
      <hidden state="on"/>
    </kvm>
    ...
  </features>

And add "kvm=off" to the QEMU command line args:

    <qemu:arg value="-cpu"/>
    <qemu:arg value="host,kvm=off"/>

Thanks bro, we alI found it out recently... And we are slowly pushing some PR.