Replies: 11 comments 2 replies
-
If a debugger isn't registered, does the program crash? I don't quite understand from your description how this program works when the anti-debug checks don't fire. |
Beta Was this translation helpful? Give feedback.
-
@williballenthin That's a good question. All the samples with these instructions as well as the other 5-6 variations of this theme run when a debugger is not registered: These API calls are located in four functions: Two of these functions are related to logging. First, the logging flag is hard-coded to zero (always log): Second, two occurrences are located before the first check of the logging flag: |
Beta Was this translation helpful? Give feedback.
-
Thanks @utkonos for starting a conversation! Thanks @williballenthin for your comment! Would this be covered by Debugger Detection::UnhandledExceptionFilter [B0001.030]? The MBC method description references Al-Khaser Anti Debugging Tricks: UnhandledExceptionFilter |
Beta Was this translation helpful? Give feedback.
-
From reading the description: this looks very similar except that there is no check for the subsequent state after these instructions. Thanks for pointing this out too. I was looking only at debugger evasion rather than detection because that's what the purpose of these instructions appears to be. I still need to answer @williballenthin's question of how/why does the binary not crash during normal debugger-free execution. |
Beta Was this translation helpful? Give feedback.
-
To answer the question, "Why does the malware run fine when a debugger isn't attached?" it looks like lstrcpy has internal exception handling according to Microsoft documentation:
Whether you can (easily) tell your debugger to ignore it and pass it to the program may depend on which debugger you are using. |
Beta Was this translation helpful? Give feedback.
-
I agree that the Debugger Detection::UnhandledExceptionFilter is close but not quite what is happening here. This feels more like a Denial Of Service (DoS) against the debugger by causing numerous intentional exceptions. A mitigation would be to identify the exception type and automatically pass it to the program instead of stopping the debugger. Different debuggers have different options / ways of doing that. |
Beta Was this translation helpful? Give feedback.
-
@malwarefrank Thanks. That exaplains it. My mitigation was just to patch the instructions with NOP since they serve no purpose in the rest of the code. Your alternative mitigation is better because it wouldn't need to detect all the different variations of this pattern. I have a set of YARA rules that detect each of the variations. I'll contribute them once I get permission to do so. Next question: this behavior fits better in Debugger Evasion rather than Debugger Detection, and I like your name: "Denial of Service" as the MBC method name for this. It is general enough that it can have other types of debugger denial of service added to it if it needs to be expanded beyond just exceptions. @dzbeck Thoughts on adding this as a new method under Debugger Evasion called "Denial of Service"? |
Beta Was this translation helpful? Give feedback.
-
I wrote a set of YARA rules that detect it. The new yara feature that lets you reference a particular function from a DLL is pretty neat and i leveraged it in these rules. |
Beta Was this translation helpful? Give feedback.
-
@utkonos @wballenthin and others, what do you think of these two new methods? Use Exception - The malware intentionally causes an exception that is handled by the code and allowed to run to its intended effect; however, an attached Debugger will “catch” the exception and pause execution. This method may be combined with the Timing/Delay Check, UnhandledExceptionFilter, or Exception Flooding methods. Exception Flooding - The malware causes numerous intentional exceptions, which are not ignored by the debugger (see Debugger Detection::Use Exception), slowing manual debugging (analyst exhaustion) or preventing automated debugging. Would "Use Exception" fall under the Debugger Detection objective and "Exception Flooding" fall under Debugger Evasion? Please suggest different names, description edits, etc. Thanks! |
Beta Was this translation helpful? Give feedback.
-
Yes, this sounds fine to me. And I think those two locations work as well. |
Beta Was this translation helpful? Give feedback.
-
The main branch has been updated with the two new methods. Thanks @utkonos, @williballenthin, and @malwarefrank! |
Beta Was this translation helpful? Give feedback.
-
I'm not sure of what to call this, but here is the description. It doesn't appear to fit into any of the categorizations under the current list of methods. However, please point me to any method that this fits in that I have missed.
Example
Malware Family: Quantum Locker
SHA256: 2fd8356abd42b19799aca857990a5f49631b02bd3253f80d96b5d27dcfd2f7c9
Description
This is a set of three instructions that comprise a call to
lstrcpyA
. The first argument,lpString1
, is the destination buffer. The address of this destination is located in a read-only section of the binary. The source,lpString2
, points to a dword containing eight random uppercase and lowercase letters. This call raises an access violation for trying to write to a read-only location in memory. There is no custom exception handler registered by this binary, so the effect is to cause a debugger to stop execution at the location of the exception and wait for the user to continue. This set of instructions is observed in a few different forms. Here are a few examples:Location:
0x1400040a6
Location:
0x140004100
Location:
0x140005cdb
A few of these examples also exhibit MBC Interleaving Code
B0032.014
Beta Was this translation helpful? Give feedback.
All reactions