Anti-Sandbox code with norman

Norman is not a person. Norman is our good old friend at norman.no – the sandbox, doing binary analysis.

In other words, since the Nepenthes module submit_norman it became one of the botnet kiddies greatest enemies as many nets were detected that way.

Since some samples I have analyzed are detecting the sandbox pretty well, I started working on that topic to understand what they do.

#include <stdio.h>
#include <windows.h>

void main()
{
MessageBox(NULL, “Hello World”, “My first C program”, MB_OK);
}

This few lines, a simple hello world program might remind you of the days you started programming. If we throw it into the sandbox, we are getting:

Test.exe : Not detected by sandbox (Signature: NO_VIRUS)
[ General information ]
* Display message box (My first C program) : Hello World
* File length: 36864 bytes.

Our program got analyzed as expected. Since we are getting good information on our program, it looks like we are not running on standard Windows DLL’s. As we are able to read the output of our messagebox we can take a peek into its memory:

#include <stdio.h>
#include <windows.h>

void main()
{
char szBuffer[512];
DWORD dwAddr = (DWORD)GetProcAddress(LoadLibrary(“user32.dll”), “MessageBoxA”);
//Get the address of any WINAPI function, we use MessageBoxA() in this example.

memset(szBuffer, 0, sizeof(szBuffer));
_snprintf(szBuffer, sizeof(szBuffer) – 1, “[ 0x%x, 0x%x, 0x%x, 0x%x, 0x%x ]”, *(BYTE*)dwAddr, *(BYTE*)(dwAddr + 1), *(BYTE*)(dwAddr + 2), *(BYTE*)(dwAddr + 3), *(BYTE*)(dwAddr + 4));
//Read the first 5 bytes of connect() into the buffer

MessageBox(NULL, szBuffer, “The Title”, MB_OK);
//Display the messagebox
}

The sandbox result reads like that:

Test.exe : Not detected by sandbox (Signature: NO_VIRUS)
[ General information ]
* Display message box (The Title) : [ 0xc8, 0x0, 0x4, 0x0, 0x60 ].
* File length: 40960 bytes.

The interesting part is the memory adress where MessageBoxA got loaded. Let’s compare it to a local windows box.

“[ 0x8b 0xff 0x55 0x8b 0xec ]”

The values returned by our program offer some kind of fingerprint which can be used to fool the sandbox, as the following code sample shows:

#include <stdio.h>
#include <windows.h>

void main()
{
unsigned char szBytes[] = { 0xc8, 0x0, 0x4, 0x0, 0x60 };
DWORD dwAddr = (DWORD)GetProcAddress(LoadLibrary(“user32.dll”), “MessageBoxA”);

if(!memcmp((LPVOID)dwAddr, (LPVOID)szBytes, sizeof(szBytes)))
{
MessageBox(NULL, “Hello Norman.”, “Detected.”, MB_OK);
ExitProcess(0);
//Exit the process cleanly so it stops execution and logging of the file
}

MessageBox(NULL, “You will not see that message in the sandbox”, “Hidden.”, MB_OK);
}

After throwing our exe into the sandbox, we see:

Test3.exe : Not detected by sandbox (Signature: NO_VIRUS)
[ General information ]

* Display message box (Detected.) : Hello Norman.
* File length: 36864 bytes.

If we are testing our binary on a local system, we will see our messagebox showing “You will not see that message in the sandbox”.

The result of our little experiment: Windows is Windows and a sandbox is a sandbox… and everything has its specific fingerprint.

Author:

Leave a Reply

Your email address will not be published. Required fields are marked *

Notify me of followup comments via e-mail. You can also subscribe without commenting.