Go back

Contents

Human-like behavior detection methods
1. General detection methods via registry
1.1. Check the number of recently opened documents
1.2. Check if the browser history contains at least 10 URLs
1.3. Check if certain software packages were installed
1.4. Countermeasures
2. Check for user presence at the moment of executing a process
2.1. Check the mouse movement
2.2. Check via a request for user interaction
2.3. Evasion technique for the Cuckoo human-interaction module
2.4. No suspicious actions until a document is scrolled down
2.5. Check user activity via GetLastInputInfo
Countermeasures
Signature recommendations
Credits


Human-like behavior detection methods

All the techniques described in this group make use of the fact that certain actions are performed differently by a user and by a virtual environment.


1. General detection methods via registry

The registry is a storage for different pieces of information. For example, recently opened URLs and documents, and software installation notes are stored here. All of these may be used to determine if the machine is operated by a human user and is not a sandbox.


1.1. Check the number of recently opened documents

It’s hard to imagine a typical host system where the user does not open any documents. Therefore, the lack of recently opened documents indicates this is likely a virtual environment.


Code sample (VB)

Public Function DKTxHE() As Boolean
DKTxHE = RecentFiles.Count < 3
End Function

This code sample was taken from SentinelOne article


1.2. Check if the browser history contains at least 10 URLs

It’s hard to imagine a typical host system where the user does not browse the Internet. Therefore, if there are fewer than 10 URLs in the browser history, this is likely a sandbox or VM.


Code sample (for Chrome)

bool chrome_history_evasion(int min_websites_visited = 10)
{
  sqlite3 *db;
  int rc;
  bool vm_found = false;

  rc = sqlite3_open("C:\\Users\\<USER_NAME>\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\History", &db);
  if (!rc)
  {
    char **results = nullptr;
    char *error = nullptr;
    int rows, columns;

    rc = sqlite3_get_table(db, "SELECT DISTINCT title FROM urls;", &results, &rows, &columns, &error);
    if (!rc)
      vm_found = rows < min_websites_visited;
    sqlite3_free_table(results);
  }

  sqlite3_close(db);
  return vm_found;
}


1.3. Check if certain software packages were installed

If the system is only used for simulation purposes then it is likely to have many fewer installed software packages than a usual user’s work machine. The installed packages may be specific to emulation purposes, not the ones that are usually used by human operators. Therefore, the list of installed packages may be compared to the list of commonly used applications to determine if it’s a sandbox.


Code sample (PowerShell)

Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Format-Table -AutoSize | Measure-Object -Line


1.4. Countermeasures

Countermeasures are simple:

  • open few documents to update the recent history
  • open few internet URLs to create a browsing history
  • install some lightweight software (like Notepad++)


2. Check for user presence at the moment of executing a process

The following sub-group leverages the differences between a user’s interaction with the machine and the actions of a virtual environment.


2.1. Check the mouse movement

This method relies on the fact that a user frequently moves the mouse during actual work.


Some sandboxes and antivirus virtual machines have a static cursor position because they do not emulate any user activity while automatically running the files.


Code sample

int gensandbox_mouse_act() {
    POINT position1, position2;

    GetCursorPos(&position1);
    Sleep(2000);
    GetCursorPos(&position2);

    if ((position1.x == position2.x) && (position1.y == position2.y))
        // No mouse activity during the sleep.
        return TRUE;
    else
        return FALSE;
}

This code sample was taken from pafish project

Such a short delay of only 2 seconds implies that the user should be active at the moment of infection.


More sophisticated checks rely on detection of not only the mouse movement per se but the pattern of such movement. The following example is taken from the research of LummaC2 Stealer conducted by Outpost24.

First, malware captures mouse movements with the delay of 50 msec between them.



Second, the vectors are drawn out of paired captured positions.



Next, the angles are calculated between the corresponding vectors.



Finally, the angles are compared with the 45.0º threshold value, and if any of the angles is bigger than this hardcoded value, malware treats the result as being suspicious and does not execute the malicious code.


Countermeasures

Implement the module for mouse movement during a sample emulation. Make sure to come up with a more delicate way of interacting with the mouse cursor rather than just random movements all around the screen, so that it resembles the behavior of a human being.


2.2. Check via a request for user interaction

Some malware samples contain a GUI installer which requires user interaction. For example, the user must click the “Install” or “Next” buttons. Therefore, the malware may take no action unless the button is clicked. Standard sandboxes like Cuckoo have a module which simulates user activity. It searches for and clicks buttons with the captions mentioned above.


To prevent auto-clicking, a malware sample may create buttons with a class name that differs from “Button” or with a different caption (not “Install” or “Next”). This way the sandbox can’t detect and click the button.


Code sample

   // we use extended style flags to make a static look like a button
   HWND hButton = CreateWindowExW(
       WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE,  // extended style flags
       TEXT("static"),         // class "static" instead of "button"
       TEXT("Real next"),      // caption different from “Install” or “Next”
       WS_VISIBLE | WS_CHILD | WS_GROUP | SS_CENTER,  // usual style flags
       10, 10, 80, 25,         // arbitrary position and size, may be any
       hWnd,                   // parent window
       NULL,                   // no menu
       NULL,                   // a handle to the instance of the module to be associated with the window
       NULL);                  // pointer to custom value is not required

Countermeasures

Check for controls other than the buttons and examine their properties. For example, if the “Install” text is linked with the “static” control (not with “button”), this may indicate that the evasion technique is applied. Therefore, such a static control may be clicked.


2.3. Evasion technique for the Cuckoo human-interaction module

Suppose that the malware installer window has a button with the “Install” caption or something similar. It can be found by the human-interaction module of a sandbox but it’s invisible to an actual user (one-pixel size, hidden, etc.).


The real installation button has an empty or fake caption and the window class “Static”, so it can’t be detected by the auto-clicking module. In addition, the malware may take some mock action if the invisible button is clicked.


Code sample

    HWND hWnd = CreateWindow(
        TEXT("Button"),         // class "button"
        TEXT("Next"),           // caption is “Install” or “Next”
        NULL,                   // style flags are not required, the control is invisible
        1, 1, 1, 1,             // the control is created of 1x1 pixel size
        hParentWnd,             // parent window
        NULL,                   // no menu
        NULL,                   // a handle to the instance of the module to be associated with the window
        NULL);                  // pointer to custom value is not required

Countermeasures

Check for controls other than buttons and examine their properties. If there is a button of 1x1 pixel size or the button is invisible, this may be an indication of evasion technique applied. Therefore, such a control should not be clicked.


2.4. No suspicious actions until a document is scrolled down

Malware payloads which reside in Office documents (namely, *.docm *.docx) don’t do anything until the document is scrolled to a certain page (second, third, etc.). A human user usually scrolls through the document while a virtual environment will likely not perform this step.


Example from FireEye report (p. 6-7):

RTF documents consist of normal text, control words, and groups. Microsoft’s RTF specification includes a shape-drawing function, which in turn includes a series of properties using the following syntax:
{\sp{\sn propertyName}{\sv propertyValueInformation}}

In this code, \sp is the control word for the drawing property, \sn is the property name, and \sv contains information about the property value. The code snippet in the image below exploits a CVE-2010-3333 vulnerability that occurs when using an invalid \sv value for the pFragments shape property:



A closer look at the exploit code, as shown in the next image, reveals a series of paragraph marks (./par) that appears before the exploit code:



The repeated paragraph marks push the exploit code to the second page of the RTF document. Therefore, the malicious code does not execute unless the document scrolls down to bring the exploit code up into the active window — more likely to be a deliberate act by a human user than simulated movement in a virtual machine.

When the RTF is scrolled down to the second page, only then is the exploit code triggered and the payload is downloaded.

In a sandbox, where any mouse activity is random or preprogrammed, the RTF document’s second page never appears. Therefore, the malicious code never executes, and nothing seems amiss in the sandbox analysis.


Countermeasures

Find a window with the document and send the WM_VSCROLL message there. Alternatively, send the WM_MOUSEWHEEL message as described here.


2.5. Check user activity via GetLastInputInfo

User activity can be checked with the call to the GetLastInputInfo function

Although Agent Tesla v3 performs this check, it does so incorrectly. Compare the code of Agent Tesla v3 with the correct technique implementation below.


Evasion technique as implemented in Agent Tesla v3. This function is called after a delay of 30 seconds.

As measured time values are in milliseconds, the difference between them cannot be larger than 30000 (30 seconds). This means that with division by 1000.0, the resulting value cannot be larger than 30. In turn, this indicates that a comparison with 600 always leads to a result in which the sandbox is undetected.

The correct implementation is provided below.


Code sample

    bool sandbox_detected = false;
    
    Sleep(30000);

    DWORD ticks = GetTickCount();

    LASTINPUTINFO li;
    li.cbSize = sizeof(LASTINPUTINFO);
    BOOL res = GetLastInputInfo(&li);

    if (ticks - li.dwTime > 6000)
    {
        sandbox_detected = true;
    }

Countermeasures

Implement the module for mouse movement during a sample emulation.


Countermeasures

Countermeasures for chapter 1 are given in the corresponding section. Countermeasures for chapter 2 are given in place in the appropriate sections.


Signature recommendations

Signature recommendations are not provided for this class of techniques as the methods described in this chapter do not imply their usage for evasion purposes. It is hard to differentiate between the code meant for evasion and code designed for non-evasion purposes.


Credits

Open-source project from where code samples were taken:

Companies from where certain examples were taken:


Go back