Using LastSystemRITEventTickCount as a (lame) antisandbox trick

LastSystemRITEventTickCount is a member of a _KUSER_SHARED_DATA structure. If you google for this particular field’s description you will eventually find sth along these lines:

Time in tick count for system-wide last user input across all terminal sessions. For MP performance, it is not updated all the time (e.g. once a minute per session). It is used for idle detection.

Since the user input is quite important from the sandbox perspective detecting changes (or lack of) of this particular field can act as a trivial (a.k.a. lame) anti-sandboxing trick.

Consider a simple routine like this:

   mov edx,ds:[7FFE02E4h] ; get LastSystemRITEventTickCount 
   back:
      pushad
      invoke Sleep,70 ; sleep for some time
      popad
      mov eax,ds:[7FFE02E4h] ; get new value of LastSystemRITEventTickCount 
      sub eax,edx
      jz  back
   ...

When ran, it waits for some user input (keyboard, mouse events) and only exits when these happen (sometimes more than one event is needed; this is probably caused by the update intervals).

LastSystemRITEventTickCount

Trivia fact: the very same value check is at the core of a function BeginIdleDetection.

An example demo program can be found here.

(lame) tricks with LdrRegisterDllNotification

It was Andrew (thanks!) who brought LdrRegisterDllNotification to my attention by asking on twitter if anyone has seen any malware using it. I couldn’t find any malware, but the function itself triggered my interest.

I quickly implemented a proof of concept. It shows how the callback that the API is registering could be utilized as a lame anti-* trick by malware that drops DLLs (in a case I am demoing), and maybe to do a few more tricky things (as I discuss below).

Consider the first .exe – let’s call it ‘good.exe’.

When executed, it drops a DLL called ‘foo.dll’.

It then resolves its one and only export ‘Bar’ and executes the function. The function shows a simple message box with a ‘Good’ message:

goodThe second .exe is called ‘better.exe’ (obviously 🙂 ).

It drops the very same ‘foo.dll’.

Functionally, it is almost identical with ‘good.exe’ as it is using the same source code. The only difference is that it registers the callback using a LdrRegisterDllNotification function. From now on, anytime a DLL is loaded the callback function takes control and is free to modify the content of the loaded DLL ‘on the fly’. As such, it can easily patch it and create a complete different memory image from the one we may expect by just looking at a static file ‘dropped’ by the .exe.

In my case the change is of a ‘visualame’ type. It’s for us to observe it.

The callback does only one thing – it checks if the string at a hardcoded offset inside the loaded DLL is equal to ‘Good’ and swaps it with a new string ‘Evil’; therefore, running the ‘better.exe’ will produce the following result:

evil

The example is intentionally simple, but there are many things that could be done here – the callback allows one to f.ex.

  • disable unwanted DLLs (by f.ex. patching their code)
  • detecting sandbox DLLs at a different stage (also use as a different enumeration method for loaded DLLs)
  • swapping data and code of modules on the fly
  • resolving API pointers earlier and potentially hooking / patching APIs used later in the code
  • introducing simple, atomic, business logic changes to the executed code (hard to spot) f.ex. modify JNZ to JZ, NOPing some instructions, etc.
  • etc.

Both files can be downloaded here.

Nothing ground breaking, but good to know about.